diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 97c8c97f..237c9ed0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,4 +1,5 @@ { + "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json", "name": "nfcore", "image": "nfcore/devcontainer:latest", diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 9b4e68ba..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,125 +0,0 @@ -# `nf-core/pixelator`: Contributing Guidelines - -Hi there! -Many thanks for taking an interest in improving nf-core/pixelator. - -We try to manage the required tasks for nf-core/pixelator using GitHub issues, you probably came to this page when creating one. -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 ;) - -> [!NOTE] -> If you need help using or modifying nf-core/pixelator then the best place to ask is on the nf-core Slack [#pixelator](https://nfcore.slack.com/channels/pixelator) channel ([join our Slack here](https://nf-co.re/join/slack)). - -## Contribution workflow - -If you'd like to write some code for nf-core/pixelator, the standard workflow is as follows: - -1. Check that there isn't already an issue about your idea in the [nf-core/pixelator issues](https://github.com/nf-core/pixelator/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/pixelator repository](https://github.com/nf-core/pixelator) to your GitHub account -3. Make the necessary changes / additions within your forked repository following [Pipeline conventions](#pipeline-contribution-conventions) -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 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. - -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 pipelines lint ` command. - -If any failures or warnings are encountered, please follow the listed URL for more documentation. - -### Pipeline tests - -Each `nf-core` pipeline should be set up with a minimal set of test-data. -`GitHub Actions` then runs the pipeline on this data to ensure that it exits successfully. -If there are any failures then the automated tests fail. -These tests are run both with the latest available version of `Nextflow` and also the minimum required version that is stated in the pipeline code. - -## Patch - -: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/main` or `upstream/master`. -- Fix the bug, and bump version (X.Y.Z+1). -- Open a pull-request from `patch` to `main`/`master` with the changes. - -## Getting help - -For further information/help, please consult the [nf-core/pixelator documentation](https://nf-co.re/pixelator/usage) and don't hesitate to get in touch on the nf-core Slack [#pixelator](https://nfcore.slack.com/channels/pixelator) channel ([join our Slack here](https://nf-co.re/join/slack)). - -## Pipeline contribution conventions - -To make the `nf-core/pixelator` 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. -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 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 in the `tests` directory. -9. Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name clean up and module plots are in the appropriate order. If applicable, add a [MultiQC](https://https://multiqc.info/) module. -10. Add a description of the output files and if relevant any appropriate images from the MultiQC report to `docs/output.md`. - -### Default values - -Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. - -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/main/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. - -The process resources can be passed on to the tool dynamically within the process with the `${task.cpus}` and `${task.memory}` variables in the `script:` block. - -### Naming schemes - -Please use the following naming schemes, to make it easy to understand what is going where. - -- initial process channel: `ch_output_from_` -- intermediate and terminal channels: `ch__for_` - -### 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 pipelines bump-version --nextflow . [min-nf-version]` - -### Images and figures - -For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines). - -## GitHub Codespaces - -This repo includes a devcontainer configuration which will create a GitHub Codespaces for Nextflow development! This is an online developer environment that runs in your browser, complete with VSCode and a terminal. - -To get started: - -- Open the repo in [Codespaces](https://github.com/nf-core/pixelator/codespaces) -- Tools installed - - nf-core - - Nextflow - -Devcontainer specs: - -- [DevContainer config](.devcontainer/devcontainer.json) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3e33e429..a302e7a5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,14 +8,14 @@ These are the most common things requested on pull requests (PRs). Remember that PRs should be made against the dev branch, unless you're preparing a pipeline release. -Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/pixelator/tree/master/.github/CONTRIBUTING.md) +Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/pixelator/tree/master/docs/CONTRIBUTING.md) --> ## PR checklist - [ ] This comment contains a description of changes (with reason). - [ ] If you've fixed a bug or added code that should be tested, add tests! -- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/pixelator/tree/master/.github/CONTRIBUTING.md) +- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/pixelator/tree/master/docs/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/pixelator _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core pipelines lint`). - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). diff --git a/.github/actions/get-shards/action.yml b/.github/actions/get-shards/action.yml index 34085279..e2833ee9 100644 --- a/.github/actions/get-shards/action.yml +++ b/.github/actions/get-shards/action.yml @@ -21,7 +21,7 @@ runs: using: "composite" steps: - name: Install nf-test - uses: nf-core/setup-nf-test@v1 + uses: nf-core/setup-nf-test@4069fbbaabe94c08faba4ad261bfa88225ba133f # v2 with: version: ${{ env.NFT_VER }} - name: Get number of shards diff --git a/.github/actions/nf-test/action.yml b/.github/actions/nf-test/action.yml index 3b9724c7..ad686e8e 100644 --- a/.github/actions/nf-test/action.yml +++ b/.github/actions/nf-test/action.yml @@ -20,24 +20,24 @@ runs: using: "composite" steps: - name: Setup Nextflow - uses: nf-core/setup-nextflow@v2 + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 with: version: "${{ env.NXF_VERSION }}" - name: Set up Python - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.14" - name: Install nf-test - uses: nf-core/setup-nf-test@v1 + uses: nf-core/setup-nf-test@4069fbbaabe94c08faba4ad261bfa88225ba133f # v2 with: version: "${{ env.NFT_VER }}" install-pdiff: true - name: Setup apptainer if: contains(inputs.profile, 'singularity') - uses: eWaterCycle/setup-apptainer@main + uses: eWaterCycle/setup-apptainer@3f706d898c9db585b1d741b4692e66755f3a1b40 # v2 - name: Set up Singularity if: contains(inputs.profile, 'singularity') @@ -48,7 +48,7 @@ runs: - name: Conda setup if: contains(inputs.profile, 'conda') - uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3 + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4 with: auto-update-conda: true conda-solver: libmamba diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 04d15cbf..126adfac 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -23,21 +23,40 @@ jobs: echo "revision=${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'release') && github.sha || 'dev' }}" >> "$GITHUB_OUTPUT" - name: Launch workflow via Seqera Platform - uses: seqeralabs/action-tower-launch@v2 + uses: seqeralabs/action-tower-launch@51565b514bff1827cf34620de25d0055759f1fc9 # v2 with: workspace_id: ${{ vars.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ vars.TOWER_COMPUTE_ENV }} revision: ${{ steps.revision.outputs.revision }} workdir: s3://${{ vars.AWS_S3_BUCKET }}/work/pixelator/work-${{ steps.revision.outputs.revision }} + nextflow_config: | + plugins { + id 'nf-slack@0.5.0' + } + slack { + enabled = true + bot { + token = '${{ secrets.NFSLACK_BOT_TOKEN }}' + channel = 'pixelator' + } + onStart { + enabled = false + } + onComplete { + message = ':white_check_mark: *pixelator/test_full* completed successfully! :tada:' + } + onError { + message = ':x: *pixelator/test_full* failed :crying_cat_face:' + } + } parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", "outdir": "s3://${{ vars.AWS_S3_BUCKET }}/pixelator/results-${{ steps.revision.outputs.revision }}" } profiles: test_full - - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: Seqera Platform debug log file path: | diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index c0673dcd..9d2d7367 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -12,7 +12,7 @@ jobs: steps: # Launch workflow using Seqera Platform CLI tool action - name: Launch workflow via Seqera Platform - uses: seqeralabs/action-tower-launch@v2 + uses: seqeralabs/action-tower-launch@51565b514bff1827cf34620de25d0055759f1fc9 # v2 with: workspace_id: ${{ vars.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} @@ -25,7 +25,7 @@ jobs: } profiles: test - - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: Seqera Platform debug log file path: | diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 0e3d6360..758348db 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -21,7 +21,7 @@ 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@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 + uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3 with: message: | ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index 6adb0fff..172de6f3 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@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10 + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." diff --git a/.github/workflows/download_pipeline.yml b/.github/workflows/download_pipeline.yml index 5bcd0421..57647601 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -38,13 +38,16 @@ jobs: runs-on: ubuntu-latest needs: configure steps: + - name: Check out pipeline code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install Nextflow - uses: nf-core/setup-nextflow@v2 + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.14" architecture: "x64" @@ -54,10 +57,15 @@ jobs: with: apptainer-version: 1.3.6 + - name: Read .nf-core.yml + id: read_yml + run: | + echo "nf_core_version=$(yq '.nf_core_version' ${{ github.workspace }}/.nf-core.yml)" >> "$GITHUB_OUTPUT" + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install git+https://github.com/nf-core/tools.git + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} - name: Make a cache directory for the container images run: | @@ -127,7 +135,7 @@ jobs: fi - name: Upload Nextflow logfile for debugging purposes - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: nextflow_logfile.txt path: .nextflow.log* diff --git a/.github/workflows/fix_linting.yml b/.github/workflows/fix_linting.yml index daaecce6..034b3453 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@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -31,22 +31,18 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - # Install and run pre-commit - - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 - with: - python-version: "3.14" - - - name: Install pre-commit - run: pip install pre-commit + - name: Install Nextflow + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - - name: Run pre-commit - id: pre-commit - run: pre-commit run --all-files + # Install and run prek + - name: Run prek + id: prek + uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 continue-on-error: true # indication that the linting has finished - name: react if linting finished succesfully - if: steps.pre-commit.outcome == 'success' + if: steps.prek.outcome == 'success' uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{ github.event.comment.id }} @@ -54,7 +50,7 @@ jobs: - name: Commit & push changes id: commit-and-push - if: steps.pre-commit.outcome == 'failure' + if: steps.prek.outcome == 'failure' run: | git config user.email "core@nf-co.re" git config user.name "nf-core-bot" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 7a527a34..8738ffc9 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -11,33 +11,31 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: Set up Python 3.14 - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 - with: - python-version: "3.14" - - - name: Install pre-commit - run: pip install pre-commit + - name: Install Nextflow + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - - name: Run pre-commit - run: pre-commit run --all-files + - name: Run prek + uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 nf-core: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install Nextflow - uses: nf-core/setup-nextflow@v2 + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.14" architecture: "x64" + - name: Setup uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 id: read_yml @@ -45,12 +43,10 @@ jobs: config: ${{ github.workspace }}/.nf-core.yml - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + run: uv tool install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} - name: Run nf-core pipelines lint - if: ${{ github.base_ref != 'master' }} + if: ${{ github.base_ref != 'master' || github.base_ref != 'main' }} env: GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -58,7 +54,7 @@ jobs: run: nf-core -l lint_log.txt pipelines lint --dir ${GITHUB_WORKSPACE} --markdown lint_results.md - name: Run nf-core pipelines lint --release - if: ${{ github.base_ref == 'master' }} + if: ${{ github.base_ref == 'master' || github.base_ref == 'main' }} env: GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -71,7 +67,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index e6e9bc26..5b0c24f7 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@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 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@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2 + uses: marocchino/sticky-pull-request-comment@70d2764d1a7d5d9560b100cbea0077fc8f633987 # v3 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ steps.pr_number.outputs.pr_number }} diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index 6aae34fc..f9618471 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -18,7 +18,7 @@ concurrency: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NFT_VER: "0.9.3" + NFT_VER: "0.9.4" NFT_WORKDIR: "~" NXF_ANSI_LOG: false NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity @@ -40,7 +40,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 @@ -64,6 +64,7 @@ jobs: runs-on: # use self-hosted runners - runs-on=${{ github.run_id }}-nf-test - runner=4cpu-linux-x64 + - volume=40gb strategy: fail-fast: false matrix: @@ -79,14 +80,14 @@ jobs: - isMain: false profile: "singularity" NXF_VER: - - "25.04.0" + - "25.10.4" - "latest-everything" env: NXF_ANSI_LOG: false TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index 431d3d44..78d5dbe0 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -18,7 +18,7 @@ jobs: id: get_description run: | echo "description=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .description')" >> $GITHUB_OUTPUT - - uses: rzr/fediverse-action@master + - uses: rzr/fediverse-action@563159eb8d45f70ab6aaba36ed55cd037e51f441 # master with: access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }} host: "mstdn.science" # custom host if not "mastodon.social" (default) @@ -34,7 +34,7 @@ jobs: bsky-post: runs-on: ubuntu-latest steps: - - uses: zentered/bluesky-post-action@6461056ea355ea43b977e149f7bf76aaa572e5e8 # v0.3.0 + - uses: zentered/bluesky-post-action@5a91cc2ad10a304a4e96c16182dbe4918710bcf6 # v0.4.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 index e8560fc7..ea30827e 100644 --- a/.github/workflows/template-version-comment.yml +++ b/.github/workflows/template-version-comment.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: ref: ${{ github.event.pull_request.head.sha }} @@ -29,7 +29,7 @@ jobs: 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 + uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3 if: | contains(env.OUTPUT, 'nf-core') with: @@ -42,5 +42,5 @@ jobs: > 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). + > For more documentation on how to update your pipeline, please see the [Synchronisation documentation](https://nf-co.re/docs/developing/template-syncs/overview). # diff --git a/.gitignore b/.gitignore index 2c8c13dc..c8f923e5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ testing* null/ .idea .vscode - .nf-test* +.lineage/ diff --git a/.nf-core.yml b/.nf-core.yml index d75c30b9..13526eda 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -3,13 +3,14 @@ lint: - assets/multiqc_config.yml - conf/igenomes.config - conf/igenomes_ignored.config - - conf/test.config - tests/default.nf.test files_unchanged: - assets/nf-core-pixelator_logo_light.png + - .gitignore - .github/PULL_REQUEST_TEMPLATE.md + - LICENSE multiqc_config: false -nf_core_version: 3.5.2 +nf_core_version: 4.0.2 repository_type: pipeline template: author: Pixelgen Technologies AB @@ -23,4 +24,4 @@ template: - fastqc - multiqc - igenomes - version: 3.0.1 + version: 4.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6fb3e1ef..4988b0ef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.6.2 + - prettier@3.8.3 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: @@ -15,15 +15,21 @@ repos: exclude: | (?x)^( .*ro-crate-metadata.json$| - modules/nf-core/.*| - subworkflows/nf-core/.*| + modules/(?!local/).*| + subworkflows/(?!local/).*| .*\.snap$ )$ - id: end-of-file-fixer exclude: | (?x)^( .*ro-crate-metadata.json$| - modules/nf-core/.*| - subworkflows/nf-core/.*| + modules/(?!local/).*| + subworkflows/(?!local/).*| .*\.snap$ )$ + - repo: https://github.com/seqeralabs/nf-lint-pre-commit + rev: v0.3.0 + hooks: + - id: nextflow-lint + files: '\.nf$|nextflow\.config$' + args: ["-output", "json"] diff --git a/.prettierignore b/.prettierignore index dd749d43..63cde500 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,4 @@ email_template.html -adaptivecard.json -slackreport.json .nextflow* work/ data/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 235298ee..8583692a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,55 @@ 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). -## [[3.0.1](https://github.com/nf-core/pixelator/releases/tag/3.0.0)] - 2026-03-09 +## [[4.0.0](https://github.com/nf-core/pixelator/releases/tag/4.0.0)] - 2026-05-19 + +### Added + +- Add Proxiome V2 workflow support, enabling sample pooling and processing of up to 8,000 cells per run by @Aratz [#204](https://github.com/nf-core/pixelator/pull/204), [#205](https://github.com/nf-core/pixelator/pull/205) + +### Enhancements & fixes + +- Use nextflow strict syntax by @Aratz [#194](https://github.com/nf-core/pixelator/pull/194) +- Use `TMPDIR` when defined to store temporary files by @Aratz [#195](https://github.com/nf-core/pixelator/pull/195) +- Retry experiment summary up to two times after failure by @Aratz [#196](https://github.com/nf-core/pixelator/pull/196) +- Updated pixelatorES to 0.10.1 in PNA experiment summary step by @Aratz [#197](https://github.com/nf-core/pixelator/pull/197), [#204](https://github.com/nf-core/pixelator/pull/204) +- Add `cells_1k` and `cells_8k` Nextflow profiles with process-specific resource overrides for different input scales by @johandahlberg [#203](https://github.com/nf-core/pixelator/pull/203) +- Fix singularity CI tests by @Aratz [#208](https://github.com/nf-core/pixelator/pull/208) +- Update nf-core template to 4.0.2 by @Aratz [#202](https://github.com/nf-core/pixelator/pull/202) + +### Software dependencies + +| Dependency | Old version | New version | +| ------------- | ----------- | ----------- | +| `pixelatorES` | 0.6.0 | 0.10.1 | +| `pixelator` | 0.23.0 | 0.26.0 | + +> [!WARNING] +> Panel and design names have been completely renamed in pixelator 0.26 +> (nf-core/pixelator 4.0 and above). Refer to the pixelator +> [changelog](https://github.com/PixelgenTechnologies/pixelator/releases/tag/v0.26.0) +> for more details. + +### Parameters + +| Old parameter | New parameter | +| ------------------------------------ | ----------------------------------------- | +| `--leiden-iterations` | | +| `--min-component-size-in-refinement` | | +| `--min-component-size-to-prune` | | +| | `--technology` | +| | `--edge_cycle-verification` | +| | `save_pna_sample_calling_pixelfile` | +| | `pna_sample_calling_save_undetermined` | +| | `pna_sample_calling_remove_incompatible` | +| | `pna_sample_calling_confidence_threshold` | + +> [!NOTE] +> Parameter has been **updated** if both old and new parameter information is present. +> Parameter has been **added** if just the new parameter information is present. +> Parameter has been **removed** if new parameter information isn't present. + +## [[3.0.1](https://github.com/nf-core/pixelator/releases/tag/3.0.1)] - 2026-03-09 ### Enhancements & fixes diff --git a/README.md b/README.md index ec345b64..f6dcb80f 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ [![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.10015112-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.10015112) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/) -[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.2) +[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.10.4-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/) +[![nf-core template version](https://img.shields.io/badge/nf--core_template-4.0.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/4.0.2) [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) @@ -35,10 +35,11 @@ The pipeline will run the following steps: 2. Create groups of amplicons based on their marker assignments ([`pixelator single-cell-pna demux`](https://github.com/PixelgenTechnologies/pixelator)) 3. Derive original molecules to use as edge list downstream by error correcting, and counting input amplicons ([`pixelator single-cell-pna collapse`](https://github.com/PixelgenTechnologies/pixelator)) 4. Compute the components of the graph from the edge list in order to create putative cells ([`pixelator single-cell-pna graph`](https://github.com/PixelgenTechnologies/pixelator)) -5. Denoise the cell graphs ([`pixelator single-cell-pna denoise`](https://github.com/PixelgenTechnologies/pixelator)) -6. Analyze the spatial information in the cell graphs ([`pixelator single-cell-pna analysis`](https://github.com/PixelgenTechnologies/pixelator)) -7. Generate 3D graph layouts for visualization of cells ([`pixelator single-cell-pna layout`](https://github.com/PixelgenTechnologies/pixelator)) -8. Proxiome Experiment Summary generation using [PixelatorES](https://github.com/PixelgenTechnologies/pixelatorES) +5. _(Conditional; only for PNA hashed data)_ Assign components to samples in pooled experiments ([`pixelator single-cell-pna sample-calling`](https://github.com/PixelgenTechnologies/pixelator)) +6. Denoise the cell graphs ([`pixelator single-cell-pna denoise`](https://github.com/PixelgenTechnologies/pixelator)) +7. Analyze the spatial information in the cell graphs ([`pixelator single-cell-pna analysis`](https://github.com/PixelgenTechnologies/pixelator)) +8. Generate 3D graph layouts for visualization of cells ([`pixelator single-cell-pna layout`](https://github.com/PixelgenTechnologies/pixelator)) +9. Proxiome Experiment Summary generation using [PixelatorES](https://github.com/PixelgenTechnologies/pixelatorES) > [!NOTE] > If you are looking to run the pipeline with Molecular Pixelation (MPX) data. Please refer to the [release 2.3.1](https://nf-co.re/pixelator/2.3.1/), @@ -52,24 +53,37 @@ The pipeline will run the following steps: ## 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/get_started/environment_setup/overview) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/get_started/run-your-first-pipeline) with `-profile test` before running the workflow on actual data. -First, prepare a samplesheet with your input data that looks as follows (the exact values you need to input depend on the design and panel you are using - please see [https://nf-co.re/pixelator/usage](https://nf-co.re/pixelator/usage) for more details): +First, prepare a samplesheet with your input data that looks as follows (the exact values you need to input depend on the design and panel you are using - please see [https://nf-co.re/pixelator/usage](https://nf-co.re/pixelator/usage) for more details). +For hashed PNA data (Proxiome kit v2), the samplesheet will look as follows: `samplesheet.csv`: ```csv -sample,sample_alias,condition,design,panel,fastq_1,fastq_2 -sample1,s1,control,pna-2,proxiome-immuno-155-v2,sample1_R1_001.fastq.gz,sample1_R2_001.fastq.gz +pool,hash_index,sample,sample_alias,condition,design,panel,fastq_1,fastq_2 +pool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz +pool1,2,sample2,s2,case,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz +pool2,1,sample3,s3,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool2_R1_001.fastq.gz,pool2_R2_001.fastq.gz ``` +> [!NOTE] +> For an example with non-hashed PNA data (Proxiome kit v1), see [Proxiome v1 samplesheet](../assets/samplesheet_proxiome_v1.csv) + +> [!WARNING] +> Panel and design names have been completely renamed in pixelator 0.26 +> (nf-core/pixelator 4.0 and above). Refer to the pixelator +> [changelog](https://github.com/PixelgenTechnologies/pixelator/releases/tag/v0.26.0) +> for more details. + Each row represents a sample and gives the design, a panel file and the input fastq files. Now, you can run the pipeline using: ```bash nextflow run nf-core/pixelator \ - -profile \ + -profile , \ + --technology --input samplesheet.csv \ --outdir ``` @@ -80,7 +94,7 @@ nextflow run nf-core/pixelator \ > We hope to add support for conda environments in the future. > [!WARNING] -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/running/run-pipelines#using-parameter-files). For more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pixelator/usage) and the [parameter documentation](https://nf-co.re/pixelator/parameters). @@ -100,7 +114,7 @@ nf-core/pixelator was originally written for [Pixelgen Technologies AB](https:// ## Contributions and Support -If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). +If you would like to contribute to this pipeline, please see the [contributing guidelines](docs/CONTRIBUTING.md). For further information or help, don't hesitate to get in touch on the [Slack `#pixelator` channel](https://nfcore.slack.com/channels/pixelator) (you can join with [this invite](https://nf-co.re/join/slack)). diff --git a/assets/adaptivecard.json b/assets/adaptivecard.json deleted file mode 100644 index d6e00574..00000000 --- a/assets/adaptivecard.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "type": "message", - "attachments": [ - { - "contentType": "application/vnd.microsoft.card.adaptive", - "contentUrl": null, - "content": { - "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "msteams": { - "width": "Full" - }, - "type": "AdaptiveCard", - "version": "1.2", - "body": [ - { - "type": "TextBlock", - "size": "Large", - "weight": "Bolder", - "color": "<% if (success) { %>Good<% } else { %>Attention<%} %>", - "text": "nf-core/pixelator v${version} - ${runName}", - "wrap": true - }, - { - "type": "TextBlock", - "spacing": "None", - "text": "Completed at ${dateComplete} (duration: ${duration})", - "isSubtle": true, - "wrap": true - }, - { - "type": "TextBlock", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors. The full error message was: ${errorReport}.<% } %>", - "wrap": true - }, - { - "type": "TextBlock", - "text": "The command used to launch the workflow was as follows:", - "wrap": true - }, - { - "type": "TextBlock", - "text": "${commandLine}", - "isSubtle": true, - "wrap": true - } - ], - "actions": [ - { - "type": "Action.ShowCard", - "title": "Pipeline Configuration", - "card": { - "type": "AdaptiveCard", - "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "body": [ - { - "type": "FactSet", - "facts": [<% out << summary.collect{ k,v -> "{\"title\": \"$k\", \"value\" : \"$v\"}"}.join(",\n") %> - ] - } - ] - } - } - ] - } - } - ] -} diff --git a/assets/example_samplesheet_proxiome_v1.csv b/assets/example_samplesheet_proxiome_v1.csv new file mode 100644 index 00000000..3b4903ec --- /dev/null +++ b/assets/example_samplesheet_proxiome_v1.csv @@ -0,0 +1,3 @@ +sample,sample_alias,condition,design,panel,fastq_1,fastq_2 +sample1,s1,control,proxiome-v1,proxiome-v1-immuno-155-v1.1,sample1_R1_001.fastq.gz,sample1_R2_001.fastq.gz +sample2,s2,treatment,proxiome-v1,proxiome-v1-immuno-155-v1.1,sample2_R1_001.fastq.gz,sample2_R2_001.fastq.gz diff --git a/assets/example_samplesheet_proxiome_v2.csv b/assets/example_samplesheet_proxiome_v2.csv new file mode 100644 index 00000000..7e721723 --- /dev/null +++ b/assets/example_samplesheet_proxiome_v2.csv @@ -0,0 +1,3 @@ +pool,hash_index,sample,sample_alias,condition,design,panel,fastq_1,fastq_2 +pool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz +pool1,2,sample2,s2,treatment,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz diff --git a/assets/samplesheet_mpx.csv b/assets/samplesheet_mpx.csv deleted file mode 100644 index e50611a7..00000000 --- a/assets/samplesheet_mpx.csv +++ /dev/null @@ -1,4 +0,0 @@ -sample,design,panel,fastq_1,fastq_2 -uropod_control_1,D21,human-sc-immunology-spatial-proteomics,uropod_control_S1_L001_R1_001.fastq.gz,uropod_control_S1_L001_R2_001.fastq.gz -uropod_control_1,D21,human-sc-immunology-spatial-proteomics,uropod_control_S1_L002_R1_001.fastq.gz,uropod_control_S1_L002_R2_001.fastq.gz -uropod_control_1,D21,human-sc-immunology-spatial-proteomics,uropod_control_S1_L003_R1_001.fastq.gz,uropod_control_S1_L003_R2_001.fastq.gz diff --git a/assets/samplesheet_pna.csv b/assets/samplesheet_pna.csv deleted file mode 100644 index a59dff3d..00000000 --- a/assets/samplesheet_pna.csv +++ /dev/null @@ -1,3 +0,0 @@ -sample,sample_alias,condition,design,panel,fastq_1,fastq_2 -sample1,s1,control,pna-2,proxiome-immuno-155-v2,sample1_R1_001.fastq.gz,sample1_R2_001.fastq.gz -sample2,s2,treatment,pna-2,proxiome-immuno-155-v2,sample2_R1_001.fastq.gz,sample2_R2_001.fastq.gz diff --git a/assets/schema_input.json b/assets/schema_input.json index 96d38d3e..41df445d 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -8,6 +8,40 @@ "type": "object", "required": ["sample", "design", "fastq_1"], "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "design": { + "const": "proxiome-v1" + } + } + }, + "then": { + "not": { + "required": ["pool"] + }, + "errorMessage": "Pooled samples can only be used with the `proxiome-v2` design." + } + }, + { + "if": { + "properties": { + "design": { + "const": "proxiome-v2" + }, + "panel": { + "const": "proxiome-v2-immuno-155-v1.0" + } + }, + "required": ["design", "panel"] + }, + "then": { + "required": ["pool", "hash_index"], + "errorMessage": "The `pool` and `hash_index` columns are required for `proxiome-v2` design with panel `proxiome-v2-immuno-155-v1.0`." + } + } + ], "properties": { "sample": { "type": "string", @@ -16,6 +50,16 @@ "description": "Sample name (no spaces).", "meta": ["id"] }, + "pool": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "pool ID cannot contain spaces", + "meta": ["pool"] + }, + "hash_index": { + "type": "integer", + "meta": ["hash_index"] + }, "design": { "type": "string", "pattern": "^\\S+$", diff --git a/assets/slackreport.json b/assets/slackreport.json deleted file mode 100644 index d25c9c08..00000000 --- a/assets/slackreport.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "attachments": [ - { - "fallback": "Plain-text summary of the attachment.", - "color": "<% if (success) { %>good<% } else { %>danger<%} %>", - "author_name": "nf-core/pixelator ${version} - ${runName}", - "author_icon": "https://www.nextflow.io/docs/latest/_static/favicon.ico", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors<% } %>", - "fields": [ - { - "title": "Command used to launch the workflow", - "value": "```${commandLine}```", - "short": false - } - <% - if (!success) { %> - , - { - "title": "Full error message", - "value": "```${errorReport}```", - "short": false - }, - { - "title": "Pipeline configuration", - "value": "<% out << summary.collect{ k,v -> k == "hook_url" ? "_${k}_: (_hidden_)" : ( ( v.class.toString().contains('Path') || ( v.class.toString().contains('String') && v.contains('/') ) ) ? "_${k}_: `${v}`" : (v.class.toString().contains('DateTime') ? ("_${k}_: " + v.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM))) : "_${k}_: ${v}") ) }.join(",\n") %>", - "short": false - } - <% } - %> - ], - "footer": "Completed at <% out << dateComplete.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM)) %> (duration: ${duration})" - } - ] -} diff --git a/assets/test_samplesheet.csv b/assets/test_samplesheet.csv deleted file mode 100644 index 9ad1694e..00000000 --- a/assets/test_samplesheet.csv +++ /dev/null @@ -1,4 +0,0 @@ -sample,design,panel,panel_file,fastq_1,fastq_2 -uropod_control_1,D21,,UNO_D21.csv,uropod_control_300k_S1_R1_001.part_001.fastq.gz,uropod_control_300k_S1_R2_001.part_001.fastq.gz -uropod_control_1,D21,,UNO_D21.csv,uropod_control_300k_S1_R1_001.part_002.fastq.gz,uropod_control_300k_S1_R2_001.part_002.fastq.gz -uropod_control_2,D21,human-sc-immunology-spatial-proteomics,,uropod_control_300k_S1_R1_001.fastq.gz,uropod_control_300k_S1_R2_001.fastq.gz diff --git a/conf/base.config b/conf/base.config index e674f262..bb0b9065 100644 --- a/conf/base.config +++ b/conf/base.config @@ -14,7 +14,7 @@ process { memory = { 6.GB * task.attempt } time = { 4.h * task.attempt } - errorStrategy = { task.exitStatus in ((130..145) + 104 + 175) ? 'retry' : 'finish' } + errorStrategy = { task.exitStatus in ((130..145) + 104 + (175..177)) ? 'retry' : 'finish' } maxRetries = 1 maxErrors = '-1' diff --git a/conf/cells_1k.config b/conf/cells_1k.config new file mode 100644 index 00000000..c958a93b --- /dev/null +++ b/conf/cells_1k.config @@ -0,0 +1,43 @@ +process { + // All processes not defined here will rely on process labels and base.config. + + withName: PIXELATOR_AMPLICON { + cpus = { 32 * task.attempt } + memory = { 32.GB * task.attempt } + time = { 4.h * task.attempt } + } + + withName: PIXELATOR_DEMUX { + cpus = { 16 * task.attempt } + memory = { 64.GB * task.attempt } + time = { 4.h * task.attempt } + } + + withName: PIXELATOR_COLLAPSE { + cpus = { 8 * task.attempt } + memory = { 64.GB * task.attempt } + time = { 8.h * task.attempt } + maxRetries = 4 + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175 + 1) ? 'retry' : 'finish' } + } + + withName: PIXELATOR_COMBINE_COLLAPSE { + cpus = { 16 * task.attempt } + memory = { 128.GB * task.attempt } + time = { 4.h * task.attempt } + maxRetries = 4 + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175 + 1) ? 'retry' : 'finish' } + } + + withName: PIXELATOR_GRAPH { + cpus = { 12 * task.attempt } + memory = { 512.GB * task.attempt } + time = { 10.h * task.attempt } + } + + withName: EXPERIMENT_SUMMARY { + cpus = { 16 * task.attempt } + memory = { 64.GB * task.attempt } + time = { 12.h * task.attempt } + } +} diff --git a/conf/cells_8k.config b/conf/cells_8k.config new file mode 100644 index 00000000..707e8bc2 --- /dev/null +++ b/conf/cells_8k.config @@ -0,0 +1,43 @@ +process { + // Keep process sizing overrides here for larger (8k cell) runs. + + withName: PIXELATOR_AMPLICON { + cpus = { 32 * task.attempt } + memory = { 32.GB * task.attempt } + time = { 40.h * task.attempt } + } + + withName: PIXELATOR_DEMUX { + cpus = { 16 * task.attempt } + memory = { 128.GB * task.attempt } + time = { 12.h * task.attempt } + } + + withName: PIXELATOR_COLLAPSE { + cpus = { 8 * task.attempt } + memory = { 256.GB * task.attempt } + time = { 8.h * task.attempt } + maxRetries = 4 + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175 + 1) ? 'retry' : 'finish' } + } + + withName: PIXELATOR_COMBINE_COLLAPSE { + cpus = { 8 * task.attempt } + memory = { 512.GB * task.attempt } + time = { 6.h * task.attempt } + maxRetries = 4 + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175 + 1) ? 'retry' : 'finish' } + } + + withName: PIXELATOR_GRAPH { + cpus = { 12 * task.attempt } + memory = { 512.GB * task.attempt } + time = { 20.h * task.attempt } + } + + withName: EXPERIMENT_SUMMARY { + cpus = { 16 * task.attempt } + memory = { 64.GB * task.attempt } + time = { 12.h * task.attempt } + } +} diff --git a/conf/container_env.config b/conf/container_env.config new file mode 100644 index 00000000..f37a786b --- /dev/null +++ b/conf/container_env.config @@ -0,0 +1,20 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Environment variables to be used inside containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Specify location to use for temporary files. If available, `TMPDIR` will be + used, otherwise it will fallback on `/tmp`. +---------------------------------------------------------------------------------------- +*/ + +env { + MPLCONFIGDIR = '${TMPDIR:-/tmp}/.config/matplotlib' + NUMBA_CACHE_DIR = '${TMPDIR:-/tmp}/.numba_cache' + + // quarto needs a writeable cache directory + XDG_CACHE_HOME = '${TMPDIR:-/tmp}/.cache' + XDG_DATA_HOME = '${TMPDIR:-/tmp}/.data' + + // DuckDB temp directory when running in containers + PIXELATOR_DUCKDB_TEMP_DIR = '${TMPDIR:-/tmp}' +} diff --git a/conf/modules.pna.config b/conf/modules.pna.config index 5b601a94..e375298b 100644 --- a/conf/modules.pna.config +++ b/conf/modules.pna.config @@ -13,7 +13,7 @@ process { - withName: PIXELATOR_PNA_AMPLICON { + withName: PIXELATOR_AMPLICON { ext.args = { [ "--design ${meta.design}", @@ -32,7 +32,7 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'amplicon/*.amplicon.fq.zst', - saveAs: { params.save_pna_amplicon_reads || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_amplicon_reads || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -43,12 +43,12 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json || params.save_all ? it : null }, + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, ], ] } - withName: PIXELATOR_PNA_DEMUX { + withName: PIXELATOR_DEMUX { ext.args = { [ params.pna_demux_mismatches instanceof Integer ? "--mismatches ${params.pna_demux_mismatches}" : '', @@ -62,19 +62,19 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'demux/*.parquet', - saveAs: { params.save_pna_demux_parquet || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_demux_parquet || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'demux/*.demux.passed.fq.zst', - saveAs: { params.save_pna_demux_passed_reads || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_demux_passed_reads || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'demux/*.demux.failed.fq.zst', - saveAs: { params.save_pna_demux_failed_reads || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_demux_failed_reads || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -85,12 +85,12 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json || params.save_all ? it : null }, + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, ], ] } - withName: PIXELATOR_PNA_COLLAPSE { + withName: PIXELATOR_COLLAPSE { ext.args = { [ params.pna_collapse_mismatches ? "--mismatches ${params.pna_collapse_mismatches}" : '', @@ -102,7 +102,7 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'collapse/*.parquet', - saveAs: { params.save_pna_collapsed_reads || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_collapsed_reads || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -113,26 +113,24 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json || params.save_all ? it : null }, + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, ], ] } - withName: PIXELATOR_PNA_GRAPH { + withName: PIXELATOR_GRAPH { ext.args = { [ params.pna_graph_multiplet_recovery ? "--multiplet-recovery" : '', - params.pna_graph_leiden_iterations ? "--leiden-iterations ${params.pna_graph_leiden_iterations}" : '', + params.pna_graph_edge_cycle_verification ? "--edge-cycle-verification" : '', params.pna_graph_initial_stage_leiden_resolution ? "--initial-stage-leiden-resolution ${params.pna_graph_initial_stage_leiden_resolution}" : '', params.pna_graph_refinement_stage_leiden_resolution ? "--refinement-stage-leiden-resolution ${params.pna_graph_refinement_stage_leiden_resolution}" : '', params.pna_graph_min_count ? "--min-count ${params.pna_graph_min_count}" : '', - params.pna_graph_min_component_size_in_refinement ? "--min-component-size-in-refinement ${params.pna_graph_min_component_size_in_refinement}" : '', params.pna_graph_max_refinement_recursion_depth ? "--max-refinement-recursion-depth ${params.pna_graph_max_refinement_recursion_depth}" : '', params.pna_graph_initial_stage_max_edges_to_remove ? "--initial-stage-max-edges-to-remove ${params.pna_graph_initial_stage_max_edges_to_remove}" : '', params.pna_graph_refinement_stage_max_edges_to_remove ? "--refinement-stage-max-edges-to-remove ${params.pna_graph_refinement_stage_max_edges_to_remove}" : '', params.pna_graph_initial_stage_max_edges_to_remove_relative ? "--initial-stage-max-edges-to-remove-relative ${params.pna_graph_initial_stage_max_edges_to_remove_relative}" : '', params.pna_graph_refinement_stage_max_edges_to_remove_relative ? "--refinement-stage-max-edges-to-remove-relative ${params.pna_graph_refinement_stage_max_edges_to_remove_relative}" : '', - params.pna_graph_graph_min_component_size_to_prune ? "--min-component-size-to-prune ${params.pna_graph_graph_min_component_size_to_prune}" : '', params.pna_graph_component_size_min_threshold ? "--component-size-min-threshold ${params.pna_graph_component_size_min_threshold}" : '', ].join(' ').trim() } @@ -141,7 +139,36 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'graph/*.pxl', - saveAs: { params.save_pna_graph_pixelfile || params.save_all ? it : null }, + saveAs: { filename -> params.save_pna_graph_pixelfile || params.save_all ? filename : null }, + ], + [ + path: { "${params.outdir}/pixelator/logs/${meta.id}" }, + mode: params.publish_dir_mode, + pattern: '*.log', + ], + [ + path: { "${params.outdir}/pixelator" }, + mode: params.publish_dir_mode, + pattern: '**/*.{report,meta}.json', + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, + ], + ] + } + + withName: PIXELATOR_SAMPLE_CALLING { + ext.args = { + [ + params.pna_sample_calling_remove_incompatible ? "--remove-incompatible" : '', + params.pna_sample_calling_save_undetermined ? "--save-undetermined" : '', + params.pna_sample_calling_confidence_threshold != null ? "--confidence-threshold ${params.pna_sample_calling_confidence_threshold}" : '', + ].join(' ').trim() + } + publishDir = [ + [ + path: { "${params.outdir}/pixelator" }, + mode: params.publish_dir_mode, + pattern: 'sample_calling/*.pxl', + saveAs: { params.save_pna_sample_calling_pixelfile || params.save_all ? it : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -157,7 +184,7 @@ process { ] } - withName: PIXELATOR_PNA_DENOISE { + withName: PIXELATOR_DENOISE { ext.when = { !params.skip_denoise } ext.args = { [ @@ -171,12 +198,7 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'denoise/*.pxl', - saveAs: { - if (params.save_pna_denoise_pixelfile) { - return it - } - return null - }, + saveAs: { filename -> params.save_pna_denoise_pixelfile ? filename : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -187,14 +209,14 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json ? it : null }, + saveAs: { filename -> params.save_json ? filename : null }, ], ] } - withName: PIXELATOR_PNA_ANALYSIS { + withName: PIXELATOR_ANALYSIS { ext.when = { !params.skip_analysis } ext.args = { [ @@ -210,12 +232,7 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: 'analysis/*.pxl', - saveAs: { - if (params.save_pna_analysis_pixelfile || params.save_all) { - return it - } - return null - }, + saveAs: { filename -> params.save_pna_analysis_pixelfile || params.save_all ? filename : null }, ], [ path: { "${params.outdir}/pixelator/logs/${meta.id}" }, @@ -226,12 +243,12 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json || params.save_all ? it : null }, + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, ], ] } - withName: PIXELATOR_PNA_LAYOUT { + withName: PIXELATOR_LAYOUT { ext.when = { !params.skip_layout } ext.args = { [ @@ -248,7 +265,7 @@ process { pattern: 'layout/*.pxl', saveAs: { // Trim the annotate directory prefix from the output name - new File(it).name + filename -> new File(filename).name }, ], [ @@ -260,7 +277,7 @@ process { path: { "${params.outdir}/pixelator" }, mode: params.publish_dir_mode, pattern: '**/*.{report,meta}.json', - saveAs: { params.save_json || params.save_all ? it : null }, + saveAs: { filename -> params.save_json || params.save_all ? filename : null }, ], ] } diff --git a/conf/test.config b/conf/test.config new file mode 100644 index 00000000..4cfa08af --- /dev/null +++ b/conf/test.config @@ -0,0 +1,14 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test + for the pna pipline + + Use as follows: + nextflow run nf-core/pixelator -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +includeConfig 'test_proxiome_v2.config' diff --git a/conf/test_full.config b/conf/test_full.config index e9621480..9c42b7cb 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -6,32 +6,9 @@ for the pna pipline Use as follows: - nextflow run nf-core/pixelator -profile test_pna, --outdir + nextflow run nf-core/pixelator -profile test_full, --outdir ---------------------------------------------------------------------------------------- */ -process { - resourceLimits = [ - cpus: 4, - memory: '15.GB', - time: '1.h', - ] - // Run a smaller experiment summary for testing - withName: EXPERIMENT_SUMMARY { - ext.args = '-P test_mode="TRUE"' - } -} - -params { - config_profile_name = 'Test profile' - config_profile_description = 'Minimal test dataset to check pipeline function' - - // Input data - input = params.pipelines_testdata_base_path + '/samplesheet/pna/samplesheet_pna.csv' - input_basedir = params.pipelines_testdata_base_path + '/testdata/pna' - - pna_graph_component_size_min_threshold = 100 - - skip_layout = false -} +includeConfig 'test_proxiome_v2.config' diff --git a/conf/test_pna.config b/conf/test_proxiome_v1.config similarity index 68% rename from conf/test_pna.config rename to conf/test_proxiome_v1.config index e9621480..afe193a4 100644 --- a/conf/test_pna.config +++ b/conf/test_proxiome_v1.config @@ -6,32 +6,35 @@ for the pna pipline Use as follows: - nextflow run nf-core/pixelator -profile test_pna, --outdir + nextflow run nf-core/pixelator -profile test_proxiome_v1, --outdir ---------------------------------------------------------------------------------------- */ -process { - resourceLimits = [ - cpus: 4, - memory: '15.GB', - time: '1.h', - ] - - // Run a smaller experiment summary for testing - withName: EXPERIMENT_SUMMARY { - ext.args = '-P test_mode="TRUE"' - } -} params { - config_profile_name = 'Test profile' + config_profile_name = 'Test profile for proxiome v1 data' config_profile_description = 'Minimal test dataset to check pipeline function' // Input data - input = params.pipelines_testdata_base_path + '/samplesheet/pna/samplesheet_pna.csv' + input = params.pipelines_testdata_base_path + '/samplesheet/pna/samplesheet_proxiome_v1.csv' input_basedir = params.pipelines_testdata_base_path + '/testdata/pna' pna_graph_component_size_min_threshold = 100 skip_layout = false + technology = "proxiome-v1" + save_all = true +} + +process { + withName: '.*' { + cpus = 2 + memory = 3.GB + time = 2.h + } + + // Run a smaller experiment summary for testing + withName: EXPERIMENT_SUMMARY { + ext.args = '-P test_mode="TRUE"' + } } diff --git a/conf/test_proxiome_v2.config b/conf/test_proxiome_v2.config new file mode 100644 index 00000000..7273a4df --- /dev/null +++ b/conf/test_proxiome_v2.config @@ -0,0 +1,40 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test + for the pna pipline + + Use as follows: + nextflow run nf-core/pixelator -profile test_proxiome_v2, --outdir + +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Test profile for proxiome v2 data' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = params.pipelines_testdata_base_path + '/samplesheet/pna/samplesheet_proxiome_v2.csv' + input_basedir = params.pipelines_testdata_base_path + '/testdata/pna' + + pna_graph_component_size_min_threshold = 100 + + skip_layout = false + technology = "proxiome-v2" + save_all = true +} + +process { + withName: '.*' { + cpus = 2 + memory = 3.GB + time = 2.h + } + + // Run a smaller experiment summary for testing + withName: EXPERIMENT_SUMMARY { + ext.args = '-P test_mode="TRUE"' + } +} diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..0428ee2d --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,205 @@ +--- +title: Contributing +markdownPlugin: checklist +--- + +# `nf-core/pixelator`: Contributing guidelines + +Hi there! +Thanks for taking an interest in improving nf-core/pixelator. + +This page describes the recommended nf-core way to contribute to both nf-core/pixelator and nf-core pipelines in general, including: + +- [General contribution guidelines](#general-contribution-guidelines): common procedures or guides across all nf-core pipelines. +- [Pipeline-specific contribution guidelines](#pipeline-specific-contribution-guidelines): procedures or guides specific to the development conventions of nf-core/pixelator. + +> [!NOTE] +> If you need help using or modifying nf-core/pixelator, ask on the nf-core Slack [#pixelator](https://nfcore.slack.com/channels/pixelator) channel ([join our Slack here](https://nf-co.re/join/slack)). + +## General contribution guidelines + +### Contribution quick start + +To contribute code to any nf-core pipeline: + +- [ ] Ensure you have Nextflow, nf-core tools, and nf-test installed. See the [nf-core/tools repository](https://github.com/nf-core/tools) for instructions. +- [ ] Check whether a GitHub [issue](https://github.com/nf-core/pixelator/issues) about your idea already exists. If an issue does not exist, create one so that others are aware you are working on it. +- [ ] [Fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the [nf-core/pixelator repository](https://github.com/nf-core/pixelator) to your GitHub account. +- [ ] Create a branch on your forked repository and make your changes following [pipeline conventions](#pipeline-contribution-conventions) (if applicable). +- [ ] To fix major bugs, name your branch `patch` and follow the [patch release](#patch-release) process. +- [ ] Update relevant documentation within the `docs/` folder, use nf-core/tools to update `nextflow_schema.json`, and update `CITATIONS.md`. +- [ ] Run and/or update tests. See [Testing](#testing) for more information. +- [ ] [Lint](#lint-tests) your code with nf-core/tools. +- [ ] Submit a pull request (PR) against the `dev` branch and request a review. + +If you are not used to this workflow with Git, see the [GitHub documentation](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or [Git resources](https://try.github.io/) for more information. + +## Use of AI and LLMs + +The nf-core stance on the use of AI and LLMs is that humans are still ultimately responsible for their submitted code, regardless of the tools they use. + +If you’re using AI tools, try to stick by these guidelines: + +- Keep PRs as small and focussed as possible +- Avoid any unnecessary changes, such as moving or refactoring code (unless that is the explicit intention of the PR) +- Review all generated code yourself before opening a PR, and ensure that you understand it +- Engage with the community review process and expect to make revisions + +For more detail, see the the [blog post](https://nf-co.re/blog/2026/statement-on-ai) for a statement from the nf-core/core team. + +### Getting help + +For further information and help, see the [nf-core/pixelator documentation](https://nf-co.re/pixelator/usage) or ask on the nf-core [#pixelator](https://nfcore.slack.com/channels/pixelator) Slack channel ([join our Slack here](https://nf-co.re/join/slack)). + +### GitHub Codespaces + +You can contribute to nf-core/pixelator without installing a local development environment on your machine by using [GitHub Codespaces](https://github.com/codespaces). + +[GitHub Codespaces](https://github.com/codespaces) is an online developer environment that runs in your browser, complete with VS Code and a terminal. +Most nf-core repositories include a devcontainer configuration, which creates a GitHub Codespaces environment specifically for Nextflow development. +The environment includes pre-installed nf-core tools, Nextflow, and a few other helpful utilities via a Docker container. + +To get started, open the repository in [Codespaces](https://github.com/nf-core/pixelator/codespaces). + +### Testing + +Once you have made your changes, run the pipeline with nf-test to test them locally. +For additional information, use the `--verbose` flag to view the Nextflow console log output. + +```bash +nf-test test --tag test --profile +docker --verbose +``` + +If you have added new functionality, ensure you update the test assertions in the `.nf.test` files in the `tests/` directory. +Update the snapshots with the following command: + +```bash +nf-test test --tag test --profile +docker --verbose --update-snapshots +``` + +Some tests can take quite long to run. To solve this we provide two utility scripts: + +- `run_smoke_tests.sh`: this runs all tests tagged with `smoke_test`. This is a good way to quickly + make sure nothing is broken after making some changes. +- `run_tests_parallel.sh`: this runs all the tests in parallel using on 5 different threads. + This is useful to update all the snapshots at once before making a PR. + +Both scripts take the same parameters `nf-test` does, e.g. run +`bash tests/scripts/run_tests_parallel.sh --update-snapshots` to update all snapshots. + +When you create a pull request with changes, GitHub Actions will run automatic tests. +Pull requests are typically reviewed when these tests are passing. + +Two types of tests are typically run: + +#### Lint tests + +nf-core has a [set of guidelines](https://nf-co.re/docs/specifications/overview) which all pipelines must follow. +To enforce these, run linting with nf-core/tools: + +```bash +nf-core pipelines lint +``` + +If you encounter failures or warnings, follow the linked documentation printed to screen. +For more information about linting tests, see [nf-core/tools API documentation](https://nf-co.re/docs/nf-core-tools/api_reference/latest/pipeline_lint_tests/actions_awsfulltest). + +#### Pipeline tests + +Each nf-core pipeline should be set up with a minimal set of test data. +GitHub Actions runs the pipeline on this data to ensure it runs through and exits successfully. +If there are any failures then the automated tests fail. +These tests are run with the latest available version of Nextflow and the minimum required version specified in the pipeline code. + +#### Test data + +By default, test data is downloaded from +https://github.com/nf-core/test-datasets/tree/pixelator. If one desires to use +local data instead, this can be overriden either with the +`pipelines_testdata_base_path` parameter or with the `NFT_TESTDATA_BASE_PATH` +environment variable. + +### Patch release + +> [!WARNING] +> Only in the unlikely event of a release that contains a critical bug. + +- [ ] Create a new branch `patch` on your fork based on `upstream/main` or `upstream/master`. +- [ ] Fix the bug and use nf-core/tools to bump the version to the next semantic version, for example, `1.2.3` → `1.2.4`. +- [ ] Open a Pull Request from `patch` directly to `main`/`master` with the changes. + +### Pipeline contribution conventions + +nf-core semi-standardises how you write code and other contributions to make the nf-core/pixelator code and processing logic more understandable for new contributors and to ensure quality. + +#### Add a new pipeline step + +To contribute a new step to the pipeline, follow the general nf-core coding procedure. +Please also refer to the [pipeline-specific contribution guidelines](#pipeline-specific-contribution-guidelines): + +- [ ] Define the corresponding [input channel](#channel-naming-schemes) into your new process from the expected previous process channel. +- [ ] Install a module with nf-core/tools, or write a local module (see [default processes resource requirements](#default-processes-resource-requirements)), and add it to the target `.nf`. +- [ ] Define the output channel if needed. Mix the version output channel into `ch_versions` and relevant files into `ch_multiqc`. +- [ ] Add new or updated parameters to `nextflow.config` with a [default value](#default-parameter-values). +- [ ] Add new or updated parameters and relevant help text to `nextflow_schema.json` with [nf-core/tools](#default-parameter-values). +- [ ] Add validation for relevant parameters to the pipeline utilisation section of `utils_nfcore_\_pipeline/main.nf` subworkflow. +- [ ] Perform local tests to validate that the new code works as expected. + - [ ] If applicable, add a new test in the `tests` directory. +- [ ] Update `usage.md`, `output.md`, and `citation.md` as appropriate. +- [ ] [Lint](lint) the code with nf-core/tools. +- [ ] Update any diagrams or pipeline images as necessary. + +To update the minimum required Nextflow version, see the [Nextflow version bumping](#nextflow-version-bumping) section below. For more information about pipeline contributions, see [pipeline-specific contribution guidelines](#pipeline-specific-contribution-guidelines). + +#### Channel naming schemes + +Use the following naming schemes for channels to make the channel flow easier to understand: + +- Initial process channel: `ch_output_from_` +- Intermediate and terminal channels: `ch__for_` + +#### Default parameter values + +Parameters should be initialised and defined with default values within the `params` scope in `nextflow.config`. +They should also be documented in the pipeline JSON schema. + +To update `nextflow_schema.json`, run: + +```bash +nf-core pipelines schema build +``` + +The schema builder interface that loads in your browser should automatically update the defaults in the parameter documentation. + +#### Default processes resource requirements + +If you write a local module, specify a default set of resource requirements for the process. + +Sensible defaults for process resource requirements (CPUs, memory, time) should be defined in `conf/base.config`. +Specify these with generic `withLabel:` selectors, so they can be shared across multiple processes and steps of the pipeline. + +nf-core provides a set of standard labels that you should follow where possible, as seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config). +These labels define resource defaults for single-core processes, modules that require a GPU, and different levels of multi-core configurations with increasing memory requirements. + +Values assigned within these labels can be dynamically passed to a tool using the the `${task.cpus}` and `${task.memory}` Nextflow variables in the `script:` block of a module (see an example in the [modules repository](https://github.com/nf-core/modules/blob/bd1b6a40f55933d94b8c9ca94ec8c1ea0eaf4b82/modules/nf-core/samtools/bam2fq/main.nf#L30)). + +#### Nextflow version bumping + +If you use a new feature from core Nextflow, bump the minimum required Nextflow version in the pipeline with: + +```bash +nf-core pipelines bump-version --nextflow . +``` + +#### Images and figures guidelines + +If you update images or graphics, follow the nf-core [style guidelines](https://nf-co.re/docs/community/brand/workflow-schematics). + +## Pipeline specific contribution guidelines + +nf-core/pixelator is built on top of mainly +[pixelator](https://github.com/PixelgenTechnologies/pixelator) and +[pixelatorES](https://github.com/PixelgenTechnologies/pixelatorES), two +products developed by Pixelgen Technologies. As open source projects, these +also welcome contributions from everyone. Please refer to the documentation of +these projects for more information. diff --git a/docs/images/nf-core-pixelator-metromap.svg b/docs/images/nf-core-pixelator-metromap.svg index 3eb27166..90af051b 100644 --- a/docs/images/nf-core-pixelator-metromap.svg +++ b/docs/images/nf-core-pixelator-metromap.svg @@ -1,373 +1,258 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - + + - + - + - + - + - - + + - + - + - + - + - - + + - + - + - + - + - - + + - + - + - + - + - - + + - + - + - - - - - - - - - - - - - - + + - - + + - - + + - - + + - - + + diff --git a/docs/output.md b/docs/output.md index d74ef1c9..9ab78fcf 100644 --- a/docs/output.md +++ b/docs/output.md @@ -19,6 +19,7 @@ The PNA pipeline consists of the following steps: - [Demultiplexing](#demultiplexing) - [Molecule collapsing and error correction](#molecule-collapsing-and-error-correction) - [Graph construction](#graph-construction) +- [Sample Calling](#sample-calling) - [Denoising](#denoising) - [Analysis](#analysis) - [Layout creation](#compute-layouts-for-visualization) @@ -121,7 +122,37 @@ the [pixelator documentation](https://software.pixelgen.com/pixelator/outputs/px -### Denoising +#### Sample Calling + +This step uses the `pixelator single-cell-pna sample-calling` command. It takes +the graph PXL file and the sample sheet as input and assigns each component to +the most likely sample in pooled experiments. + +Components with assignment confidence below the selected threshold are marked +as undetermined and can be saved to a separate output file. The resulting +per-sample dehashed PXL files are then used as input for the denoising step. + +
+Output files + +- `pixelator` + - `sample_calling` + - `.dehashed.pxl`: The pixel file containing the data associated with each samples. + - `.meta.json`: Command invocation metadata. + - `.report.json`: QC metrics for the sample calling step. + - `_undetermined.dehashed.pxl`: The pixel file containing data that could not be associated with any sample. This is only output when `pna_sample_calling_save_undetermined = true`. + - `_undetermined.meta.json`: Command invocation metadata. + - `_undetermined.report.json`: QC metrics for the sample calling step. + + - `logs` + - `.pixelator-sample-calling.log`: pixelator log output. + +
+ +> [!NOTE] +> This step is run only when `--technology proxiome-v2` is set. + +#### Denoising This step uses the `pixelator single-cell-pna denoise` command. It will try to find differences between the well-connected parts of each component graph and the less well-connected parts of the graph. It will @@ -145,7 +176,7 @@ The denoised graph will be saved as a new PXL file. -### Analysis +#### Analysis This step uses the `pixelator single-cell-pna analysis` command to calculate spatial statistics. @@ -223,15 +254,16 @@ The output from this step will be placed in the output folder root. ### Output directory structure With default parameters, the pixelator pipeline output directory will only include the latest PXL file -generated by the pipeline (with the most "complete" information) and an interactive HTML report per sample. +generated by the pipeline (with the most "complete" information) and an interactive HTML report summarizing the data for all samples. The PXL dataset files can be from either the `graph`, `analysis` or `layout` step. With default parameters, the `.layout.pxl` will be copied to the output directory. -If the `layout` stage is skipped (using `--skip_layout`) the `.analysis.pxl` files will be included and -if the `analysis` stage is skipped (using `--skip_analysis`) the `.graph.pxl` will be copied. Various flags are available to store intermediate files and are described in the input parameter documentation. Alternatively, you can keep all intermediate files using `--save_all`. +> [!WARNING] +> If the `layout` stage is skipped (using `--skip_layout`), use `--save_pna_` to output the latest PXL files. + Below is an example output structure for a pipeline run using the default settings. - `pipeline_info/` diff --git a/docs/usage.md b/docs/usage.md index 1c1e05c2..d35200d9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -15,8 +15,9 @@ Use this parameter to specify its location. --input '[path to samplesheet file]' ``` -We provide an example samplesheet for [PNA data](../assets/samplesheet_pna.csv), -that can be used as a template to create your own samplesheet. +We provide example samplesheets for [Proxiome v1 data](../assets/samplesheet_proxiome_v1.csv) +and [Proxiome v2 data](../assets/samplesheet_proxiome_v2.csv), that can be used as a template to +create your own samplesheet. ### Format @@ -32,7 +33,7 @@ to match those defined in the table below. > using for your experiment. Using a mismatched panel file will lead to incorrect antibody > assignments and erroneous results. > -> An update list of which panel files correspond to which kit lot versions can be found +> An updated list of which panel files correspond to which kit lot versions can be found > on the [Pixelgen Technologies website](https://www.pixelgen.com/panel-file-for-data-processing/) Below is an example of a simple samplesheet with two samples. @@ -46,24 +47,47 @@ sample2,s2,treatment,pna-2,proxiome-immuno-155-v2,sample2_R1_001.fastq.gz,sample Columns not defined in the table below are ignored by the pipeline but can be useful to add extra information for downstream processing. -| Column | Required | Description | -| ----------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sample` | Yes | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | -| `sample_alias` | Yes (Only for PNA runs) | Custom sample alias. Will be used to identify the sample in reports and visualizations. | -| `condition` | Yes (Only for PNA run) | Experimental condition for the sample (e.g. control, treatment). | -| `design` | Yes | The name of the pixelator design configuration. | -| `panel`
or
`panel_file` | Yes | Name of the panel to use.
or
Path to a CSV file containing a custom panel. | -| `fastq_1` | Yes | Path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `fastq_2` | No | Path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". Parameter only used if you are running paired-end. | +| Column | Required | Description | +| ----------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `pool` | Yes (with pooled samples) | Custom pool name. | +| `hash_index` | Yes (with pooled samples) | Index of the hashing antibody used with this sample. | +| `sample` | Yes | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. | +| `sample_alias` | Yes | Custom sample alias. Will be used to identify the sample in reports and visualizations. | +| `condition` | Yes | Custom experimental condition for the sample (e.g. control, treatment). Used for reports and visualizations. | +| `design` | Yes | The name of the pixelator design configuration. | +| `panel`
or
`panel_file` | Yes | Name of the panel to use.
or
Path to a CSV file containing a custom panel. | +| `fastq_1` | Yes | Path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | +| `fastq_2` | No | Path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". Parameter only used if you are running paired-end. | The `panel` and `panel_file` options are mutually exclusive. If both are specified, the pipeline will throw an error. One of them has to be specified. The pipeline will auto-detect whether a sample is single- or paired-end based on if both `fastq_1` and `fastq_2` or only `fastq_1` is present in the samplesheet. +### Pooling samples + +Pooled samples are supported with the Proxiome v2 kit. To process them, include +the `pool` and `hash_index` columns in the samplesheet and use the +`proxiome-v2` design. Hash indices have to match the hashing antibody used for each sample. +Typically there are 8 hashed samples per pool (numbering 1 to 8). + +```csv +pool,hash_index,sample,sample_alias,condition,design,panel,fastq_1,fastq_2 +pool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz +pool2,2,sample2,s2,treatment,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz +``` + ### Multiple runs of the same sample -The `sample` identifiers have to be the same when you have re-sequenced the same sample more than once e.g. to increase sequencing depth. The pipeline will concatenate the raw reads before performing any downstream analysis. Below is an example for the same sample sequenced across 3 lanes: +When a sample or pool has been re-sequenced (for example, to increase +sequencing depth), use the same `sample` or `pool` identifier across runs. The +pipeline will then concatenate the corresponding FastQ files before downstream +analysis. + +> [!NOTE] +> When combining multiple runs, sample metadata such as pool, hash_index, sample_alias, condition, design and panel needs to be repeated on all rows. + +Below is an example for the same sample sequenced across 3 lanes: ```csv title="samplesheet.csv" sample,sample_alias,condition,design,panel,fastq_1,fastq_2 @@ -72,6 +96,16 @@ uropod_control_1,s1,control,pna-2,proxiome-immuno-155-v2,uropod_control_S1_L002_ uropod_control_1,s1,control,pna-2,proxiome-immuno-155-v2,uropod_control_S1_L003_R1_001.fastq.gz,uropod_control_S1_L003_R2_001.fastq.gz ``` +The same approach applies when pooled hashed samples are sequenced again: + +```csv title="samplesheet.csv" +pool,hash_index,sample,sample_alias,condition,design,panel,fastq_1,fastq_2 +pool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_run1_R1_001.fastq.gz,pool1_run1_R2_001.fastq.gz +pool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_run2_R1_001.fastq.gz,pool1_run2_R2_001.fastq.gz +pool1,2,sample2,s2,treatment,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_run1_R1_001.fastq.gz,pool1_run1_R2_001.fastq.gz +pool1,2,sample2,s2,treatment,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_run2_R1_001.fastq.gz,pool1_run2_R2_001.fastq.gz +``` + ### Relative paths Using relative paths in a samplesheet is supported. @@ -91,7 +125,7 @@ You can use following samplesheet: ```csv title="samplesheet.csv" sample,sample_alias,condition,design,panel,panel_file,fastq_1,fastq_2 -sample1,s1,control,pna-2,proxiome-immuno-155-v2,,fastq/sample1_R1.fq.gz,fastq/sample1_R2.fq.gz +sample1,s1,control,proxiome-v1,proxiome-v1-immuno-155-v1.1,,fastq/sample1_R1.fq.gz,fastq/sample1_R2.fq.gz ``` Using the `--input_basedir` option you can specify a different location that will be used to resolve relative paths. @@ -104,7 +138,7 @@ For example, using the same samplesheet as above, but with the samplesheet on th - sample1_R2.fq.gz ```shell -nextflow run nf-core/pixelator --input samplesheet.csv --input_basedir s3://my-company-data/experiment-1/ +nextflow run nf-core/pixelator --input samplesheet.csv --input_basedir s3://my-company-data/experiment-1/ --output ./resulst --technology proxiome-v1 ``` ### Design @@ -139,10 +173,12 @@ pixelator single-cell-pna --list-panels The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/pixelator --input ./samplesheet.csv --outdir ./results -profile docker +nextflow run nf-core/pixelator --input ./samplesheet.csv --outdir ./results -profile docker,cells_8k --technology proxiome-v2 ``` -This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. +This will launch the pipeline with the `docker` configuration profile, and resource configurations +for 8000 cells. If you have samples with 1000 cells as input, pick the `cells_1k` profile instead. +See below for more information about profiles. Note that the pipeline will create the following files in your working directory: @@ -158,12 +194,12 @@ If you wish to repeatedly use the same parameters for multiple runs, rather than Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `. > [!WARNING] -> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). +> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/running/run-pipelines#configuring-pipelines), other infrastructural tweaks (such as output directories), or module arguments (args). The above pipeline run specified with a params file in yaml format: ```bash -nextflow run nf-core/pixelator -profile docker -params-file params.yaml +nextflow run nf-core/pixelator -profile docker,cells_8k -params-file params.yaml ``` with: @@ -178,6 +214,9 @@ You can find an extensive example of a `params.yaml` file with all options and documentation in comments [here](../assets/params-file.yml). You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-co.re/launch). +> [!NOTE] +> By default, processes from nf-core/pixelator will use the path defined in `TMPDIR` to store temporary file. If this variable is not defined, they will fallback to `/tmp`. + ### Updating the pipeline When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: @@ -239,6 +278,10 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to be used with [Apptainer](https://apptainer.org/) - `wave` - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). +- `cells_8k` + - A configuration profile for 8000 cells. +- `cells_1k` + - A configuration profile for 1000 cells. :::warning Since Nextflow 23.07.0-edge, Nextflow no longer mounts the host's home directory when using Apptainer or Singularity. @@ -262,19 +305,19 @@ Specify the path to a specific config file (this is a core Nextflow command). Se Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the pipeline steps, if the job exits with any of the error codes specified [here](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher resources request (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. -To change the resource requests, please see the [max resources](https://nf-co.re/docs/usage/configuration#max-resources) and [tuning workflow resources](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources) section of the nf-core website. +To change the resource requests, please see the [max resources](https://nf-co.re/docs/running/configuration/nextflow-for-your-system#set-max-resources) and [customise process resources](https://nf-co.re/docs/running/configuration/nextflow-for-your-system#customize-process-resources) section of the nf-core website. ### Custom Containers In some cases, you may wish to change the container or conda environment used by a pipeline steps for a particular tool. By default, nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However, in some cases the pipeline specified version maybe out of date. -To use a different container from the default container or conda environment specified in a pipeline, please see the [updating tool versions](https://nf-co.re/docs/usage/configuration#updating-tool-versions) section of the nf-core website. +To use a different container from the default container or conda environment specified in a pipeline, please see the [updating tool versions](https://nf-co.re/docs/running/configuration/nextflow-for-your-system#update-tool-versions) section of the nf-core website. ### Custom Tool Arguments A pipeline might not always support every possible argument or option of a particular tool used in pipeline. Fortunately, nf-core pipelines provide some freedom to users to insert additional parameters that the pipeline does not include by default. -To learn how to provide additional arguments to a particular tool of the pipeline, please see the [customising tool arguments](https://nf-co.re/docs/usage/configuration#customising-tool-arguments) section of the nf-core website. +To learn how to provide additional arguments to a particular tool of the pipeline, please see the [customising tool arguments](https://nf-co.re/docs/running/configuration/nextflow-for-your-system#modifying-tool-arguments) section of the nf-core website. ### nf-core/configs diff --git a/main.nf b/main.nf index a8951cba..4a653cc9 100644 --- a/main.nf +++ b/main.nf @@ -39,7 +39,7 @@ workflow NFCORE_PIXELATOR { // WORKFLOW: Run pipeline // PIXELATOR ( - samplesheet + samplesheet, ) } /* @@ -83,7 +83,6 @@ workflow { params.plaintext_email, params.outdir, params.monochrome_logs, - params.hook_url, ) } diff --git a/modules.json b/modules.json index 526f0b40..75e0d8aa 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "cat/fastq": { "branch": "master", - "git_sha": "5d28ea7cfaebcfae6f74d1067ea766d8ff19dff3", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["modules"] } } @@ -16,17 +16,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "git_sha": "1a545fcbd762911c21a64ced3dbef99b2b51ac75", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "65f5e638d901a51534c68fd5c1c19e8112fb4df1", + "git_sha": "a3fb7351b1fdb2b1de282b765816bbea190e86a8", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57", + "git_sha": "ce3424257de288c0ca25f097a68d3a289da23f12", "installed_by": ["subworkflows"] } } diff --git a/modules/local/experiment_summary/main.nf b/modules/local/experiment_summary/main.nf index 2967a5c1..bd3b42b2 100644 --- a/modules/local/experiment_summary/main.nf +++ b/modules/local/experiment_summary/main.nf @@ -1,23 +1,15 @@ process EXPERIMENT_SUMMARY { tag "${meta.id}" label "process_medium" + label "error_retry" container "${params.experiment_summary_container?: workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelatores:0.6.0' - : 'quay.io/pixelgen-technologies/pixelatores:0.6.0'}" + ? 'quay.io/pixelgen-technologies/pixelatores:0.10.1' + : 'quay.io/pixelgen-technologies/pixelatores:0.10.1'}" input: path samplesheet_path - tuple ( - val(meta), - path(amplicon_data , stageAs: "results/amplicon/*"), - path(demux_data , stageAs: "results/demux/*"), - path(collapse_data , stageAs: "results/collapse/*"), - path(graph_data , stageAs: "results/graph/*"), - path(denoise_data , stageAs: "results/denoise/*"), - path(analysis_data , stageAs: "results/analysis/*"), - path(layout_data , stageAs: "results/layout/*") - ) + tuple val(meta), val(result_stages), path(results_data, arity: "1..*", stageAs: "results_raw/?/*") output: tuple val(meta), path("*experiment-summary.html") , emit: html @@ -25,9 +17,22 @@ process EXPERIMENT_SUMMARY { script: def args = task.ext.args ?: '' + + assert result_stages instanceof List : "Expected result_stages to be a List, got ${result_stages?.getClass()?.simpleName ?: 'null'}" + assert results_data instanceof List : "Expected results_data to be a List, got ${results_data?.getClass()?.simpleName ?: 'null'}" + assert results_data.size() == result_stages.size(): "Mismatch between result files (${results_data.size()}) and stage labels (${result_stages.size()})" + + def stageCopies = [result_stages, results_data].transpose().collect { stage, file -> + """ + mkdir -p "results/${stage}" + ln -s "../../${file}" "results/${stage}/" + """ + }.join('\n') """ # Copy the full quarto dir from the read-only image into the workdir cp -r /workspace/inst/quarto/ ./quarto/ + mkdir -p results + ${stageCopies} quarto render ./quarto/pixelatorES.qmd \\ -P sample_sheet="\$PWD/${samplesheet_path}" \\ -P data_folder="\$PWD/results/" \\ diff --git a/modules/local/experiment_summary/meta.yml b/modules/local/experiment_summary/meta.yml new file mode 100644 index 00000000..46509e73 --- /dev/null +++ b/modules/local/experiment_summary/meta.yml @@ -0,0 +1,72 @@ +name: experiment_summary +description: Generate an HTML experiment summary report from pipeline outputs. +keywords: + - report + - quarto + - summary + - experiment +tools: + - experiment-summary: + description: Pixelator experiment summary report generation with pixelatorES. + homepage: https://pixelgen.com/ + documentation: https://github.com/PixelgenTechnologies/pixelatorES + licence: ["MIT"] + identifier: "" +input: + - - samplesheet_path: + type: file + description: Sample sheet used for the experiment. + pattern: "*.{csv,tsv,txt}" + ontologies: [] + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - result_stages: + type: list + description: Stage label for each file in `results_data` (same order). + ontologies: [] + - results_data: + type: file + description: Result files to organize under stage folders in the report input. + ontologies: [] +output: + html: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*experiment-summary.html": + type: file + description: Generated experiment summary HTML report. + pattern: "*experiment-summary.html" + ontologies: [] + versions_experiment_summary: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - experiment-summary: + type: string + description: The tool name. + - Rscript -e 'cat(as.character(packageVersion("pixelatorES")), "\n")': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - experiment-summary: + type: string + description: The tool name. + - Rscript -e 'cat(as.character(packageVersion("pixelatorES")), "\n")': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/experiment_summary/tests/main.nf.test b/modules/local/experiment_summary/tests/main.nf.test index a78dc744..56bed6aa 100644 --- a/modules/local/experiment_summary/tests/main.nf.test +++ b/modules/local/experiment_summary/tests/main.nf.test @@ -17,59 +17,15 @@ nextflow_process { when { process { """ - input[0] = [ file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_pna.csv', checkIfExists: true) ] + input[0] = [ file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_proxiome_v2.csv', checkIfExists: true) ] input[1] = [ - [id:'all', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - // amplicon + [id:'all', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), + 'amplicon', 'amplicon', ], - // demux [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // (combined collapse) - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // graph - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // denoise - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // analysis - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // layout - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.layout.pxl', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.layout.pxl', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.report.json', checkIfExists: true), ] ] """ @@ -97,59 +53,84 @@ nextflow_process { } process { """ - input[0] = [ file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_pna.csv', checkIfExists: true) ] + input[0] = [ file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_proxiome_v2.csv', checkIfExists: true) ] input[1] = [ - [id:'all', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - // amplicon - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // demux - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // (combined collapse) - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // graph - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // denoise - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), - ], - // analysis + [id:'all', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), + 'amplicon', 'amplicon', 'amplicon', 'amplicon', + 'demux', 'demux', 'demux', 'demux', + 'collapse', 'collapse', 'collapse', 'collapse', + 'graph', 'graph', 'graph', 'graph', 'graph', 'graph', + 'denoise', 'denoise', 'denoise', 'denoise', 'denoise', 'denoise', 'denoise', 'denoise', + 'analysis', 'analysis', 'analysis', 'analysis', 'analysis', 'analysis', 'analysis', 'analysis', + 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', 'layout', + 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', 'sample_calling', ], - // layout [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.layout.pxl', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.layout.pxl', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.meta.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_unfiltered_S7.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool1.graph.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool2.graph.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample3.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample3.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample4.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/sample4.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample3.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample3.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample4.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample4.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample1.layout.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample2.layout.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample3.layout.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample3.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample3.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample4.layout.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample4.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/sample4.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool1.sample_calling.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool1_undetermined.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool1_undetermined.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool2.sample_calling.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool2_undetermined.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/pool2_undetermined.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.dehashed.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample2.dehashed.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample2.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample2.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample3.dehashed.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample3.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample3.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample4.dehashed.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample4.meta.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample4.report.json', checkIfExists: true), ] ] """ diff --git a/modules/local/experiment_summary/tests/main.nf.test.snap b/modules/local/experiment_summary/tests/main.nf.test.snap index a2a7cec2..4410fd25 100644 --- a/modules/local/experiment_summary/tests/main.nf.test.snap +++ b/modules/local/experiment_summary/tests/main.nf.test.snap @@ -3,6 +3,7 @@ "content": [ 1, [ + "pipeline_info", "pixelator", "pixelator/experiment-summary.html" ], @@ -10,15 +11,15 @@ [ "EXPERIMENT_SUMMARY", "experiment-summary", - "0.6.0 " + "0.10.1 " ] ] ], + "timestamp": "2026-05-21T11:58:35.886952064", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:00:23.063912644" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } }, "PNA experiment summary - stub": { "content": [ @@ -26,14 +27,14 @@ [ "EXPERIMENT_SUMMARY", "experiment-summary", - "0.6.0 " + "0.10.1 " ] ] ], + "timestamp": "2026-05-13T13:50:43.046443239", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T13:57:21.610883862" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } } } \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/amplicon/main.nf b/modules/local/pixelator/amplicon/main.nf similarity index 87% rename from modules/local/pixelator/single-cell-pna/amplicon/main.nf rename to modules/local/pixelator/amplicon/main.nf index ef0231c0..fefe338b 100644 --- a/modules/local/pixelator/single-cell-pna/amplicon/main.nf +++ b/modules/local/pixelator/amplicon/main.nf @@ -1,12 +1,12 @@ -process PIXELATOR_PNA_AMPLICON { +process PIXELATOR_AMPLICON { tag "${meta.id}" label 'process_medium' // TODO: Add conda // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(reads, arity: '1..*') @@ -16,6 +16,7 @@ process PIXELATOR_PNA_AMPLICON { tuple val(meta), path("amplicon/*.report.json"), emit: report_json tuple val(meta), path("amplicon/*.meta.json"), emit: metadata_json tuple val(meta), path("*pixelator-amplicon.log"), emit: log + tuple val('amplicon'), path("amplicon/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions @@ -25,7 +26,6 @@ process PIXELATOR_PNA_AMPLICON { script: def prefix = task.ext.prefix ?: "${meta.id}" def args = task.ext.args ?: '' - def r = reads // Make list of old name and new name pairs to use for renaming // Use R1/R2 style suffixes for limited backward compatibility with pixelator<0.17 @@ -34,7 +34,7 @@ process PIXELATOR_PNA_AMPLICON { : reads.withIndex().collect { entry, index -> [entry, "${prefix}_R${index + 1}${getFileSuffix(entry)}"] }) // Flatten a list of tuples into a single string joined with spaces def rename_to = old_new_pairs.flatten().join(' ') - def renamed_reads = old_new_pairs.collect { old_name, new_name -> new_name }.join(' ') + def renamed_reads = old_new_pairs.collect { _old_name, new_name -> new_name }.join(' ') """ diff --git a/modules/local/pixelator/amplicon/meta.yml b/modules/local/pixelator/amplicon/meta.yml new file mode 100644 index 00000000..d580765d --- /dev/null +++ b/modules/local/pixelator/amplicon/meta.yml @@ -0,0 +1,93 @@ +name: pixelator_amplicon +description: Run `pixelator single-cell-pna amplicon` on input FASTQ files. +keywords: + - pixelator + - single-cell-pna + - amplicon + - fastq +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - reads: + type: file + description: Input FASTQ files. + pattern: "*.{fq,fastq,fq.gz,fastq.gz,fq.zst,fastq.zst}" + ontologies: + - http://edamontology.org/format_2545 +output: + amplicon: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.amplicon.{fq,fastq}.zst": + type: file + description: Amplicon FASTQ output. + pattern: "*.{fq,fastq}.zst" + ontologies: + - http://edamontology.org/format_2545 + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-amplicon.log": + type: file + description: Pixelator amplicon command log. + pattern: "*pixelator-amplicon.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test b/modules/local/pixelator/amplicon/tests/main.nf.test similarity index 68% rename from modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test rename to modules/local/pixelator/amplicon/tests/main.nf.test index 3247210a..9f16a6cf 100644 --- a/modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test +++ b/modules/local/pixelator/amplicon/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_AMPLICON" + name "Test Process PIXELATOR_AMPLICON" script "../main.nf" - process "PIXELATOR_PNA_AMPLICON" + process "PIXELATOR_AMPLICON" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_amplicon" + tag "pixelator/amplicon" test("PNA amplicon - stub") { @@ -16,10 +15,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R1_001.fastq.gz', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R2_001.fastq.gz', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R2.fastq.gz', checkIfExists: true) ] ] """ @@ -42,10 +41,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R1_001.fastq.gz', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R2_001.fastq.gz', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R2.fastq.gz', checkIfExists: true) ] ] """ diff --git a/modules/local/pixelator/amplicon/tests/main.nf.test.snap b/modules/local/pixelator/amplicon/tests/main.nf.test.snap new file mode 100644 index 00000000..479969e7 --- /dev/null +++ b/modules/local/pixelator/amplicon/tests/main.nf.test.snap @@ -0,0 +1,153 @@ +{ + "PNA amplicon - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.amplicon.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-amplicon.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "amplicon", + [ + "pool1.amplicon.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + "PIXELATOR_AMPLICON", + "pixelator", + "0.26.0" + ] + ], + "amplicon": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.amplicon.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-amplicon.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_AMPLICON", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:27:25.664498136", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA amplicon - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/pool1.amplicon.fq.zst", + "pixelator/amplicon/pool1.meta.json", + "pixelator/amplicon/pool1.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-amplicon.log" + ], + [ + [ + "PIXELATOR_AMPLICON", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T11:56:54.148117208", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/analysis/main.nf b/modules/local/pixelator/analysis/main.nf similarity index 86% rename from modules/local/pixelator/single-cell-pna/analysis/main.nf rename to modules/local/pixelator/analysis/main.nf index 78cb0533..0a8f6e86 100644 --- a/modules/local/pixelator/single-cell-pna/analysis/main.nf +++ b/modules/local/pixelator/analysis/main.nf @@ -1,4 +1,4 @@ -process PIXELATOR_PNA_ANALYSIS { +process PIXELATOR_ANALYSIS { tag "${meta.id}" label 'process_medium' @@ -6,8 +6,8 @@ process PIXELATOR_PNA_ANALYSIS { // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(data) @@ -18,6 +18,7 @@ process PIXELATOR_PNA_ANALYSIS { tuple val(meta), path("analysis/*.meta.json"), emit: metadata_json tuple val(meta), path("analysis/*"), emit: all_results tuple val(meta), path("*pixelator-analysis.log"), emit: log + tuple val('analysis'), path("analysis/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/analysis/meta.yml b/modules/local/pixelator/analysis/meta.yml new file mode 100644 index 00000000..16222f1d --- /dev/null +++ b/modules/local/pixelator/analysis/meta.yml @@ -0,0 +1,99 @@ +name: pixelator_analysis +description: Run `pixelator single-cell-pna analysis` on pixel data. +keywords: + - pixelator + - single-cell-pna + - analysis + - pxl +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - data: + type: file + description: Input file for the analysis subcommand. + ontologies: [] +output: + pixelfile: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.pxl": + type: file + description: Pixelator PXL output file. + pattern: "*.pxl" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + all_results: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*": + type: directory + description: All files generated in the analysis output directory. + pattern: "*" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-analysis.log": + type: file + description: Pixelator analysis command log. + pattern: "*pixelator-analysis.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test b/modules/local/pixelator/analysis/tests/main.nf.test similarity index 71% rename from modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test rename to modules/local/pixelator/analysis/tests/main.nf.test index a17440e7..3f099139 100644 --- a/modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test +++ b/modules/local/pixelator/analysis/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_ANALYSIS" + name "Test Process PIXELATOR_ANALYSIS" script "../main.nf" - process "PIXELATOR_PNA_ANALYSIS" + process "PIXELATOR_ANALYSIS" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_analysis" + tag "pixelator/analysis" test("PNA analysis - stub") { @@ -16,8 +15,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true), + [ id:'sample1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.dehashed.pxl', checkIfExists: true), ] """ } @@ -39,8 +38,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true), + [ id:'sample1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.dehashed.pxl', checkIfExists: true), ] """ } diff --git a/modules/local/pixelator/analysis/tests/main.nf.test.snap b/modules/local/pixelator/analysis/tests/main.nf.test.snap new file mode 100644 index 00000000..aa130c7b --- /dev/null +++ b/modules/local/pixelator/analysis/tests/main.nf.test.snap @@ -0,0 +1,183 @@ +{ + "PNA analysis - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/analysis", + "pixelator/analysis/sample1.analysis.pxl", + "pixelator/analysis/sample1.meta.json", + "pixelator/analysis/sample1.report.json", + "pixelator/logs", + "pixelator/logs/sample1", + "pixelator/logs/sample1/sample1.pixelator-analysis.log" + ], + [ + [ + "PIXELATOR_ANALYSIS", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T11:57:42.454900722", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA analysis - stub": { + "content": [ + { + "0": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "4": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-analysis.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + "analysis", + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "6": [ + [ + "PIXELATOR_ANALYSIS", + "pixelator", + "0.26.0" + ] + ], + "all_results": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-analysis.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pixelfile": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_ANALYSIS", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:27:59.265000672", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/collapse/main.nf b/modules/local/pixelator/collapse/main.nf similarity index 87% rename from modules/local/pixelator/single-cell-pna/collapse/main.nf rename to modules/local/pixelator/collapse/main.nf index 4251de7c..ae0b0f55 100644 --- a/modules/local/pixelator/single-cell-pna/collapse/main.nf +++ b/modules/local/pixelator/collapse/main.nf @@ -1,4 +1,4 @@ -process PIXELATOR_PNA_COLLAPSE { +process PIXELATOR_COLLAPSE { tag "${meta.id}" label 'process_medium' @@ -7,8 +7,8 @@ process PIXELATOR_PNA_COLLAPSE { // TODO: Add conda // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(reads), path(panel_file), val(panel), val(design) @@ -18,6 +18,7 @@ process PIXELATOR_PNA_COLLAPSE { tuple val(meta), path("collapse/*.report.json", arity: '1..*'), emit: report_json tuple val(meta), path("collapse/*.meta.json"), emit: metadata_json tuple val(meta), path("*pixelator-collapse.log"), emit: log + tuple val('collapse'), path("collapse/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/collapse/meta.yml b/modules/local/pixelator/collapse/meta.yml new file mode 100644 index 00000000..c5ab74dd --- /dev/null +++ b/modules/local/pixelator/collapse/meta.yml @@ -0,0 +1,102 @@ +name: pixelator_collapse +description: Run `pixelator single-cell-pna collapse` to collapse reads into molecule-level parquet outputs. +keywords: + - pixelator + - single-cell-pna + - collapse + - parquet +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', design:'pna-2' ] + - reads: + type: file + description: Input FASTQ files. + pattern: "*.{fq,fastq,fq.gz,fastq.gz,fq.zst,fastq.zst}" + ontologies: + - http://edamontology.org/format_2545 + - panel_file: + type: file + description: Optional panel definition file. + ontologies: [] + - panel: + type: string + description: Optional panel name. + - design: + type: string + description: Assay design identifier. +output: + collapsed: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.parquet": + type: file + description: Collapsed molecule-level parquet output(s). + pattern: "*.parquet" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-collapse.log": + type: file + description: Pixelator collapse command log. + pattern: "*pixelator-collapse.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test b/modules/local/pixelator/collapse/tests/main.nf.test similarity index 67% rename from modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test rename to modules/local/pixelator/collapse/tests/main.nf.test index 0ffa619e..331fa9bd 100644 --- a/modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test +++ b/modules/local/pixelator/collapse/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_COLLAPSE" + name "Test Process PIXELATOR_COLLAPSE" script "../main.nf" - process "PIXELATOR_PNA_COLLAPSE" + process "PIXELATOR_COLLAPSE" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_collapse" + tag "pixelator/collapse" test("PNA collapse - stub") { @@ -16,13 +15,13 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.demux.m1.part_000.parquet', checkIfExists: true) ], [], // panel_file - 'proxiome-immuno-155-v2', // panel - 'pna-2' // design + 'proxiome-v2-immuno-155-v1.0', // panel + 'proxiome-v2' // design ] """ } @@ -44,13 +43,13 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.demux.m1.part_000.parquet', checkIfExists: true) ], [], // panel_file - 'proxiome-immuno-155-v2', // panel - 'pna-2' // design + 'proxiome-v2-immuno-155-v1.0', // panel + 'proxiome-v2' // design ] """ } @@ -79,14 +78,14 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.demux.m1.part_001.parquet', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.demux.m1.part_000.parquet', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/pool1.demux.m2.part_000.parquet', checkIfExists: true) ], [], // panel_file - 'proxiome-immuno-155-v2', // panel - 'pna-2' // design + 'proxiome-v2-immuno-155-v1.0', // panel + 'proxiome-v2' // design ] """ } diff --git a/modules/local/pixelator/collapse/tests/main.nf.test.snap b/modules/local/pixelator/collapse/tests/main.nf.test.snap new file mode 100644 index 00000000..57a182ea --- /dev/null +++ b/modules/local/pixelator/collapse/tests/main.nf.test.snap @@ -0,0 +1,186 @@ +{ + "PNA collapse - small test - single file": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.m1.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_000.parquet", + "pixelator/collapse/pool1.collapse.m1.part_000.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-collapse.log" + ], + [ + [ + "PIXELATOR_COLLAPSE", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T11:58:24.85769919", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA collapse - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.m1.part_000.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.m1.part_000.pixelator-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "collapse", + [ + "pool1.demux.m1.part_000.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m1.part_000.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + "PIXELATOR_COLLAPSE", + "pixelator", + "0.26.0" + ] + ], + "collapsed": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.m1.part_000.pixelator-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.m1.part_000.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_COLLAPSE", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:28:34.287934812", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA collapse - small test - multiple files": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.m1.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_000.parquet", + "pixelator/collapse/pool1.collapse.m1.part_000.report.json", + "pixelator/collapse/pool1.collapse.m2.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_000.parquet", + "pixelator/collapse/pool1.collapse.m2.part_000.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-collapse.log" + ], + null + ], + "timestamp": "2026-05-21T11:58:56.273822152", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/combine_collapse/main.nf b/modules/local/pixelator/combine_collapse/main.nf similarity index 89% rename from modules/local/pixelator/single-cell-pna/combine_collapse/main.nf rename to modules/local/pixelator/combine_collapse/main.nf index 3ecb4c19..f427e040 100644 --- a/modules/local/pixelator/single-cell-pna/combine_collapse/main.nf +++ b/modules/local/pixelator/combine_collapse/main.nf @@ -1,4 +1,4 @@ -process PIXELATOR_PNA_COMBINE_COLLAPSE { +process PIXELATOR_COMBINE_COLLAPSE { tag "${meta.id}" label 'process_medium' @@ -6,8 +6,8 @@ process PIXELATOR_PNA_COMBINE_COLLAPSE { // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(parquet_files, stageAs: "parquet/*"), path(json_report_files, stageAs: "reports/*") @@ -17,6 +17,7 @@ process PIXELATOR_PNA_COMBINE_COLLAPSE { tuple val(meta), path("collapse/*.report.json"), emit: report_json tuple val(meta), path("collapse/*.meta.json"), emit: metadata_json tuple val(meta), path("*pixelator-combine-collapse.log"), emit: log + tuple val('collapse'), path("collapse/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/combine_collapse/meta.yml b/modules/local/pixelator/combine_collapse/meta.yml new file mode 100644 index 00000000..1b64cf96 --- /dev/null +++ b/modules/local/pixelator/combine_collapse/meta.yml @@ -0,0 +1,96 @@ +name: pixelator_combine_collapse +description: Run `pixelator single-cell-pna combine-collapse` to merge multiple collapse outputs. +keywords: + - pixelator + - single-cell-pna + - combine-collapse + - parquet +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - parquet_files: + type: file + description: Parquet files produced by collapse. + pattern: "*.parquet" + ontologies: [] + - json_report_files: + type: file + description: JSON reports associated with collapse parquet files. + pattern: "*.report.json" + ontologies: [] +output: + parquet: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.parquet": + type: file + description: Combined collapse parquet output. + pattern: "*.parquet" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-combine-collapse.log": + type: file + description: Pixelator combine-collapse command log. + pattern: "*pixelator-combine-collapse.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/combine_collapse/tests/main.nf.test b/modules/local/pixelator/combine_collapse/tests/main.nf.test new file mode 100644 index 00000000..15e2e383 --- /dev/null +++ b/modules/local/pixelator/combine_collapse/tests/main.nf.test @@ -0,0 +1,80 @@ +nextflow_process { + + name "Test Process PIXELATOR_COMBINE_COLLAPSE" + script "../main.nf" + process "PIXELATOR_COMBINE_COLLAPSE" + tag "modules" + tag "pixelator" + tag "modules_pixelator" + tag "pixelator/combine_collapse" + + + test("PNA combine collapse - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + [ + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m1.part_000.parquet', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m2.part_000.parquet', checkIfExists: true), + ], + [ + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m1.part_000.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m2.part_000.report.json', checkIfExists: true) + ] + ] + """ + } + } + + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("PNA combine collapse - multiple files") { + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + [ + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m1.part_000.parquet', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m2.part_000.parquet', checkIfExists: true), + ], + [ + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m1.part_000.report.json', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.m2.part_000.report.json', checkIfExists: true) + ] + ] + """ + } + } + + + then { + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // All stable path name, with a relative path + stable_name, + process.out.versions_pixelator, + ).match() } + ) + } + } +} diff --git a/modules/local/pixelator/combine_collapse/tests/main.nf.test.snap b/modules/local/pixelator/combine_collapse/tests/main.nf.test.snap new file mode 100644 index 00000000..b2e75a61 --- /dev/null +++ b/modules/local/pixelator/combine_collapse/tests/main.nf.test.snap @@ -0,0 +1,152 @@ +{ + "PNA combine collapse - multiple files": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.parquet", + "pixelator/collapse/pool1.meta.json", + "pixelator/collapse/pool1.report.json", + "pixelator/logs", + "pixelator/logs/pool1.pixelator-combine-collapse.log" + ], + [ + [ + "PIXELATOR_COMBINE_COLLAPSE", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T11:59:42.965992059", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA combine collapse - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.collapse.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.collapse.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-combine-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "collapse", + [ + "pool1.collapse.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.collapse.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + "PIXELATOR_COMBINE_COLLAPSE", + "pixelator", + "0.26.0" + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-combine-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.collapse.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "parquet": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.collapse.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_COMBINE_COLLAPSE", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:29:17.917223368", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/demux/main.nf b/modules/local/pixelator/demux/main.nf similarity index 90% rename from modules/local/pixelator/single-cell-pna/demux/main.nf rename to modules/local/pixelator/demux/main.nf index e2490760..dd5ce74e 100644 --- a/modules/local/pixelator/single-cell-pna/demux/main.nf +++ b/modules/local/pixelator/demux/main.nf @@ -1,4 +1,4 @@ -process PIXELATOR_PNA_DEMUX { +process PIXELATOR_DEMUX { tag "${meta.id}" label 'process_medium' @@ -6,8 +6,8 @@ process PIXELATOR_PNA_DEMUX { // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(reads), path(panel_file), val(panel), val(design) @@ -19,6 +19,7 @@ process PIXELATOR_PNA_DEMUX { tuple val(meta), path("demux/*.report.json"), emit: report_json tuple val(meta), path("demux/*.meta.json"), emit: metadata_json tuple val(meta), path("*pixelator-demux.log"), emit: log + tuple val('demux'), path("demux/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/demux/meta.yml b/modules/local/pixelator/demux/meta.yml new file mode 100644 index 00000000..a138345f --- /dev/null +++ b/modules/local/pixelator/demux/meta.yml @@ -0,0 +1,122 @@ +name: pixelator_demux +description: Run `pixelator single-cell-pna demux` to split reads and generate demultiplexed outputs. +keywords: + - pixelator + - single-cell-pna + - demux + - parquet +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', design:'pna-2' ] + - reads: + type: file + description: Input FASTQ files. + pattern: "*.{fq,fastq,fq.gz,fastq.gz,fq.zst,fastq.zst}" + ontologies: + - http://edamontology.org/format_2545 + - panel_file: + type: file + description: Optional panel definition file. + ontologies: [] + - panel: + type: string + description: Optional panel name. + - design: + type: string + description: Assay design identifier. +output: + demuxed: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.parquet": + type: file + description: Demultiplexed parquet output(s). + pattern: "*.parquet" + ontologies: [] + passed: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*demux.passed*.{fq,fastq}.zst": + type: file + description: Reads that passed demultiplexing. + pattern: "*demux.passed*.{fq,fastq}.zst" + ontologies: + - http://edamontology.org/format_2545 + failed: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*demux.failed.{fq,fastq}.zst": + type: file + description: Reads that failed demultiplexing. + pattern: "*demux.failed.{fq,fastq}.zst" + ontologies: + - http://edamontology.org/format_2545 + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-demux.log": + type: file + description: Pixelator demux command log. + pattern: "*pixelator-demux.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test b/modules/local/pixelator/demux/tests/main.nf.test similarity index 71% rename from modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test rename to modules/local/pixelator/demux/tests/main.nf.test index bf01b060..dacc77e8 100644 --- a/modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test +++ b/modules/local/pixelator/demux/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_DEMUX" + name "Test Process PIXELATOR_DEMUX" script "../main.nf" - process "PIXELATOR_PNA_DEMUX" + process "PIXELATOR_DEMUX" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_demux" + tag "pixelator/demux" test("PNA demux - stub") { @@ -19,11 +18,11 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.amplicon.fq.zst', checkIfExists: true), + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.amplicon.fq.zst', checkIfExists: true), [], - 'proxiome-immuno-155-v2', - 'pna-2' + 'proxiome-v2-immuno-155-v1.0', + 'proxiome-v2' ] """ } @@ -45,11 +44,11 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.amplicon.fq.zst', checkIfExists: true), + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.amplicon.fq.zst', checkIfExists: true), [], - 'proxiome-immuno-155-v2', - 'pna-2' + 'proxiome-v2-immuno-155-v1.0', + 'proxiome-v2' ] """ } @@ -80,11 +79,11 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.amplicon.fq.zst', checkIfExists: true), + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/pool1.amplicon.fq.zst', checkIfExists: true), [], - 'proxiome-immuno-155-v2', - 'pna-2' + 'proxiome-v2-immuno-155-v1.0', + 'proxiome-v2' ] """ } diff --git a/modules/local/pixelator/demux/tests/main.nf.test.snap b/modules/local/pixelator/demux/tests/main.nf.test.snap new file mode 100644 index 00000000..dba8dc77 --- /dev/null +++ b/modules/local/pixelator/demux/tests/main.nf.test.snap @@ -0,0 +1,254 @@ +{ + "PNA demux - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/demux", + "pixelator/demux/pool1.demux.failed.fq.zst", + "pixelator/demux/pool1.demux.m1.part_000.parquet", + "pixelator/demux/pool1.demux.m2.part_000.parquet", + "pixelator/demux/pool1.demux.passed.fq.zst", + "pixelator/demux/pool1.meta.json", + "pixelator/demux/pool1.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-demux.log" + ], + [ + [ + "PIXELATOR_DEMUX", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T12:00:37.132304324", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA demux - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m2.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.passed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.failed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-demux.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + "demux", + [ + "pool1.demux.failed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m2.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.passed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "7": [ + [ + "PIXELATOR_DEMUX", + "pixelator", + "0.26.0" + ] + ], + "demuxed": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.demux.m2.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "failed": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.failed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-demux.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "passed": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.demux.passed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_DEMUX", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:29:38.959759778", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA demux - multiple chunks": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/demux", + "pixelator/demux/pool1.demux.failed.fq.zst", + "pixelator/demux/pool1.demux.m1.part_000.parquet", + "pixelator/demux/pool1.demux.m1.part_001.parquet", + "pixelator/demux/pool1.demux.m1.part_002.parquet", + "pixelator/demux/pool1.demux.m1.part_003.parquet", + "pixelator/demux/pool1.demux.m1.part_004.parquet", + "pixelator/demux/pool1.demux.m1.part_005.parquet", + "pixelator/demux/pool1.demux.m1.part_006.parquet", + "pixelator/demux/pool1.demux.m1.part_007.parquet", + "pixelator/demux/pool1.demux.m2.part_000.parquet", + "pixelator/demux/pool1.demux.m2.part_001.parquet", + "pixelator/demux/pool1.demux.m2.part_002.parquet", + "pixelator/demux/pool1.demux.m2.part_003.parquet", + "pixelator/demux/pool1.demux.m2.part_004.parquet", + "pixelator/demux/pool1.demux.m2.part_005.parquet", + "pixelator/demux/pool1.demux.m2.part_006.parquet", + "pixelator/demux/pool1.demux.m2.part_007.parquet", + "pixelator/demux/pool1.demux.passed.fq.zst", + "pixelator/demux/pool1.meta.json", + "pixelator/demux/pool1.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-demux.log" + ], + [ + [ + "PIXELATOR_DEMUX", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T12:01:07.6787683", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/demux/tests/multiple_chunks.config b/modules/local/pixelator/demux/tests/multiple_chunks.config similarity index 62% rename from modules/local/pixelator/single-cell-pna/demux/tests/multiple_chunks.config rename to modules/local/pixelator/demux/tests/multiple_chunks.config index 4cffec50..6a12f124 100644 --- a/modules/local/pixelator/single-cell-pna/demux/tests/multiple_chunks.config +++ b/modules/local/pixelator/demux/tests/multiple_chunks.config @@ -1,5 +1,5 @@ process { - withName: "PIXELATOR_PNA_DEMUX" { + withName: "PIXELATOR_DEMUX" { ext.args = "--output-chunk-reads 40K" } } diff --git a/modules/local/pixelator/single-cell-pna/denoise/main.nf b/modules/local/pixelator/denoise/main.nf similarity index 86% rename from modules/local/pixelator/single-cell-pna/denoise/main.nf rename to modules/local/pixelator/denoise/main.nf index 02cb20ee..3018a54d 100644 --- a/modules/local/pixelator/single-cell-pna/denoise/main.nf +++ b/modules/local/pixelator/denoise/main.nf @@ -1,4 +1,4 @@ -process PIXELATOR_PNA_DENOISE { +process PIXELATOR_DENOISE { tag "$meta.id" label 'process_high' @@ -6,8 +6,8 @@ process PIXELATOR_PNA_DENOISE { // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(data) @@ -18,6 +18,7 @@ process PIXELATOR_PNA_DENOISE { tuple val(meta), path("denoise/*.meta.json") , emit: metadata_json tuple val(meta), path("denoise/*") , emit: all_results tuple val(meta), path("*pixelator-denoise.log") , emit: log + tuple val('denoise'), path("denoise/*") , topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/denoise/meta.yml b/modules/local/pixelator/denoise/meta.yml new file mode 100644 index 00000000..714730c8 --- /dev/null +++ b/modules/local/pixelator/denoise/meta.yml @@ -0,0 +1,99 @@ +name: pixelator_denoise +description: Run `pixelator single-cell-pna denoise` on graph output data. +keywords: + - pixelator + - single-cell-pna + - denoise + - pxl +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - data: + type: file + description: Input file for the denoise subcommand. + ontologies: [] +output: + pixelfile: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.pxl": + type: file + description: Pixelator PXL output file. + pattern: "*.pxl" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + all_results: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*": + type: directory + description: All files generated in the denoise output directory. + pattern: "*" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-denoise.log": + type: file + description: Pixelator denoise command log. + pattern: "*pixelator-denoise.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test b/modules/local/pixelator/denoise/tests/main.nf.test similarity index 71% rename from modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test rename to modules/local/pixelator/denoise/tests/main.nf.test index 797968f7..b6c383cf 100644 --- a/modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test +++ b/modules/local/pixelator/denoise/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_DENOISE" + name "Test Process PIXELATOR_DENOISE" script "../main.nf" - process "PIXELATOR_PNA_DENOISE" + process "PIXELATOR_DENOISE" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_denoise" + tag "pixelator/denoise" test("PNA denoise - stub") { @@ -15,8 +14,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true), + [ id:'sample1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.dehashed.pxl', checkIfExists: true), ] """ } @@ -38,8 +37,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true), + [ id:'sample1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/sample_calling/sample1.dehashed.pxl', checkIfExists: true), ] """ } diff --git a/modules/local/pixelator/denoise/tests/main.nf.test.snap b/modules/local/pixelator/denoise/tests/main.nf.test.snap new file mode 100644 index 00000000..70b8cfa2 --- /dev/null +++ b/modules/local/pixelator/denoise/tests/main.nf.test.snap @@ -0,0 +1,182 @@ +{ + "PNA denoise - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/denoise", + "pixelator/denoise/sample1.meta.json", + "pixelator/denoise/sample1.report.json", + "pixelator/logs", + "pixelator/logs/sample1", + "pixelator/logs/sample1/sample1.pixelator-denoise.log" + ], + [ + [ + "PIXELATOR_DENOISE", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T12:01:36.760255316", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA denoise - stub": { + "content": [ + { + "0": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "4": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-denoise.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + "denoise", + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "6": [ + [ + "PIXELATOR_DENOISE", + "pixelator", + "0.26.0" + ] + ], + "all_results": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-denoise.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pixelfile": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_DENOISE", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:30:37.793498942", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/graph/main.nf b/modules/local/pixelator/graph/main.nf similarity index 87% rename from modules/local/pixelator/single-cell-pna/graph/main.nf rename to modules/local/pixelator/graph/main.nf index 372a5cf4..0ccc74f8 100644 --- a/modules/local/pixelator/single-cell-pna/graph/main.nf +++ b/modules/local/pixelator/graph/main.nf @@ -1,11 +1,11 @@ -process PIXELATOR_PNA_GRAPH { +process PIXELATOR_GRAPH { tag "${meta.id}" label 'process_high_memory' label 'process_long' container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(edge_list), path(panel_file), val(panel) @@ -16,6 +16,7 @@ process PIXELATOR_PNA_GRAPH { tuple val(meta), path("graph/*.report.json"), emit: report_json tuple val(meta), path("graph/*.meta.json"), emit: metadata_json tuple val(meta), path("*pixelator-graph.log"), emit: log + tuple val('graph'), path("graph/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/graph/meta.yml b/modules/local/pixelator/graph/meta.yml new file mode 100644 index 00000000..a2846c98 --- /dev/null +++ b/modules/local/pixelator/graph/meta.yml @@ -0,0 +1,106 @@ +name: pixelator_graph +description: Run `pixelator single-cell-pna graph` to build graph-level pixel files. +keywords: + - pixelator + - single-cell-pna + - graph + - pxl +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - edge_list: + type: file + description: Input edge list parquet file. + ontologies: [] + - panel_file: + type: file + description: Optional panel definition file. + ontologies: [] + - panel: + type: string + description: Optional panel name. +output: + all_results: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*": + type: directory + description: All files generated in the graph output directory. + pattern: "*" + ontologies: [] + pixelfile: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.pxl": + type: file + description: Pixelator PXL output file. + pattern: "*.pxl" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-graph.log": + type: file + description: Pixelator graph command log. + pattern: "*pixelator-graph.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test b/modules/local/pixelator/graph/tests/main.nf.test similarity index 70% rename from modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test rename to modules/local/pixelator/graph/tests/main.nf.test index d71d5032..2a68005a 100644 --- a/modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test +++ b/modules/local/pixelator/graph/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_GRAPH" + name "Test Process PIXELATOR_GRAPH" script "../main.nf" - process "PIXELATOR_PNA_GRAPH" + process "PIXELATOR_GRAPH" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_graph" + tag "pixelator/graph" test("PNA graph - stub") { @@ -20,10 +19,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.parquet', checkIfExists: true), + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.parquet', checkIfExists: true), [], - 'proxiome-immuno-155-v2', + 'proxiome-v2-immuno-155-v1.0', ] """ } @@ -47,10 +46,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.parquet', checkIfExists: true), + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/pool1.collapse.parquet', checkIfExists: true), [], - 'proxiome-immuno-155-v2', + 'proxiome-v2-immuno-155-v1.0', ] """ } diff --git a/modules/local/pixelator/graph/tests/main.nf.test.snap b/modules/local/pixelator/graph/tests/main.nf.test.snap new file mode 100644 index 00000000..98c4ff8f --- /dev/null +++ b/modules/local/pixelator/graph/tests/main.nf.test.snap @@ -0,0 +1,183 @@ +{ + "PNA graph - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-graph.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + "graph", + [ + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "6": [ + [ + "PIXELATOR_GRAPH", + "pixelator", + "0.26.0" + ] + ], + "all_results": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-graph.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pixelfile": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_GRAPH", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:31:00.131846199", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA graph - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/graph", + "pixelator/graph/pool1.graph.pxl", + "pixelator/graph/pool1.meta.json", + "pixelator/graph/pool1.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-graph.log" + ], + [ + [ + "PIXELATOR_GRAPH", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T12:02:11.997776808", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/layout/main.nf b/modules/local/pixelator/layout/main.nf similarity index 86% rename from modules/local/pixelator/single-cell-pna/layout/main.nf rename to modules/local/pixelator/layout/main.nf index 0b85fbff..fecb0f68 100644 --- a/modules/local/pixelator/single-cell-pna/layout/main.nf +++ b/modules/local/pixelator/layout/main.nf @@ -1,12 +1,12 @@ -process PIXELATOR_PNA_LAYOUT { +process PIXELATOR_LAYOUT { tag "${meta.id}" label 'process_high' // TODO: Add conda // conda "bioconda::pixelator=0.18.2" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" input: tuple val(meta), path(data) @@ -18,6 +18,7 @@ process PIXELATOR_PNA_LAYOUT { tuple val(meta), path("layout/*"), emit: all_results tuple val(meta), path("*pixelator-layout.log"), emit: log + tuple val('layout'), path("layout/*"), topic: all_results_for_reports tuple val("${task.process}"), val('pixelator'), eval("pixelator --version 2>/dev/null | sed 's/pixelator, version //g'"), emit: versions_pixelator, topic: versions diff --git a/modules/local/pixelator/layout/meta.yml b/modules/local/pixelator/layout/meta.yml new file mode 100644 index 00000000..75eb3a9e --- /dev/null +++ b/modules/local/pixelator/layout/meta.yml @@ -0,0 +1,99 @@ +name: pixelator_layout +description: Run `pixelator single-cell-pna layout` to compute layout outputs from pixel data. +keywords: + - pixelator + - single-cell-pna + - layout + - pxl +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - data: + type: file + description: Input file for the layout subcommand. + ontologies: [] +output: + pixelfile: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.pxl": + type: file + description: Pixelator PXL output file. + pattern: "*.pxl" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.report.json": + type: file + description: Run report in JSON format. + pattern: "*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "*.meta.json" + ontologies: [] + all_results: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*": + type: directory + description: All files generated in the layout output directory. + pattern: "*" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-layout.log": + type: file + description: Pixelator layout command log. + pattern: "*pixelator-layout.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test b/modules/local/pixelator/layout/tests/main.nf.test similarity index 74% rename from modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test rename to modules/local/pixelator/layout/tests/main.nf.test index 2fdc8524..db2f832a 100644 --- a/modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test +++ b/modules/local/pixelator/layout/tests/main.nf.test @@ -1,12 +1,11 @@ nextflow_process { - name "Test Process PIXELATOR_PNA_LAYOUT" + name "Test Process PIXELATOR_LAYOUT" script "../main.nf" - process "PIXELATOR_PNA_LAYOUT" + process "PIXELATOR_LAYOUT" tag "modules" tag "pixelator" - tag "pixelator/pna" - tag "pixelator/single_cell_pna_layout" + tag "pixelator/layout" test("Test PNA layout - stub") { @@ -22,8 +21,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design: 'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.analysis.pxl', checkIfExists: true) + [ id:'sample1', design: 'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample1.analysis.pxl', checkIfExists: true) ] """ } @@ -48,8 +47,8 @@ nextflow_process { process { """ input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design: 'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.analysis.pxl', checkIfExists: true) + [ id:'sample1', design: 'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/sample1.analysis.pxl', checkIfExists: true) ] """ } diff --git a/modules/local/pixelator/layout/tests/main.nf.test.snap b/modules/local/pixelator/layout/tests/main.nf.test.snap new file mode 100644 index 00000000..cd2c7733 --- /dev/null +++ b/modules/local/pixelator/layout/tests/main.nf.test.snap @@ -0,0 +1,183 @@ +{ + "Test PNA layout - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/layout", + "pixelator/layout/sample1.meta.json", + "pixelator/layout/sample1.report.json", + "pixelator/logs", + "pixelator/logs/sample1", + "pixelator/logs/sample1/sample1.pixelator-layout.log", + "pixelator/sample1.layout.pxl" + ], + [ + [ + "PIXELATOR_LAYOUT", + "pixelator", + "0.26.0" + ] + ] + ], + "timestamp": "2026-05-21T12:02:56.888630957", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "Test PNA layout - stub": { + "content": [ + { + "0": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "4": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-layout.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + "layout", + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "6": [ + [ + "PIXELATOR_LAYOUT", + "pixelator", + "0.26.0" + ] + ], + "all_results": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pixelator-layout.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pixelfile": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report_json": [ + [ + { + "id": "sample1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "sample1.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_pixelator": [ + [ + "PIXELATOR_LAYOUT", + "pixelator", + "0.26.0" + ] + ] + } + ], + "timestamp": "2026-05-20T14:31:26.577414445", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/list_options/main.nf b/modules/local/pixelator/list_options/main.nf index dd24023f..bef8d5a3 100644 --- a/modules/local/pixelator/list_options/main.nf +++ b/modules/local/pixelator/list_options/main.nf @@ -5,8 +5,8 @@ process PIXELATOR_LIST_OPTIONS { // TODO: Add conda back // conda "${moduleDir}/environment.yml" container "${params.pixelator_container?:workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'quay.io/pixelgen-technologies/pixelator:0.23.0' - : 'quay.io/pixelgen-technologies/pixelator:0.23.0'}" + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" output: path "design_options.txt", emit: designs @@ -28,11 +28,13 @@ process PIXELATOR_LIST_OPTIONS { stub: """ cat <<-END_DESIGN > design_options.txt - pna-2 + proxiome-v1 + proxiome-v2 END_DESIGN cat <<-END_PANELS > panel_options.txt - proxiome-immuno-155-v2 + proxiome-v1-immuno-155-v1.1 + proxiome-v2-immuno-155-v1.0 END_PANELS """ } diff --git a/modules/local/pixelator/list_options/meta.yml b/modules/local/pixelator/list_options/meta.yml new file mode 100644 index 00000000..5889867d --- /dev/null +++ b/modules/local/pixelator/list_options/meta.yml @@ -0,0 +1,57 @@ +name: pixelator_list_options +description: List available Pixelator single-cell-pna design and panel options. +keywords: + - pixelator + - single-cell-pna + - list + - options +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: [] +output: + designs: + - - design_options.txt: + type: file + description: Text file containing available design options. + pattern: "design_options.txt" + ontologies: [] + panels: + - - panel_options.txt: + type: file + description: Text file containing available panel options. + pattern: "panel_options.txt" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/sample_calling/main.nf b/modules/local/pixelator/sample_calling/main.nf new file mode 100644 index 00000000..efc7b9ff --- /dev/null +++ b/modules/local/pixelator/sample_calling/main.nf @@ -0,0 +1,72 @@ +process PIXELATOR_SAMPLE_CALLING { + tag "${meta.id}" + label 'process_high' + + // TODO: Add conda + // conda "bioconda::pixelator=0.18.2" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'quay.io/pixelgen-technologies/pixelator:0.26.0' + : 'quay.io/pixelgen-technologies/pixelator:0.26.0'}" + + input: + tuple val(meta), path(data), path(samplesheet) + + output: + tuple val(meta), path("sample_calling/*.pxl"), emit: pixelfile + tuple val(meta), path("sample_calling/*.report.json"), emit: report_json + tuple val(meta), path("sample_calling/*.meta.json"), emit: metadata_json + tuple val(meta), path("sample_calling/*"), emit: all_results + + tuple val(meta), path("*pixelator-sample-calling.log"), emit: log + tuple val('sample_calling'), path("sample_calling/*"), topic: all_results_for_reports + + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + + prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + + """ + pixelator \ + --cores ${task.cpus} \ + --log-file ${prefix}.pixelator-sample-calling.log \ + --verbose \ + single-cell-pna \ + sample-calling \ + --samplesheet ${samplesheet} \ + --output . \ + ${args} \ + ${data} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pixelator: \$(echo \$(pixelator --version 2>/dev/null) | sed 's/pixelator, version //g' ) + END_VERSIONS + """ + + // The stub here generates multiple output pxl files to mimic real run + // in reality these should match up with what has been configured in the + // samplesheet + stub: + prefix = task.ext.prefix ?: "${meta.id}" + + """ + mkdir sample_calling + touch sample_calling/${prefix}.sample_calling.report.json + touch sample_calling/${prefix}.sample_calling.meta.json + touch sample_calling/sample1.dehashed.pxl + touch sample_calling/sample2.dehashed.pxl + touch sample_calling/sample3.dehashed.pxl + touch sample_calling/sample4.dehashed.pxl + touch ${prefix}.pixelator-sample-calling.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pixelator: \$(echo \$(pixelator --version 2>/dev/null) | sed 's/pixelator, version //g' ) + END_VERSIONS + """ +} diff --git a/modules/local/pixelator/sample_calling/meta.yml b/modules/local/pixelator/sample_calling/meta.yml new file mode 100644 index 00000000..cf904a9b --- /dev/null +++ b/modules/local/pixelator/sample_calling/meta.yml @@ -0,0 +1,104 @@ +name: pixelator_sample_calling +description: Run `pixelator single-cell-pna sample-calling` to split data into sample-level pixel files. +keywords: + - pixelator + - single-cell-pna + - sample-calling + - pxl +tools: + - pixelator: + description: Single-cell sequencing data analysis toolkit from Pixelgen Technologies. + homepage: https://pixelgen.com/ + documentation: https://software.pixelgen.com/pixelator/ + licence: ["MIT"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1' ] + - data: + type: file + description: Input file for the sample-calling subcommand. + ontologies: [] + - samplesheet: + type: file + description: Samplesheet used to split results into sample-level outputs. + pattern: "*.{csv,tsv,txt}" + ontologies: [] +output: + pixelfile: + - - meta: + type: map + description: Groovy Map containing sample information. + - "sample_calling/*.pxl": + type: file + description: Sample-level Pixelator PXL output file(s). + pattern: "sample_calling/*.pxl" + ontologies: [] + report_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "sample_calling/*.report.json": + type: file + description: Run report in JSON format. + pattern: "sample_calling/*.report.json" + ontologies: [] + metadata_json: + - - meta: + type: map + description: Groovy Map containing sample information. + - "sample_calling/*.meta.json": + type: file + description: Metadata in JSON format. + pattern: "sample_calling/*.meta.json" + ontologies: [] + all_results: + - - meta: + type: map + description: Groovy Map containing sample information. + - "sample_calling/*": + type: directory + description: All files generated in the sample-calling output directory. + pattern: "sample_calling/*" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information. + - "*pixelator-sample-calling.log": + type: file + description: Pixelator sample-calling command log. + pattern: "*pixelator-sample-calling.log" + ontologies: [] + versions_pixelator: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from. + - pixelator: + type: string + description: The tool name. + - pixelator --version 2>/dev/null | sed 's/pixelator, version //g': + type: eval + description: The expression used to obtain the tool version. +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/modules/local/pixelator/sample_calling/tests/main.nf.test b/modules/local/pixelator/sample_calling/tests/main.nf.test new file mode 100644 index 00000000..aff4ddf5 --- /dev/null +++ b/modules/local/pixelator/sample_calling/tests/main.nf.test @@ -0,0 +1,64 @@ +nextflow_process { + + name "Test Process PIXELATOR_SAMPLE_CALLING" + script "../main.nf" + process "PIXELATOR_SAMPLE_CALLING" + tag "modules" + tag "pixelator" + tag "pixelator/pna" + tag "pixelator/sample_calling" + + test("PNA sample calling - stub") { + + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool1.graph.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_proxiome_v2.csv', checkIfExists: true), + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("PNA sample calling - small test") { + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [ id:'pool1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v2' ], + file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/pool1.graph.pxl', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'samplesheet/pna/samplesheet_proxiome_v2.csv', checkIfExists: true), + ] + """ + } + } + + then { + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // All stable path name, with a relative path + stable_name, + process.out.versions_pixelator, + ).match() } + ) + } + } +} diff --git a/modules/local/pixelator/sample_calling/tests/main.nf.test.snap b/modules/local/pixelator/sample_calling/tests/main.nf.test.snap new file mode 100644 index 00000000..7d531009 --- /dev/null +++ b/modules/local/pixelator/sample_calling/tests/main.nf.test.snap @@ -0,0 +1,194 @@ +{ + "PNA sample calling - small test": { + "content": [ + 1, + [ + "pipeline_info", + "pixelator", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1/pool1.pixelator-sample-calling.log", + "pixelator/sample_calling", + "pixelator/sample_calling/pool1.sample_calling.report.json", + "pixelator/sample_calling/pool1_undetermined.meta.json", + "pixelator/sample_calling/pool1_undetermined.report.json", + "pixelator/sample_calling/sample1.dehashed.pxl", + "pixelator/sample_calling/sample1.meta.json", + "pixelator/sample_calling/sample1.report.json", + "pixelator/sample_calling/sample2.dehashed.pxl", + "pixelator/sample_calling/sample2.meta.json", + "pixelator/sample_calling/sample2.report.json" + ], + null + ], + "timestamp": "2026-05-21T12:03:20.674454727", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "PNA sample calling - stub": { + "content": [ + { + "0": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.sample_calling.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.sample_calling.report.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "4": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-sample-calling.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + "sample_calling", + [ + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.sample_calling.report.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "6": [ + "versions.yml:md5,7c42eee900660ec5bcdc04fbbb2e2e3e" + ], + "all_results": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.sample_calling.report.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "log": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.pixelator-sample-calling.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metadata_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pixelfile": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + [ + "sample1.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.dehashed.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "report_json": [ + [ + { + "id": "pool1", + "design": "proxiome-v2", + "panel": "proxiome-v2-immuno-155-v1.0", + "technology": "proxiome-v2" + }, + "pool1.sample_calling.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,7c42eee900660ec5bcdc04fbbb2e2e3e" + ] + } + ], + "timestamp": "2026-05-20T14:31:49.737316113", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test.snap deleted file mode 100644 index 5f396d08..00000000 --- a/modules/local/pixelator/single-cell-pna/amplicon/tests/main.nf.test.snap +++ /dev/null @@ -1,141 +0,0 @@ -{ - "PNA amplicon - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.amplicon.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-amplicon.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - "PIXELATOR_PNA_AMPLICON", - "pixelator", - "0.23.0" - ] - ], - "amplicon": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.amplicon.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-amplicon.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_AMPLICON", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T13:57:19.517355298" - }, - "PNA amplicon - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/amplicon", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-amplicon.log" - ], - [ - [ - "PIXELATOR_PNA_AMPLICON", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T13:58:10.802280883" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/amplicon/tests/tags.yml b/modules/local/pixelator/single-cell-pna/amplicon/tests/tags.yml deleted file mode 100644 index dc533a28..00000000 --- a/modules/local/pixelator/single-cell-pna/amplicon/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_amplicon: - - modules/local/pixelator/single-cell-pna/amplicon/** diff --git a/modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test.snap deleted file mode 100644 index f497c737..00000000 --- a/modules/local/pixelator/single-cell-pna/analysis/tests/main.nf.test.snap +++ /dev/null @@ -1,171 +0,0 @@ -{ - "PNA analysis - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/analysis", - "pixelator/analysis/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-analysis.log" - ], - [ - [ - "PIXELATOR_PNA_ANALYSIS", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:01:56.742281294" - }, - "PNA analysis - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "4": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-analysis.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - "PIXELATOR_PNA_ANALYSIS", - "pixelator", - "0.23.0" - ] - ], - "all_results": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-analysis.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "pixelfile": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_ANALYSIS", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T13:58:25.311094417" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/analysis/tests/tags.yml b/modules/local/pixelator/single-cell-pna/analysis/tests/tags.yml deleted file mode 100644 index 12f2ae52..00000000 --- a/modules/local/pixelator/single-cell-pna/analysis/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_analysis: - - modules/local/pixelator/single-cell-pna/analysis/** diff --git a/modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test.snap deleted file mode 100644 index c351c53b..00000000 --- a/modules/local/pixelator/single-cell-pna/collapse/tests/main.nf.test.snap +++ /dev/null @@ -1,171 +0,0 @@ -{ - "PNA collapse - small test - single file": { - "content": [ - 1, - [ - "pixelator", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-collapse.log" - ], - [ - [ - "PIXELATOR_PNA_COLLAPSE", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:02:49.092397636" - }, - "PNA collapse - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.m1.part_000.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.m1.part_000.pixelator-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - "PIXELATOR_PNA_COLLAPSE", - "pixelator", - "0.23.0" - ] - ], - "collapsed": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.m1.part_000.pixelator-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.m1.part_000.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_COLLAPSE", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:02:16.992233383" - }, - "PNA collapse - small test - multiple files": { - "content": [ - 1, - [ - "pixelator", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-collapse.log" - ], - null - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:03:21.487439646" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/collapse/tests/tags.yml b/modules/local/pixelator/single-cell-pna/collapse/tests/tags.yml deleted file mode 100644 index b5e97eb0..00000000 --- a/modules/local/pixelator/single-cell-pna/collapse/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_collapse: - - modules/local/pixelator/single-cell-pna/collapse/** diff --git a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test b/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test deleted file mode 100644 index 00220c34..00000000 --- a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test +++ /dev/null @@ -1,89 +0,0 @@ -nextflow_process { - - name "Test Process PIXELATOR_PNA_COMBINE_COLLAPSE" - script "../main.nf" - process "PIXELATOR_PNA_COMBINE_COLLAPSE" - tag "modules" - tag "pixelator" - tag "pixelator/pna" - tag "modules_pixelator" - tag "pixelator/single_cell_pna_combine_collapse" - - - test("PNA combine collapse - stub") { - - options "-stub" - - when { - process { - """ - input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.parquet', checkIfExists: true), - ], - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.report.json', checkIfExists: true) - ] - ] - """ - } - } - - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("PNA combine collapse - multiple files") { - when { - params { - outdir = "$outputDir" - } - process { - """ - input[0] = [ - [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ], - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.parquet', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.parquet', checkIfExists: true), - ], - [ - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.report.json', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.report.json', checkIfExists: true) - ] - ] - """ - } - } - - - then { - def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) - assertAll( - { assert workflow.success }, - { assert snapshot( - // Number of successful tasks - workflow.trace.succeeded().size(), - // All stable path name, with a relative path - stable_name, - process.out.versions_pixelator, - ).match() } - ) - } - } -} diff --git a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test.snap deleted file mode 100644 index 79c3e70e..00000000 --- a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/main.nf.test.snap +++ /dev/null @@ -1,141 +0,0 @@ -{ - "PNA combine collapse - multiple files": { - "content": [ - 1, - [ - "pixelator", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log" - ], - [ - [ - "PIXELATOR_PNA_COMBINE_COLLAPSE", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:04:05.138304037" - }, - "PNA combine collapse - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.collapse.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.collapse.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - "PIXELATOR_PNA_COMBINE_COLLAPSE", - "pixelator", - "0.23.0" - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.collapse.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "parquet": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.collapse.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_COMBINE_COLLAPSE", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:03:40.204931897" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/multiple_chunks.config b/modules/local/pixelator/single-cell-pna/combine_collapse/tests/multiple_chunks.config deleted file mode 100644 index 89181d1c..00000000 --- a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/multiple_chunks.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: "PIXELATOR_PNA_DEMUX" { - ext.args = "--output-chunk-size 40K" - } -} diff --git a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/tags.yml b/modules/local/pixelator/single-cell-pna/combine_collapse/tests/tags.yml deleted file mode 100644 index c2b7a926..00000000 --- a/modules/local/pixelator/single-cell-pna/combine_collapse/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_demux: - - modules/local/pixelator/single-cell-pna/demux/** diff --git a/modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test.snap deleted file mode 100644 index 325861bc..00000000 --- a/modules/local/pixelator/single-cell-pna/demux/tests/main.nf.test.snap +++ /dev/null @@ -1,217 +0,0 @@ -{ - "PNA demux - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/demux", - "pixelator/demux/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-demux.log" - ], - [ - [ - "PIXELATOR_PNA_DEMUX", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:05:08.373454769" - }, - "PNA demux - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.demux.m2.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.passed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.failed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-demux.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "6": [ - [ - "PIXELATOR_PNA_DEMUX", - "pixelator", - "0.23.0" - ] - ], - "demuxed": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.demux.m2.part_000.parquet:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "failed": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.failed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-demux.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "passed": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.demux.passed.fq.zst:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_DEMUX", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:04:18.304195722" - }, - "PNA demux - multiple chunks": { - "content": [ - 1, - [ - "pixelator", - "pixelator/demux", - "pixelator/demux/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-demux.log" - ], - [ - [ - "PIXELATOR_PNA_DEMUX", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:05:49.98769129" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/demux/tests/tags.yml b/modules/local/pixelator/single-cell-pna/demux/tests/tags.yml deleted file mode 100644 index c2b7a926..00000000 --- a/modules/local/pixelator/single-cell-pna/demux/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_demux: - - modules/local/pixelator/single-cell-pna/demux/** diff --git a/modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test.snap deleted file mode 100644 index 4044f38a..00000000 --- a/modules/local/pixelator/single-cell-pna/denoise/tests/main.nf.test.snap +++ /dev/null @@ -1,171 +0,0 @@ -{ - "PNA denoise - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/denoise", - "pixelator/denoise/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-denoise.log" - ], - [ - [ - "PIXELATOR_PNA_DENOISE", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:06:20.982865336" - }, - "PNA denoise - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "4": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-denoise.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - "PIXELATOR_PNA_DENOISE", - "pixelator", - "0.23.0" - ] - ], - "all_results": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-denoise.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "pixelfile": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_DENOISE", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:06:01.113423824" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test.snap deleted file mode 100644 index 56632406..00000000 --- a/modules/local/pixelator/single-cell-pna/graph/tests/main.nf.test.snap +++ /dev/null @@ -1,171 +0,0 @@ -{ - "PNA graph - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-graph.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - "PIXELATOR_PNA_GRAPH", - "pixelator", - "0.23.0" - ] - ], - "all_results": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-graph.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "pixelfile": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_GRAPH", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:06:31.8229537" - }, - "PNA graph - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/graph", - "pixelator/graph/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-graph.log" - ], - [ - [ - "PIXELATOR_PNA_GRAPH", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2025-12-11T14:06:46.156401007" - } -} \ No newline at end of file diff --git a/modules/local/pixelator/single-cell-pna/graph/tests/tags.yml b/modules/local/pixelator/single-cell-pna/graph/tests/tags.yml deleted file mode 100644 index a3b68c3c..00000000 --- a/modules/local/pixelator/single-cell-pna/graph/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/single_cell_pna_graph: - - modules/local/pixelator/single-cell-pna/graph/** diff --git a/modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test.snap b/modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test.snap deleted file mode 100644 index 96a3b9eb..00000000 --- a/modules/local/pixelator/single-cell-pna/layout/tests/main.nf.test.snap +++ /dev/null @@ -1,172 +0,0 @@ -{ - "Test PNA layout - small test": { - "content": [ - 1, - [ - "pixelator", - "pixelator/PNA055_Sample07_filtered_S7.layout.pxl", - "pixelator/layout", - "pixelator/layout/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-layout.log" - ], - [ - [ - "PIXELATOR_PNA_LAYOUT", - "pixelator", - "0.23.0" - ] - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2026-02-04T13:06:34.606588167" - }, - "Test PNA layout - stub": { - "content": [ - { - "0": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "4": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-layout.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - "PIXELATOR_PNA_LAYOUT", - "pixelator", - "0.23.0" - ] - ], - "all_results": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - [ - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e", - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "log": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pixelator-layout.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "metadata_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "pixelfile": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.pxl:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "report_json": [ - [ - { - "id": "PNA055_Sample07_filtered_S7", - "design": "pna-2", - "panel": "proxiome-immuno-155-v2", - "technology": "pna" - }, - "PNA055_Sample07_filtered_S7.report.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_pixelator": [ - [ - "PIXELATOR_PNA_LAYOUT", - "pixelator", - "0.23.0" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2026-02-04T13:06:03.163681958" - } -} \ No newline at end of file diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index e70af3d1..8d12a78c 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -3,7 +3,7 @@ process CAT_FASTQ { label 'process_single' conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" diff --git a/nextflow.config b/nextflow.config index 93d154a3..9212c8df 100644 --- a/nextflow.config +++ b/nextflow.config @@ -31,9 +31,12 @@ params { save_pna_demux_failed_reads = false save_pna_collapsed_reads = false save_pna_graph_pixelfile = false + save_pna_sample_calling_pixelfile = false save_pna_denoise_pixelfile = false save_pna_analysis_pixelfile = false + technology = null + // PNA amplicon pna_amplicon_mismatches = 0.1 pna_amplicon_remove_polyg = true @@ -57,19 +60,22 @@ params { // PNA graph pna_graph_multiplet_recovery = true - pna_graph_leiden_iterations = 1 pna_graph_initial_stage_leiden_resolution = 1.0 pna_graph_refinement_stage_leiden_resolution = 0.01 pna_graph_min_count = 1 - pna_graph_min_component_size_in_refinement = 1000 - pna_graph_max_refinement_recursion_depth = 5 - pna_graph_initial_stage_max_edges_to_remove = null - pna_graph_refinement_stage_max_edges_to_remove = 4 + pna_graph_max_refinement_recursion_depth = 3 + pna_graph_edge_cycle_verification = true + pna_graph_initial_stage_max_edges_to_remove = 10 + pna_graph_refinement_stage_max_edges_to_remove = 10 pna_graph_initial_stage_max_edges_to_remove_relative = null pna_graph_refinement_stage_max_edges_to_remove_relative = null - pna_graph_graph_min_component_size_to_prune = 100 pna_graph_component_size_min_threshold = 8000 + // sample-calling options + pna_sample_calling_remove_incompatible = true + pna_sample_calling_save_undetermined = false + pna_sample_calling_confidence_threshold = 0.9 + // PNA denoise pna_denoise_run_one_core_graph_denoising = true pna_denoise_pval_threshold = 0.05 @@ -105,12 +111,12 @@ params { email_on_fail = null plaintext_email = false monochrome_logs = false - hook_url = System.getenv('HOOK_URL') help = false help_full = false show_hidden = false version = false - pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/' + pipelines_testdata_base_path = System.getenv('NFT_TESTDATA_BASE_PATH') ?: 'https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/' + modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' trace_report_suffix = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') // Config options @@ -126,21 +132,13 @@ params { validate_params = true } +// Backwards compatibility for publishDir syntax +outputDir = params.outdir +workflow.output.mode = params.publish_dir_mode + // Load base.config by default for all pipelines includeConfig 'conf/base.config' -def container_env_options = [ - "MPLCONFIGDIR": '/tmp/.config/matplotlib', - "NUMBA_CACHE_DIR": "/tmp/.numba_cache", - - // quarto needs a writeable cache directory - "XDG_CACHE_HOME": "/tmp/.cache", - "XDG_DATA_HOME": "/tmp/.data", - - // DuckDB temp directory when running in containers - "PIXELATOR_DUCKDB_TEMP_DIR": "/tmp", -] - profiles { debug { dumpHashes = true @@ -177,7 +175,7 @@ profiles { charliecloud.enabled = false apptainer.enabled = false docker.runOptions = '-u $(id -u):$(id -g)' - env = container_env_options + includeConfig 'conf/container_env.config' } arm64 { process.arch = 'arm64' @@ -202,7 +200,7 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - env = container_env_options + includeConfig 'conf/container_env.config' } podman { podman.enabled = true @@ -213,7 +211,7 @@ profiles { charliecloud.enabled = false apptainer.enabled = false podman.runOptions = '--userns=keep-id' - env = container_env_options + includeConfig 'conf/container_env.config' } shifter { shifter.enabled = true @@ -223,7 +221,7 @@ profiles { podman.enabled = false charliecloud.enabled = false apptainer.enabled = false - env = container_env_options + includeConfig 'conf/container_env.config' } charliecloud { charliecloud.enabled = true @@ -233,7 +231,7 @@ profiles { podman.enabled = false shifter.enabled = false apptainer.enabled = false - env = container_env_options + includeConfig 'conf/container_env.config' } apptainer { apptainer.enabled = true @@ -244,7 +242,7 @@ profiles { podman.enabled = false shifter.enabled = false charliecloud.enabled = false - env = container_env_options + includeConfig 'conf/container_env.config' } wave { apptainer.ociAutoPull = true @@ -260,12 +258,28 @@ profiles { } test { - includeConfig 'conf/test_pna.config' + includeConfig 'conf/test.config' + } + + test_proxiome_v1 { + includeConfig 'conf/test_proxiome_v1.config' + } + + test_proxiome_v2 { + includeConfig 'conf/test_proxiome_v2.config' } test_full { includeConfig 'conf/test_full.config' } + + cells_1k { + includeConfig 'conf/cells_1k.config' + } + + cells_8k { + includeConfig 'conf/cells_8k.config' + } } // Load nf-core custom profiles from different institutions includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" @@ -356,14 +370,15 @@ manifest { description = """Pipeline for analysis of Proximity Network Assay data""" mainScript = 'main.nf' defaultBranch = 'master' - nextflowVersion = '!>=25.04.0' - version = '3.0.1' + nextflowVersion = '!>=25.10.4' + version = '4.0.0' doi = '10.1101/2023.06.05.543770' } // Nextflow plugins plugins { id 'nf-schema@2.5.1' + id 'nf-slack@0.5.1' } validation { @@ -371,6 +386,13 @@ validation { monochromeLogs = params.monochrome_logs } +slack { + enabled = true + webhook { + url = System.getenv('HOOK_URL') + } +} + // Load modules.config for DSL2 module specific options includeConfig 'conf/modules.config' includeConfig 'conf/modules.pna.config' diff --git a/nextflow_schema.json b/nextflow_schema.json index d0fac578..38aa0806 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,7 +10,7 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": ["input", "outdir"], + "required": ["input", "outdir", "technology"], "properties": { "input": { "type": "string", @@ -45,9 +45,9 @@ } }, "pna_amplicon_options": { - "title": "Amplicon generation options", + "title": "Amplicon options", "type": "object", - "fa_icon": "fas fa-circle", + "fa_icon": "fas fa-dna", "properties": { "save_pna_amplicon_reads": { "fa_icon": "fas fa-save", @@ -57,30 +57,33 @@ }, "pna_amplicon_mismatches": { "type": "number", + "fa_icon": "fas fa-not-equal", "minimum": 0, "maximum": 0.5, "description": "The number of mismatches allowed while anchoring reads using LBS sequences (in percentage of seen LBS length) [default: 0.1; 0.0<=x<=0.5]", "default": 0.1 }, "pna_amplicon_remove_polyg": { - "fa_icon": "fas g", "description": "Remove PolyG sequences (length of 10 or more)", + "fa_icon": "fas fa-cut", "type": "boolean", "default": true }, "pna_amplicon_quality_cutoff": { - "fa_icon": "fas gauge", "description": "Minimum average quality a read must have. Pass 0 to disable quality filtering.", + "fa_icon": "fas fa-sliders-h", "type": "integer", "default": 20 }, "pna_amplicon_low_complexity_filter": { "type": "boolean", + "fa_icon": "fas fa-filter", "default": true, "description": "Enable filtering of amplicons with low complexity UMI sequences." }, "pna_amplicon_low_complexity_threshold": { "type": "number", + "fa_icon": "fas fa-percentage", "default": 0.8, "minimum": 0.5, "maximum": 1, @@ -88,11 +91,13 @@ }, "pna_amplicon_lbs_filter": { "type": "boolean", + "fa_icon": "fas fa-filter", "default": true, "description": "Enable filtering of amplicons with UMI sequences that show similarity to the LBS sequence." }, "pna_amplicon_lbs_filter_min_overlap": { "type": "integer", + "fa_icon": "fas fa-arrows-alt-h", "default": 8, "minimum": 4, "maximum": 28, @@ -100,6 +105,7 @@ }, "pna_amplicon_lbs_filter_error_rate": { "type": "number", + "fa_icon": "fas fa-percentage", "default": 0.1, "minimum": 0, "maximum": 1, @@ -108,11 +114,12 @@ } }, "pna_demux_options": { - "title": "Demux options for PNA data", + "title": "Demux options", "type": "object", + "fa_icon": "fas fa-random", "properties": { "pna_demux_mismatches": { - "fa_icon": "fas not-equal", + "fa_icon": "fas fa-not-equal", "description": "The number of mismatches allowed in marker barcodes.", "type": "integer", "default": 1, @@ -166,9 +173,10 @@ "pna_collapse_options": { "title": "Collapse options", "type": "object", + "fa_icon": "fas fa-compress-alt", "properties": { "pna_collapse_algorithm": { - "fa_icon": "fas code-fork", + "fa_icon": "fas fa-project-diagram", "description": "The algorithm to use for collapsing.", "default": "directional", "enum": ["cluster", "directional"], @@ -176,7 +184,7 @@ "help": "**cluster:** Form networks of connected UMIs (based on hamming distance threshold). Each connected component is a read group. In the above example, all the UMIs are contained in a single connected component and thus there is one read group containing all reads, with ACGT as the `selected` UMI.\n\n**directional (default):** Form networks with edges defined based on hamming distance threshold and node A counts >= (2 * node B counts) - 1. Each connected component is a read group, with the node with the highest counts selected as the top node for the component." }, "pna_collapse_mismatches": { - "fa_icon": "fas not-equal", + "fa_icon": "fas fa-not-equal", "description": "The number of mismatches allowed when collapsing (adjacency)", "type": "integer", "default": 2, @@ -192,27 +200,25 @@ } }, "pna_graph_options": { - "title": "Options for pixelator graph command on PNA data.", + "title": "Graph options", "type": "object", + "fa_icon": "fas fa-project-diagram", "properties": { "save_pna_graph_pixelfile": { "type": "boolean", + "fa_icon": "fas fa-save", "description": "Save the PXL dataset after the graph stage.", "help": "By default, the PXL file after graph will not be saved to the results directory unless `--skip_analysis` and `--skip_layout` is passed. Specify this flag (or set to `true` in your config file) to copy these files to the results directory when complete." }, "pna_graph_multiplet_recovery": { "description": "Activate the multiplet recovery using leiden community detection", + "fa_icon": "fas fa-project-diagram", "type": "boolean", "default": true }, - "pna_graph_leiden_iterations": { - "type": "integer", - "default": 1, - "description": "Number of iterations for the leiden algorithm.", - "help": "High values will decrease the variance of the results but increase the runtime" - }, "pna_graph_initial_stage_leiden_resolution": { - "default": 1, + "default": 1.0, + "fa_icon": "fas fa-sliders-h", "minimum": 0, "type": "number", "description": "The resolution parameter for the leiden algorithm at the initial stage.", @@ -220,72 +226,111 @@ }, "pna_graph_refinement_stage_leiden_resolution": { "default": 0.01, + "fa_icon": "fas fa-sliders-h", "minimum": 0, "type": "number", "description": "The resolution parameter for the leiden algorithm at the refinement stage.", "help": "This should typically be set lower than the initial stage resolution." }, + "pna_graph_edge_cycle_verification": { + "type": "boolean", + "fa_icon": "fas fa-check-circle", + "default": true, + "description": "Activate edge cycle verification to remove edges from well connected regions that are not part of cycles in the graph.", + "help": "This option can help improve the quality of the graph by removing potentially false edges." + }, "pna_graph_min_count": { - "default": 1, + "default": 1.0, + "fa_icon": "fas fa-hashtag", "maximum": 50, "minimum": 0, "type": "number", "description": "Discard edges with a read count below given value. Set to 1 to disable filtering." }, - "pna_graph_min_component_size_in_refinement": { - "type": "integer", - "default": 1000, - "minimum": 1, - "description": "The minimum component size to consider for refinement" - }, "pna_graph_max_refinement_recursion_depth": { "type": "integer", - "default": 5, + "fa_icon": "fas fa-sitemap", + "default": 3, "minimum": 1, "maximum": 100, "description": "The maximum recursion depth for the refinement algorithm. Set to 1 to disable refinement." }, "pna_graph_initial_stage_max_edges_to_remove": { "type": "integer", + "fa_icon": "fas fa-trash", + "default": 10, "minimum": 1, "description": "The maximum number of edges to remove between components during the initial stage (iteration == 0) of multiplet recovery." }, "pna_graph_refinement_stage_max_edges_to_remove": { "type": "integer", - "default": 4, + "fa_icon": "fas fa-trash", + "default": 10, "minimum": 1, "description": "The maximum number of edges to remove between components during the refinement stage (iteration > 0) of multiplet recovery." }, "pna_graph_initial_stage_max_edges_to_remove_relative": { "type": "number", + "fa_icon": "fas fa-trash", "minimum": 0, "description": "The maximum number of edges to remove between two components relative to the number of nodes in the smaller of the two when during the initial stage (iteration == 0) of multiplet recovery." }, "pna_graph_refinement_stage_max_edges_to_remove_relative": { "type": "number", + "fa_icon": "fas fa-trash", "minimum": 0, "description": "The maximum number of edges to remove between two components relative to the number of nodes in the smaller of the two when during the refinement stage (iteration > 0) of multiplet recovery." }, - "pna_graph_graph_min_component_size_to_prune": { - "type": "integer", - "minimum": 1, - "default": 100, - "description": "The minimum number of nodes in an potential new components in order for it to be pruned." - }, "pna_graph_component_size_min_threshold": { "type": "integer", + "fa_icon": "fas fa-expand-alt", "minimum": 1, "default": 8000, "description": "Components with fewer nodes than this will be filtered from the output data. Set to null to enable automatic size filtering based on the data." } } }, + "pna_sample_calling_options": { + "title": "Sample calling options", + "type": "object", + "fa_icon": "fas fa-vial", + "properties": { + "save_pna_sample_calling_pixelfile": { + "type": "boolean", + "fa_icon": "fas fa-save", + "description": "Save the PXL dataset after the sample calling stage.", + "help": "By default, the PXL file after sample calling will not be saved to the results directory. Specify this flag (or set to `true` in your config file) to copy these files to the results directory when complete." + }, + "pna_sample_calling_save_undetermined": { + "type": "boolean", + "fa_icon": "fas fa-save", + "description": "Save components that could not be confidently assigned to any sample to a separate pxl file." + }, + "pna_sample_calling_remove_incompatible": { + "type": "boolean", + "fa_icon": "fas fa-trash", + "description": "Remove antibodies that are incompatible with their component's called sample.", + "default": true + }, + "pna_sample_calling_confidence_threshold": { + "type": "number", + "fa_icon": "fas fa-percentage", + "description": "Confidence threshold for sample calling.", + "help_text": "Components with a sample confidence below this threshold will be considered undetermined.", + "default": 0.9, + "minimum": 0.0, + "maximum": 1.0 + } + } + }, "pna_denoise_options": { - "title": "Options for pixelator denoise command.", + "title": "Denoise options", "type": "object", + "fa_icon": "fas fa-microscope", "properties": { "skip_denoise": { "description": "Skip denoise step", + "fa_icon": "fas fa-forward", "type": "boolean" }, "save_pna_denoise_pixelfile": { @@ -296,17 +341,20 @@ }, "pna_denoise_run_one_core_graph_denoising": { "description": "Activate the one-core graph denoising algorithm", + "fa_icon": "fas fa-microscope", "type": "boolean", "default": true }, "pna_denoise_pval_threshold": { "type": "number", + "fa_icon": "fas fa-flask", "description": "The p-value threshold for the a marker to be considered significantly over-expressed in the one-core layer of a component", "default": 0.05, "minimum": 0 }, "pna_denoise_inflate_factor": { "type": "number", + "fa_icon": "fas fa-expand-arrows-alt", "description": "The inflate factor for the number of nodes from over-expressed markers to be removed from the one-core layer of a component", "default": 1.5, "minimum": 1 @@ -314,11 +362,13 @@ } }, "pna_analysis_options": { - "title": "Options for pixelator analysis command.", + "title": "Analysis options", "type": "object", + "fa_icon": "fas fa-chart-line", "properties": { "skip_analysis": { "description": "Skip analysis step", + "fa_icon": "fas fa-forward", "type": "boolean" }, "save_pna_analysis_pixelfile": { @@ -329,27 +379,32 @@ }, "pna_analysis_compute_proximity": { "description": "Compute proximity scores", + "fa_icon": "fas fa-ruler-combined", "type": "boolean", "default": true }, "pna_analysis_compute_k_cores": { "description": "Compute k-core summary tables for each component", + "fa_icon": "fas fa-network-wired", "type": "boolean", "default": true }, "pna_analysis_proximity_nbr_of_permutations": { "type": "integer", + "fa_icon": "fas fa-random", "description": "Number of permutations to use when computing the expected proximity scores", "default": 100, "minimum": 50 }, "pna_analysis_compute_svd_var_explained": { "description": "Compute the variance explained by the SVD components", + "fa_icon": "fas fa-chart-pie", "type": "boolean", "default": true }, "pna_analysis_svd_nbr_of_pivots": { "type": "integer", + "fa_icon": "fas fa-compass", "description": "Number of pivots to use for the SVD decomposition", "default": 50, "minimum": 10, @@ -358,31 +413,37 @@ } }, "pna_layout_options": { - "title": "Options for pixelator single-cell-pna layout command.", + "title": "Layout options", "type": "object", + "fa_icon": "fas fa-draw-polygon", "properties": { "skip_layout": { "description": "Skip layout step", + "fa_icon": "fas fa-forward", "type": "boolean" }, "pna_layout_no_node_marker_counts": { "description": "Skip adding marker counts to the layout.", + "fa_icon": "fas fa-ban", "type": "boolean" }, "pna_layout_layout_algorithm": { "description": "Select a layout algorithm to use. This can be specified as a comma separated list to compute multiple layouts. Possible values are: pmds, pmds_3d, wpmds, wpmds_3d.", + "fa_icon": "fas fa-project-diagram", "type": "string", "enum": ["pmds_3d", "wpmds_3d"], "default": "wpmds_3d" }, "pna_layout_pmds_pivots": { "type": "integer", + "fa_icon": "fas fa-compass", "description": "Number of pivots to use for the PMDS layout algorithm. Default: 50. More gives better results, but increases computation time.", "default": 50, "minimum": 50 }, "pna_layout_wpmds_k": { "type": "integer", + "fa_icon": "fas fa-ruler", "description": "The window size used when computing probability weights for the wpmds layout method. Only used when layout algorithm is set to wpmds.", "default": 5, "minimum": 1, @@ -391,11 +452,13 @@ } }, "experiment_summary_options": { - "title": "Options for experiment summary.", + "title": "Experiment Summary options", "type": "object", + "fa_icon": "fas fa-clipboard-list", "properties": { "skip_experiment_summary": { "description": "Skip experiment summary generation", + "fa_icon": "fas fa-forward", "type": "boolean" } } @@ -403,15 +466,18 @@ "global_config_options": { "title": "Global options", "type": "object", + "fa_icon": "fas fa-cogs", "description": "Global configuration options specific to nf-core/pixelator.", "properties": { "pixelator_container": { "type": "string", + "fa_icon": "fas fa-box", "description": "Override the container image reference to use for all steps using the `pixelator` command.", "help_text": "Use this to force the pipeline to use a different image version in all steps that use the pixelator command.\nThe pipeline is not guaranteed to work when using different pixelator versions." }, "experiment_summary_container": { "type": "string", + "fa_icon": "fas fa-box", "description": "Override the container image to use for the experiment summary step.", "help_text": "Use this to force the pipeline to use a different image version for the experiment summary step.\nThe pipeline is not guaranteed to work when using different experiment summary versions." }, @@ -426,6 +492,12 @@ "type": "boolean", "default": true, "description": "Save all JSON report and metadata files generated by pixelator." + }, + "technology": { + "type": "string", + "fa_icon": "fas fa-microchip", + "description": "The technology used to process the samples", + "enum": ["proxiome-v1", "proxiome-v2", "hashed_samples", "nonhashed_samples"] } } }, @@ -519,13 +591,6 @@ "fa_icon": "fas fa-palette", "hidden": true }, - "hook_url": { - "type": "string", - "description": "Incoming hook URL for messaging service", - "fa_icon": "fas fa-people-group", - "help_text": "Incoming hook URL for messaging service. Currently, MS Teams and Slack are supported.", - "hidden": true - }, "validate_params": { "type": "boolean", "description": "Boolean whether to validate parameters against the schema at runtime", @@ -540,9 +605,14 @@ "default": "https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/", "hidden": true }, + "modules_testdata_base_path": { + "type": "string", + "description": "Base path / URL for data used in the modules", + "default": "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/", + "hidden": true + }, "trace_report_suffix": { "type": "string", - "fa_icon": "far calendar", "description": "Suffix to add to the trace report filename. Default is the date and time in the format yyyy-MM-dd_HH-mm-ss.", "hidden": true }, @@ -577,6 +647,9 @@ { "$ref": "#/$defs/pna_graph_options" }, + { + "$ref": "#/$defs/pna_sample_calling_options" + }, { "$ref": "#/$defs/pna_denoise_options" }, diff --git a/nf-test.config b/nf-test.config index d84fa287..598e68d5 100644 --- a/nf-test.config +++ b/nf-test.config @@ -1,21 +1,39 @@ config { // location for all nf-test tests - testsDir "." + testsDir = "." // nf-test directory including temporary files for each test - workDir System.getenv("NFT_WORKDIR") ?: ".nf-test" + workDir = System.getenv("NFT_WORKDIR") ?: ".nf-test" // location of an optional nextflow.config file specific for executing tests - configFile "tests/nextflow.config" + configFile = "tests/nextflow.config" // ignore tests coming from the nf-core/modules repo - ignore 'modules/nf-core/**/tests/*', 'subworkflows/nf-core/**/tests/*' + ignore = [ + 'modules/nf-core/**/tests/*', + 'subworkflows/nf-core/**/tests/*', + ] // run all test with defined profile(s) from the main nextflow.config - profile "test" + profile = "test" // list of filenames or patterns that should be trigger a full test run - triggers 'nextflow.config', 'nf-test.config', 'conf/test.config', 'tests/nextflow.config', 'tests/.nftignore', 'assets/schema_input.json', 'nextflow_schema.json' + triggers = [ + // template triggers + '.github/actions/nf-test/action.yml', + '.github/workflows/nf-test.yml', + 'assets/schema_input.json', + 'bin/*', + 'conf/test.config', + 'nextflow.config', + 'nextflow_schema.json', + 'nf-test.config', + 'tests/.nftignore', + 'tests/nextflow.config', + + // pixelator triggers + 'conf/container_env.config', + ] // load the necessary plugins plugins { diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 50808df0..7963e0fc 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -22,8 +22,8 @@ "@id": "./", "@type": "Dataset", "creativeWorkStatus": "Stable", - "datePublished": "2026-03-09T09:30:49+00:00", - "description": "

\n \n \n \"nf-core/pixelator\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/pixelator)\n[![GitHub Actions CI Status](https://github.com/nf-core/pixelator/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/pixelator/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/pixelator/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/pixelator/actions/workflows/linting.yml)\n[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pixelator/results)\n[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.10015112-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.10015112)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/pixelator)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pixelator-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pixelator)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/pixelator** is a bioinformatics best-practice analysis pipeline for analysis of data from the\nProximity Network (PNA) assay. It takes a samplesheet as input and will process your data\nusing `pixelator` to produce a PXL file containing single-cell protein abundance and protein interactomics data.\n\n![](./docs/images/nf-core-pixelator-metromap.svg)\n\nThe pipeline will run the following steps:\n\n1. Do quality control checks of input reads and build amplicons ([`pixelator single-cell-pna amplicon`](https://github.com/PixelgenTechnologies/pixelator))\n2. Create groups of amplicons based on their marker assignments ([`pixelator single-cell-pna demux`](https://github.com/PixelgenTechnologies/pixelator))\n3. Derive original molecules to use as edge list downstream by error correcting, and counting input amplicons ([`pixelator single-cell-pna collapse`](https://github.com/PixelgenTechnologies/pixelator))\n4. Compute the components of the graph from the edge list in order to create putative cells ([`pixelator single-cell-pna graph`](https://github.com/PixelgenTechnologies/pixelator))\n5. Denoise the cell graphs ([`pixelator single-cell-pna denoise`](https://github.com/PixelgenTechnologies/pixelator))\n6. Analyze the spatial information in the cell graphs ([`pixelator single-cell-pna analysis`](https://github.com/PixelgenTechnologies/pixelator))\n7. Generate 3D graph layouts for visualization of cells ([`pixelator single-cell-pna layout`](https://github.com/PixelgenTechnologies/pixelator))\n8. Proxiome Experiment Summary generation using [PixelatorES](https://github.com/PixelgenTechnologies/pixelatorES)\n\n> [!NOTE]\n> If you are looking to run the pipeline with Molecular Pixelation (MPX) data. Please refer to the [release 2.3.1](https://nf-co.re/pixelator/2.3.1/),\n> which is the last version to support that data type.\n\n> [!WARNING]\n> Since Nextflow 23.07.0-edge, Nextflow no longer mounts the host's home directory when using Apptainer or Singularity.\n> This causes issues in some dependencies. As a workaround, you can revert to the old behavior by setting the environment variable\n> `NXF_APPTAINER_HOME_MOUNT` or `NXF_SINGULARITY_HOME_MOUNT` to `true` in the machine from which you launch the pipeline.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet with your input data that looks as follows (the exact values you need to input depend on the design and panel you are using - please see [https://nf-co.re/pixelator/usage](https://nf-co.re/pixelator/usage) for more details):\n\n`samplesheet.csv`:\n\n```csv\nsample,sample_alias,condition,design,panel,fastq_1,fastq_2\nsample1,s1,control,pna-2,proxiome-immuno-155-v2,sample1_R1_001.fastq.gz,sample1_R2_001.fastq.gz\n```\n\nEach row represents a sample and gives the design, a panel file and the input fastq files.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/pixelator \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> This version of the pipeline does not support conda environments, due to issues with upstream dependencies.\n> This means you cannot use the `conda` and `mamba` profiles. Please use `docker` or `singularity` instead.\n> We hope to add support for conda environments in the future.\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/pixelator/usage) and the [parameter documentation](https://nf-co.re/pixelator/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/pixelator/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/pixelator/output).\n\n## Credits\n\nnf-core/pixelator was originally written for [Pixelgen Technologies AB](https://www.pixelgen.com/) by:\n\n- Florian De Temmerman\n- Johan Dahlberg\n- Alvaro Martinez Barrio\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 `#pixelator` channel](https://nfcore.slack.com/channels/pixelator) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/pixelator for your analysis, please cite it using the following doi: [10.5281/zenodo.10015112](https://doi.org/10.5281/zenodo.10015112)\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\nYou can cite the Proximity Network Technology as follows:\n\n> **Single-Cell Protein Interactomes by the Proximity Network Assay.**\n>\n> Filip Karlsson, Michele Simonetti, Christina Galonska, Max Karlsson, Hanna van Ooijen, Tomasz Kallas, Divya Thiagarajan, Maud Schweitzer, Ludvig Larsson, Vincent van Hoef, Pouria Tajvar, Johan Dahlberg, Florian De Temmerman, Louise Leijonancker, Sylvain Geny, Rikard Forlin, Erika Negrini, Stefan Petkov, Lovisa Franz\u00e9n, Jessica Bunz, Christine Moge, Henrik Everberg, Petter Brodin, Alvaro Martinez Barrio, Simon Fredriksson\n>\n> _bioRxiv_ 2025.06.19.660329; doi: [10.1101/2025.06.19.660329](https://doi.org/10.1101/2025.06.19.660329)\n", + "datePublished": "2026-05-19T08:43:42+00:00", + "description": "

\n \n \n \"nf-core/pixelator\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/pixelator)\n[![GitHub Actions CI Status](https://github.com/nf-core/pixelator/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/pixelator/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/pixelator/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/pixelator/actions/workflows/linting.yml)\n[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pixelator/results)\n[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.10015112-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.10015112)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.10.4-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-4.0.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/4.0.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/pixelator)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pixelator-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pixelator)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/pixelator** is a bioinformatics best-practice analysis pipeline for analysis of data from the\nProximity Network (PNA) assay. It takes a samplesheet as input and will process your data\nusing `pixelator` to produce a PXL file containing single-cell protein abundance and protein interactomics data.\n\n![](./docs/images/nf-core-pixelator-metromap.svg)\n\nThe pipeline will run the following steps:\n\n1. Do quality control checks of input reads and build amplicons ([`pixelator single-cell-pna amplicon`](https://github.com/PixelgenTechnologies/pixelator))\n2. Create groups of amplicons based on their marker assignments ([`pixelator single-cell-pna demux`](https://github.com/PixelgenTechnologies/pixelator))\n3. Derive original molecules to use as edge list downstream by error correcting, and counting input amplicons ([`pixelator single-cell-pna collapse`](https://github.com/PixelgenTechnologies/pixelator))\n4. Compute the components of the graph from the edge list in order to create putative cells ([`pixelator single-cell-pna graph`](https://github.com/PixelgenTechnologies/pixelator))\n5. _(Conditional; only for PNA hashed data)_ Assign components to samples in pooled experiments ([`pixelator single-cell-pna sample-calling`](https://github.com/PixelgenTechnologies/pixelator))\n6. Denoise the cell graphs ([`pixelator single-cell-pna denoise`](https://github.com/PixelgenTechnologies/pixelator))\n7. Analyze the spatial information in the cell graphs ([`pixelator single-cell-pna analysis`](https://github.com/PixelgenTechnologies/pixelator))\n8. Generate 3D graph layouts for visualization of cells ([`pixelator single-cell-pna layout`](https://github.com/PixelgenTechnologies/pixelator))\n9. Proxiome Experiment Summary generation using [PixelatorES](https://github.com/PixelgenTechnologies/pixelatorES)\n\n> [!NOTE]\n> If you are looking to run the pipeline with Molecular Pixelation (MPX) data. Please refer to the [release 2.3.1](https://nf-co.re/pixelator/2.3.1/),\n> which is the last version to support that data type.\n\n> [!WARNING]\n> Since Nextflow 23.07.0-edge, Nextflow no longer mounts the host's home directory when using Apptainer or Singularity.\n> This causes issues in some dependencies. As a workaround, you can revert to the old behavior by setting the environment variable\n> `NXF_APPTAINER_HOME_MOUNT` or `NXF_SINGULARITY_HOME_MOUNT` to `true` in the machine from which you launch the pipeline.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/get_started/environment_setup/overview) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/get_started/run-your-first-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet with your input data that looks as follows (the exact values you need to input depend on the design and panel you are using - please see [https://nf-co.re/pixelator/usage](https://nf-co.re/pixelator/usage) for more details).\nFor hashed PNA data (Proxiome kit v2), the samplesheet will look as follows:\n\n`samplesheet.csv`:\n\n```csv\npool,hash_index,sample,sample_alias,condition,design,panel,fastq_1,fastq_2\npool1,1,sample1,s1,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz\npool1,2,sample2,s2,case,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool1_R1_001.fastq.gz,pool1_R2_001.fastq.gz\npool2,1,sample3,s3,control,proxiome-v2,proxiome-v2-immuno-155-v1.0,pool2_R1_001.fastq.gz,pool2_R2_001.fastq.gz\n```\n\n> [!NOTE]\n> For an example with non-hashed PNA data (Proxiome kit v1), see [Proxiome v1 samplesheet](../assets/samplesheet_proxiome_v1.csv)\n\n> [!WARNING]\n> Panel and design names have been completely renamed in pixelator 0.26\n> (nf-core/pixelator 4.0 and above). Refer to the pixelator\n> [changelog](https://github.com/PixelgenTechnologies/pixelator/releases/tag/v0.26.0)\n> for more details.\n\nEach row represents a sample and gives the design, a panel file and the input fastq files.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/pixelator \\\n -profile , \\\n --technology \n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> This version of the pipeline does not support conda environments, due to issues with upstream dependencies.\n> This means you cannot use the `conda` and `mamba` profiles. Please use `docker` or `singularity` instead.\n> We hope to add support for conda environments in the future.\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/running/run-pipelines#using-parameter-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pixelator/usage) and the [parameter documentation](https://nf-co.re/pixelator/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/pixelator/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/pixelator/output).\n\n## Credits\n\nnf-core/pixelator was originally written for [Pixelgen Technologies AB](https://www.pixelgen.com/) by:\n\n- Florian De Temmerman\n- Johan Dahlberg\n- Alvaro Martinez Barrio\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](docs/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pixelator` channel](https://nfcore.slack.com/channels/pixelator) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/pixelator for your analysis, please cite it using the following doi: [10.5281/zenodo.10015112](https://doi.org/10.5281/zenodo.10015112)\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\nYou can cite the Proximity Network Technology as follows:\n\n> **Single-Cell Protein Interactomes by the Proximity Network Assay.**\n>\n> Filip Karlsson, Michele Simonetti, Christina Galonska, Max Karlsson, Hanna van Ooijen, Tomasz Kallas, Divya Thiagarajan, Maud Schweitzer, Ludvig Larsson, Vincent van Hoef, Pouria Tajvar, Johan Dahlberg, Florian De Temmerman, Louise Leijonancker, Sylvain Geny, Rikard Forlin, Erika Negrini, Stefan Petkov, Lovisa Franz\u00e9n, Jessica Bunz, Christine Moge, Henrik Everberg, Petter Brodin, Alvaro Martinez Barrio, Simon Fredriksson\n>\n> _bioRxiv_ 2025.06.19.660329; doi: [10.1101/2025.06.19.660329](https://doi.org/10.1101/2025.06.19.660329)\n", "hasPart": [ { "@id": "main.nf" @@ -102,7 +102,7 @@ }, "mentions": [ { - "@id": "#0937da83-39ee-4f26-ba19-81636de5941c" + "@id": "#e1d538fd-160d-4bef-9279-564055014e49" } ], "name": "nf-core/pixelator" @@ -129,19 +129,21 @@ "SoftwareSourceCode", "ComputationalWorkflow" ], - "creator": [ - { - "@id": "https://orcid.org/0000-0003-2702-1103" - }, + "author": [ { "@id": "https://orcid.org/0009-0006-0086-2470" + } + ], + "contributor": [ + { + "@id": "https://orcid.org/0000-0001-6962-1460" }, { - "@id": "#johan.dahlberg@pixelgen.tech" + "@id": "https://orcid.org/0000-0001-5064-2093" } ], "dateCreated": "", - "dateModified": "2026-03-09T10:30:49Z", + "dateModified": "2026-05-19T10:43:42Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -159,9 +161,6 @@ "maintainer": [ { "@id": "https://orcid.org/0009-0006-0086-2470" - }, - { - "@id": "#johan.dahlberg@pixelgen.tech" } ], "name": [ @@ -175,10 +174,10 @@ }, "url": [ "https://github.com/nf-core/pixelator", - "https://nf-co.re/pixelator/3.0.1/" + "https://nf-co.re/pixelator/4.0.0/" ], "version": [ - "3.0.1" + "4.0.0" ] }, { @@ -191,14 +190,14 @@ "url": { "@id": "https://www.nextflow.io/" }, - "version": "!>=25.04.0" + "version": "!>=25.10.4" }, { - "@id": "#0937da83-39ee-4f26-ba19-81636de5941c", + "@id": "#e1d538fd-160d-4bef-9279-564055014e49", "@type": "TestSuite", "instance": [ { - "@id": "#a64c8985-335d-483b-9020-cc0dffd1d4a2" + "@id": "#f2105274-dcac-426b-96f7-fc9f2b3e504a" } ], "mainEntity": { @@ -207,7 +206,7 @@ "name": "Test suite for nf-core/pixelator" }, { - "@id": "#a64c8985-335d-483b-9020-cc0dffd1d4a2", + "@id": "#f2105274-dcac-426b-96f7-fc9f2b3e504a", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/pixelator", "resource": "repos/nf-core/pixelator/actions/workflows/nf-test.yml", @@ -341,22 +340,28 @@ "url": "https://nf-co.re/" }, { - "@id": "https://orcid.org/0000-0003-2702-1103", + "@id": "https://orcid.org/0009-0006-0086-2470", "@type": "Person", - "email": "adrien.coulier@pixelgen.com", - "name": "Adrien Coulier" + "affiliation": "Pixelgen Technologies AB", + "email": "florian.detemmerman@pixelgen.com", + "name": "Florian De Temmerman", + "url": "https://github.com/fbdtemme" }, { - "@id": "https://orcid.org/0009-0006-0086-2470", + "@id": "https://orcid.org/0000-0001-6962-1460", "@type": "Person", - "email": "florian.detemmerman@pixelgen.com", - "name": "Florian De Temmerman" + "affiliation": "Pixelgen Technologies AB", + "email": "johan.dahlberg@pixelgen.com", + "name": "Johan Dahlberg", + "url": "https://github.com/johandahlberg" }, { - "@id": "#johan.dahlberg@pixelgen.tech", + "@id": "https://orcid.org/0000-0001-5064-2093", "@type": "Person", - "email": "johan.dahlberg@pixelgen.tech", - "name": "Johan Dahlberg" + "affiliation": "Pixelgen Technologies AB", + "email": "alvaro.martinez.barrio@pixelgen.com", + "name": "Alvaro Martinez Barrio", + "url": "https://github.com/ambarrio" } ] } \ No newline at end of file diff --git a/subworkflows/local/pna/generate_reports/main.nf b/subworkflows/local/pna/generate_reports/main.nf deleted file mode 100644 index 7b6306bd..00000000 --- a/subworkflows/local/pna/generate_reports/main.nf +++ /dev/null @@ -1,95 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main' - -/* -======================================================================================== - SUBWORKFLOW TO GENERATE PIXELATOR REPORTS -======================================================================================== -*/ - -workflow PNA_GENERATE_REPORTS { - take: - samplesheet // channel: [path(samplesheet)] - panel_files // channel: [meta, path(panel_file) | []] - amplicon_data // channel: [meta, [path, ...]] - demux_data // channel: [meta, [path, ...]] - collapse_data // channel: [meta, [path, ...]] - graph_data // channel: [meta, [path, ...]] - denoise_data // channel: [meta, [path, ...]] - analysis_data // channel: [meta, [path, ...]] - layout_data // channel: [meta, [path, ...]] - - skip_experiment_summary // boolean - - main: - ch_meta_col = panel_files - .map { meta, _data -> [meta.id, meta] } - .groupTuple() - .map { id, data -> - if (data instanceof List) { - def newMeta = [:] - data.each { newMeta += it } - return [id, newMeta] - } - return [id, data] - } - - ch_report_data = ch_meta_col - .join( panel_files.map { meta, data -> [ meta.id, data ] } ) - .join( amplicon_data.map { meta, data -> [ meta.id, data ] } ) - .join( demux_data.map { meta, data -> [ meta.id, data ] } ) - .join( collapse_data.map { meta, data -> [ meta.id, data ] } ) - .join( graph_data.map { meta, data -> [ meta.id, data ] } ) - .join( denoise_data.map { meta, data -> [ meta.id, data ] } ) - .join( analysis_data.map { meta, data -> [ meta.id, data ] } ) - .join( layout_data.map { meta, data -> [ meta.id, data ] } ) - - - - - // Accumulate results across all samples grouped per stage - - def accumulator = [ - meta: [ id: "all-samples", samples: [] ], - amplicon: [], - demux: [], - collapse: [], - graph: [], - denoise: [], - analysis: [], - layout: [] - ] - - ch_grouped_data = ch_report_data.reduce ( accumulator ) { acc, val -> - def (_id, meta, _panels, amplicon, demux, collapse, graph, denoise, analysis, layout) = val - acc.meta.samples += meta.id - acc.amplicon += amplicon - acc.demux += demux - acc.collapse += collapse - acc.graph += graph - acc.denoise += denoise - acc.analysis += analysis - acc.layout += layout - return acc - }.map { acc -> - [ acc.meta, acc.amplicon, acc.demux, acc.collapse, acc.graph, acc.denoise, acc.analysis, acc.layout ] - } - // Filter out the entry if it just contains empty lists, eg when no PNA samples are present - .filter { it -> it[0].samples.size() > 0 } - - if (!skip_experiment_summary) { - EXPERIMENT_SUMMARY ( samplesheet, ch_grouped_data ) - ch_experiment_summary = EXPERIMENT_SUMMARY.out.html - } else { - ch_experiment_summary = ch_grouped_data.map { it -> it[0] }.combine(Channel.of([])) - } - - - emit: - experiment_summary = ch_experiment_summary -} diff --git a/subworkflows/local/pna/main.nf b/subworkflows/local/pna/main.nf deleted file mode 100644 index 06720552..00000000 --- a/subworkflows/local/pna/main.nf +++ /dev/null @@ -1,195 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ -include { softwareVersionsToYAML } from '../../nf-core/utils_nfcore_pipeline' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - CONFIG FILES -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT LOCAL MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { PIXELATOR_PNA_AMPLICON } from '../../../modules/local/pixelator/single-cell-pna/amplicon/main' -include { PIXELATOR_PNA_DEMUX } from '../../../modules/local/pixelator/single-cell-pna/demux/main' -include { PIXELATOR_PNA_COLLAPSE } from '../../../modules/local/pixelator/single-cell-pna/collapse/main' -include { PIXELATOR_PNA_GRAPH } from '../../../modules/local/pixelator/single-cell-pna/graph/main' -include { PIXELATOR_PNA_DENOISE } from '../../../modules/local/pixelator/single-cell-pna/denoise/main' -include { PIXELATOR_PNA_ANALYSIS } from '../../../modules/local/pixelator/single-cell-pna/analysis/main' -include { PIXELATOR_PNA_COMBINE_COLLAPSE } from '../../../modules/local/pixelator/single-cell-pna/combine_collapse/main' -include { PIXELATOR_PNA_LAYOUT } from '../../../modules/local/pixelator/single-cell-pna/layout/main' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT LOCAL SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { PNA_GENERATE_REPORTS } from '../pna/generate_reports' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT NF-CORE MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* -======================================================================================== - IMPORT CUSTOM MODULES/SUBWORKFLOWS -======================================================================================== -*/ - -// - - -workflow PNA { - take: - fastq // channel: [ meta, [path(sample_1.fq), path(sample_2.fq)] ] - panel_files // channel: [ meta, path(panel_file) | ] - - main: - // - // MODULE: Run pixelator single-cell-pna amplicon - // - PIXELATOR_PNA_AMPLICON ( fastq ) - ch_amplicon = PIXELATOR_PNA_AMPLICON.out.amplicon - - // - // MODULE: Run pixelator single-cell demux - // - ch_demux_input = ch_amplicon - .join(panel_files) - .map { meta, fq, panel_file -> [meta, fq, panel_file, meta.panel, meta.design] } - - - PIXELATOR_PNA_DEMUX(ch_demux_input) - ch_demuxed = PIXELATOR_PNA_DEMUX.out.demuxed - - // - // MODULE: Run pixelator single-cell collapse - // - ch_collapse_input = ch_demuxed - .join(panel_files) - .map { meta, parquet, panel_file -> - // Inject the number of parts into the meta data - // to be able to group the files without waiting later - def newMeta = meta.clone() - newMeta['parts'] = parquet.size() - parquet.collect { single_parquet_file -> - [newMeta, single_parquet_file, panel_file, panel_file ? null : meta.panel, meta.design] - } - } - .flatMap() - - - PIXELATOR_PNA_COLLAPSE(ch_collapse_input) - ch_collapsed = PIXELATOR_PNA_COLLAPSE.out.collapsed - ch_collapsed_reports = PIXELATOR_PNA_COLLAPSE.out.report_json - - // Collect the partitioned collapse.parquet files in a list per sample - // use the dynamic size information from `meta.parts` to group the files - ch_collapse_collected = ch_collapsed - .join(ch_collapsed_reports) - .map { meta, collapsed, reports -> tuple(groupKey(meta.id, meta.parts), [meta, collapsed, reports]) } - .groupTuple() - .map { _key, data -> - // Remove the parts meta key again - def newMeta = data[0][0].clone() - newMeta.remove('parts') - - // Strip the duplicates meta from each element - def parquet = data.collect { it[1] }.flatten() - def reports = data.collect { it[2] }.flatten() - [newMeta, parquet, reports] - } - - ch_collapse_combine_split = ch_collapse_collected.branch { - single: it[1].size() == 1 - multi: it[1].size() > 1 - } - - - PIXELATOR_PNA_COMBINE_COLLAPSE(ch_collapse_combine_split.multi) - - ch_combined_collapsed = ch_collapse_combine_split.single - .map { meta, parquet, _reports -> [meta, parquet] } - .mix(PIXELATOR_PNA_COMBINE_COLLAPSE.out.parquet) - - // - // MODULE: Run pixelator single-cell graph - // - ch_graph_input = ch_combined_collapsed - .join(panel_files) - .map { meta, parquet, panel_file -> [meta, parquet, panel_file, panel_file ? null : meta.panel] } - - PIXELATOR_PNA_GRAPH(ch_graph_input) - ch_graph = PIXELATOR_PNA_GRAPH.out.pixelfile - - // - // MODULE: Run pixelator single-cell denoise - // - PIXELATOR_PNA_DENOISE ( ch_graph ) - ch_denoise = PIXELATOR_PNA_DENOISE.out.pixelfile - - // - // MODULE: Run pixelator single-cell analysis - // - ch_analysis_input = params.skip_denoise ? ch_graph : ch_denoise - PIXELATOR_PNA_ANALYSIS(ch_analysis_input) - ch_analysis = PIXELATOR_PNA_ANALYSIS.out.pixelfile - - // - // MODULE: Run pixelator single-cell layout - // - - PIXELATOR_PNA_LAYOUT(ch_analysis) - - // Prepare all data needed by reporting for each pixelator step - - ch_amplicon_data = PIXELATOR_PNA_AMPLICON.out.report_json - .concat(PIXELATOR_PNA_AMPLICON.out.metadata_json) - .groupTuple(size: 2) - - ch_demux_data = PIXELATOR_PNA_DEMUX.out.report_json - .concat(PIXELATOR_PNA_DEMUX.out.metadata_json) - .groupTuple(size: 2) - - ch_collapse_data = PIXELATOR_PNA_COMBINE_COLLAPSE.out.report_json - .concat(PIXELATOR_PNA_COMBINE_COLLAPSE.out.metadata_json) - .groupTuple(size: 2) - - ch_cluster_data = PIXELATOR_PNA_GRAPH.out.all_results - ch_denoise_data = PIXELATOR_PNA_DENOISE.out.all_results - ch_analysis_data = PIXELATOR_PNA_ANALYSIS.out.all_results - - ch_layout_data = PIXELATOR_PNA_LAYOUT.out.report_json - .concat(PIXELATOR_PNA_LAYOUT.out.metadata_json) - .groupTuple(size: 2) - - - ch_input = Channel.fromPath(params.input) - - PNA_GENERATE_REPORTS( - ch_input, - panel_files, - ch_amplicon_data, - ch_demux_data, - ch_collapse_data, - ch_cluster_data, - ch_denoise_data, - ch_analysis_data, - ch_layout_data, - params.skip_experiment_summary - ) - - emit: - graph = ch_graph - analysis = ch_analysis -} diff --git a/subworkflows/local/pna/nextflow.config b/subworkflows/local/pna/nextflow.config deleted file mode 100644 index 5809a048..00000000 --- a/subworkflows/local/pna/nextflow.config +++ /dev/null @@ -1,3 +0,0 @@ -params { - pna_demux_output_chunk_reads = "30K" -} diff --git a/subworkflows/local/pna/tests/main.nf.test.snap b/subworkflows/local/pna/tests/main.nf.test.snap deleted file mode 100644 index 98207d42..00000000 --- a/subworkflows/local/pna/tests/main.nf.test.snap +++ /dev/null @@ -1,77 +0,0 @@ -{ - "Default parameters [design: pna-2, panel: proxiome-immuno-155-v2]": { - "content": [ - 21, - [ - "pixelator", - "pixelator/PNA055_Sample07_filtered_S7.layout.pxl", - "pixelator/amplicon", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.report.json", - "pixelator/analysis", - "pixelator/analysis/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_filtered_S7.report.json", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_001.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_002.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_002.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_003.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_003.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_004.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_004.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_005.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_005.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_006.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_006.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_001.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_002.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_002.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_003.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_003.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_004.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_004.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_005.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_005.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_006.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_006.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.report.json", - "pixelator/demux", - "pixelator/demux/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_filtered_S7.report.json", - "pixelator/denoise", - "pixelator/denoise/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_filtered_S7.report.json", - "pixelator/graph", - "pixelator/graph/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_filtered_S7.report.json", - "pixelator/layout", - "pixelator/layout/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_filtered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-amplicon.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-analysis.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-demux.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-denoise.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-graph.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-layout.log" - ], - null - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2025-12-04T12:48:00.492394412" - } -} \ No newline at end of file diff --git a/subworkflows/local/pna/tests/tags.yml b/subworkflows/local/pna/tests/tags.yml deleted file mode 100644 index 0c395141..00000000 --- a/subworkflows/local/pna/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -pixelator/pna: - - subworkflows/local/pna/** diff --git a/subworkflows/local/pna/v1/main.nf b/subworkflows/local/pna/v1/main.nf new file mode 100644 index 00000000..81eccb60 --- /dev/null +++ b/subworkflows/local/pna/v1/main.nf @@ -0,0 +1,222 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CONFIG FILES +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { PIXELATOR_AMPLICON } from '../../../../modules/local/pixelator/amplicon/main' +include { PIXELATOR_DEMUX } from '../../../../modules/local/pixelator/demux/main' +include { PIXELATOR_COLLAPSE } from '../../../../modules/local/pixelator/collapse/main' +include { PIXELATOR_GRAPH } from '../../../../modules/local/pixelator/graph/main' +include { PIXELATOR_DENOISE } from '../../../../modules/local/pixelator/denoise/main' +include { PIXELATOR_ANALYSIS } from '../../../../modules/local/pixelator/analysis/main' +include { PIXELATOR_COMBINE_COLLAPSE } from '../../../../modules/local/pixelator/combine_collapse/main' +include { PIXELATOR_LAYOUT } from '../../../../modules/local/pixelator/layout/main' +include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT NF-CORE MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { CAT_FASTQ } from '../../../../modules/nf-core/cat/fastq/main' + +/* +======================================================================================== + IMPORT CUSTOM MODULES/SUBWORKFLOWS +======================================================================================== +*/ + +// + + +workflow PIXELATOR_PNA_V1 { + take: + ch_fastq // channel: [ meta, [path(sample_1.fq), path(sample_2.fq)] ] + ch_panel_files // channel: [ meta, path(panel_file) | ] + + main: + + ch_fastq_split = ch_fastq + .groupTuple() + .branch { + meta, fastq -> + single: fastq.size() == 1 + return [ meta, fastq.flatten() ] + multiple: fastq.size() > 1 + return [ meta, fastq.flatten() ] + } + + // + // MODULE: Concatenate FastQ files from the same sample if required + // + ch_fastq_split.multiple + + ch_cat_fastq = CAT_FASTQ ( ch_fastq_split.multiple ) + .reads + .mix(ch_fastq_split.single) + + // Check that multi lane samples use the same panel file + ch_checked_panel_files = ch_panel_files + .map { meta, data -> [ meta.id, data] } + .groupTuple() + .map { id, data -> + if (!data) { + return [id, []] + } + def unique_panels = data.unique() + if (unique_panels.size() > 1) { + exit 1, "ERROR: Concatenated samples must use the same panel." + } + return [ id, unique_panels[0] ] + } + + ch_cat_panel_files = ch_cat_fastq + .map { meta, _fastqs -> [meta.id, meta] } + .join(ch_checked_panel_files) + .map { _id, meta, panel_files -> [meta, panel_files] } + + // + // MODULE: Run pixelator single-cell-pna amplicon + // + PIXELATOR_AMPLICON ( ch_cat_fastq ) + ch_amplicon = PIXELATOR_AMPLICON.out.amplicon + + // + // MODULE: Run pixelator single-cell demux + // + ch_demux_input = ch_amplicon + .join(ch_panel_files) + .map { meta, fq, panel_file -> [meta, fq, panel_file, meta.panel, meta.design] } + + + PIXELATOR_DEMUX(ch_demux_input) + ch_demuxed = PIXELATOR_DEMUX.out.demuxed + + // + // MODULE: Run pixelator single-cell collapse + // + ch_collapse_input = ch_demuxed + .join(ch_panel_files) + .map { meta, parquet, panel_file -> + // Inject the number of parts into the meta data + // to be able to group the files without waiting later + def newMeta = meta.clone() + newMeta['parts'] = parquet.size() + parquet.collect { single_parquet_file -> + [newMeta, single_parquet_file, panel_file, panel_file ? null : meta.panel, meta.design] + } + } + .flatMap() + + + PIXELATOR_COLLAPSE(ch_collapse_input) + ch_collapsed = PIXELATOR_COLLAPSE.out.collapsed + ch_collapsed_reports = PIXELATOR_COLLAPSE.out.report_json + + // Collect the partitioned collapse.parquet files in a list per sample + // use the dynamic size information from `meta.parts` to group the files + ch_collapse_collected = ch_collapsed + .join(ch_collapsed_reports) + .map { meta, collapsed, reports -> tuple(groupKey(meta.id, meta.parts), [meta, collapsed, reports]) } + .groupTuple() + .map { _key, data -> + // Remove the parts meta key again + def newMeta = data[0][0].clone() + newMeta.remove('parts') + + // Strip the duplicates meta from each element + def parquet = data.collect { _meta, collapsed, _reports -> collapsed }.flatten() + def reports = data.collect { _meta, _collapsed, reports -> reports }.flatten() + [newMeta, parquet, reports] + } + + ch_collapse_combine_split = ch_collapse_collected.branch { + _meta, parquet, _reports -> + single: parquet.size() == 1 + multi: parquet.size() > 1 + } + + + PIXELATOR_COMBINE_COLLAPSE(ch_collapse_combine_split.multi) + + ch_combined_collapsed = ch_collapse_combine_split.single + .map { meta, parquet, _reports -> [meta, parquet] } + .mix(PIXELATOR_COMBINE_COLLAPSE.out.parquet) + + // + // MODULE: Run pixelator single-cell graph + // + ch_graph_input = ch_combined_collapsed + .join(ch_panel_files) + .map { meta, parquet, panel_file -> [meta, parquet, panel_file, panel_file ? null : meta.panel] } + + PIXELATOR_GRAPH(ch_graph_input) + ch_graph = PIXELATOR_GRAPH.out.pixelfile + + // + // MODULE: Run pixelator single-cell denoise + // + PIXELATOR_DENOISE ( ch_graph ) + ch_denoise = PIXELATOR_DENOISE.out.pixelfile + + // + // MODULE: Run pixelator single-cell analysis + // + ch_analysis_input = params.skip_denoise ? ch_graph : ch_denoise + PIXELATOR_ANALYSIS(ch_analysis_input) + ch_analysis = PIXELATOR_ANALYSIS.out.pixelfile + + // + // MODULE: Run pixelator single-cell layout + // + + PIXELATOR_LAYOUT(ch_analysis) + + // Prepare all data needed by reporting for each pixelator step + ch_input = channel.fromPath(params.input) + ch_experiment_summary_input = channel + .topic('all_results_for_reports') + .map { stage, files -> + def values = files instanceof List ? files : [files] + values.collect { f -> tuple(stage, f) } + } + .flatMap { it } + .collect(flat: false) + .map { stageFilePairs -> + def meta = [id: 'all'] + def stages = stageFilePairs.collect { it[0] } + def files = stageFilePairs.collect { it[1] } + tuple(meta, stages, files) + } + + if (!params.skip_experiment_summary) { + EXPERIMENT_SUMMARY( + ch_input, + ch_experiment_summary_input, + ) + } + + emit: + graph = ch_graph + analysis = ch_analysis +} diff --git a/subworkflows/local/pna/v1/meta.yml b/subworkflows/local/pna/v1/meta.yml new file mode 100644 index 00000000..b0cbc6e1 --- /dev/null +++ b/subworkflows/local/pna/v1/meta.yml @@ -0,0 +1,54 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: pixelator_pna_v1 +description: Run the Pixelator single-cell PNA proxiome v1 workflow from FASTQ input through graph and analysis outputs. +keywords: + - pixelator + - pna + - single-cell + - fastq +components: + - cat/fastq + - pixelator/amplicon + - pixelator/demux + - pixelator/collapse + - pixelator/combine/collapse + - pixelator/graph + - pixelator/denoise + - pixelator/analysis + - pixelator/layout + - experiment/summary + - pna_generate_reports +input: + - fastq: + type: file + description: | + Input channel containing sample metadata and one or more FASTQ files. + Structure: [ val(meta), path(reads) ] + pattern: "*.{fq,fastq,fq.gz,fastq.gz,fq.zst,fastq.zst}" + - panel_files: + type: file + description: | + Input channel containing sample metadata and optional panel definition files. + Structure: [ val(meta), path(panel_file) ] + pattern: "*" +output: + - graph: + type: file + description: | + Channel containing graph-stage pixel files. + Structure: [ val(meta), path("*.pxl") ] + pattern: "*.pxl" + - analysis: + type: file + description: | + Channel containing analysis-stage pixel files. + Structure: [ val(meta), path("*.pxl") ] + pattern: "*.pxl" +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/subworkflows/local/pna/tests/main.nf.test b/subworkflows/local/pna/v1/tests/main.nf.test similarity index 64% rename from subworkflows/local/pna/tests/main.nf.test rename to subworkflows/local/pna/v1/tests/main.nf.test index 3b2a5f68..660477a1 100644 --- a/subworkflows/local/pna/tests/main.nf.test +++ b/subworkflows/local/pna/v1/tests/main.nf.test @@ -1,31 +1,32 @@ nextflow_workflow { - name "Test Workflow PNA" + name "Test Workflow PIXELATOR_PNA_V1" script "../main.nf" - config "../nextflow.config" - workflow "PNA" + workflow "PIXELATOR_PNA_V1" + profile "test_proxiome_v1" + tag "subworkflows" tag "subworkflows_pixelator" tag "pixelator" tag "pixelator/pna" - test("Default parameters [design: pna-2, panel: proxiome-immuno-155-v2]") { + test("Default parameters [design: proxiome-v1, panel: proxiome-v1-immuno-155-v1.1]") { when { params { - pna_graph_component_size_min_threshold = 100 skip_experiment_summary = true outdir = "$outputDir" + pna_demux_output_chunk_reads = "30K" } workflow { """ - def meta = [ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155-v2', technology:'pna' ] + def meta = [ id:'sample1', design:'proxiome-v1', panel:'proxiome-v1-immuno-155-v1.1', technology:'proxiome-v1' ] input[0] = Channel.of([ meta, [ - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R1_001.fastq.gz', checkIfExists: true), - file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/PNA055_Sample07_filtered_S7_R2_001.fastq.gz', checkIfExists: true) + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/sample1_R1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/sample1_R2.fastq.gz', checkIfExists: true) ] ]) input[1] = Channel.of([meta, []]) @@ -42,7 +43,6 @@ nextflow_workflow { workflow.trace.succeeded().size(), // All stable path name, with a relative path stable_name, - removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_mqc_versions.yml"), ).match() } ) } diff --git a/subworkflows/local/pna/v1/tests/main.nf.test.snap b/subworkflows/local/pna/v1/tests/main.nf.test.snap new file mode 100644 index 00000000..8078d9d0 --- /dev/null +++ b/subworkflows/local/pna/v1/tests/main.nf.test.snap @@ -0,0 +1,102 @@ +{ + "Default parameters [design: proxiome-v1, panel: proxiome-v1-immuno-155-v1.1]": { + "content": [ + 19, + [ + "pipeline_info", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/sample1.amplicon.fq.zst", + "pixelator/amplicon/sample1.meta.json", + "pixelator/amplicon/sample1.report.json", + "pixelator/analysis", + "pixelator/analysis/sample1.analysis.pxl", + "pixelator/analysis/sample1.meta.json", + "pixelator/analysis/sample1.report.json", + "pixelator/collapse", + "pixelator/collapse/sample1.collapse.m1.part_000.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_000.parquet", + "pixelator/collapse/sample1.collapse.m1.part_000.report.json", + "pixelator/collapse/sample1.collapse.m1.part_001.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_001.parquet", + "pixelator/collapse/sample1.collapse.m1.part_001.report.json", + "pixelator/collapse/sample1.collapse.m1.part_002.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_002.parquet", + "pixelator/collapse/sample1.collapse.m1.part_002.report.json", + "pixelator/collapse/sample1.collapse.m1.part_003.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_003.parquet", + "pixelator/collapse/sample1.collapse.m1.part_003.report.json", + "pixelator/collapse/sample1.collapse.m1.part_004.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_004.parquet", + "pixelator/collapse/sample1.collapse.m1.part_004.report.json", + "pixelator/collapse/sample1.collapse.m1.part_005.meta.json", + "pixelator/collapse/sample1.collapse.m1.part_005.parquet", + "pixelator/collapse/sample1.collapse.m1.part_005.report.json", + "pixelator/collapse/sample1.collapse.m2.part_000.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_000.parquet", + "pixelator/collapse/sample1.collapse.m2.part_000.report.json", + "pixelator/collapse/sample1.collapse.m2.part_001.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_001.parquet", + "pixelator/collapse/sample1.collapse.m2.part_001.report.json", + "pixelator/collapse/sample1.collapse.m2.part_002.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_002.parquet", + "pixelator/collapse/sample1.collapse.m2.part_002.report.json", + "pixelator/collapse/sample1.collapse.m2.part_003.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_003.parquet", + "pixelator/collapse/sample1.collapse.m2.part_003.report.json", + "pixelator/collapse/sample1.collapse.m2.part_004.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_004.parquet", + "pixelator/collapse/sample1.collapse.m2.part_004.report.json", + "pixelator/collapse/sample1.collapse.m2.part_005.meta.json", + "pixelator/collapse/sample1.collapse.m2.part_005.parquet", + "pixelator/collapse/sample1.collapse.m2.part_005.report.json", + "pixelator/collapse/sample1.collapse.parquet", + "pixelator/collapse/sample1.meta.json", + "pixelator/collapse/sample1.report.json", + "pixelator/demux", + "pixelator/demux/sample1.demux.failed.fq.zst", + "pixelator/demux/sample1.demux.m1.part_000.parquet", + "pixelator/demux/sample1.demux.m1.part_001.parquet", + "pixelator/demux/sample1.demux.m1.part_002.parquet", + "pixelator/demux/sample1.demux.m1.part_003.parquet", + "pixelator/demux/sample1.demux.m1.part_004.parquet", + "pixelator/demux/sample1.demux.m1.part_005.parquet", + "pixelator/demux/sample1.demux.m2.part_000.parquet", + "pixelator/demux/sample1.demux.m2.part_001.parquet", + "pixelator/demux/sample1.demux.m2.part_002.parquet", + "pixelator/demux/sample1.demux.m2.part_003.parquet", + "pixelator/demux/sample1.demux.m2.part_004.parquet", + "pixelator/demux/sample1.demux.m2.part_005.parquet", + "pixelator/demux/sample1.demux.passed.fq.zst", + "pixelator/demux/sample1.meta.json", + "pixelator/demux/sample1.report.json", + "pixelator/denoise", + "pixelator/denoise/sample1.denoised_graph.pxl", + "pixelator/denoise/sample1.meta.json", + "pixelator/denoise/sample1.report.json", + "pixelator/graph", + "pixelator/graph/sample1.graph.pxl", + "pixelator/graph/sample1.meta.json", + "pixelator/graph/sample1.report.json", + "pixelator/layout", + "pixelator/layout/sample1.layout.pxl", + "pixelator/layout/sample1.meta.json", + "pixelator/layout/sample1.report.json", + "pixelator/logs", + "pixelator/logs/sample1.pixelator-amplicon.log", + "pixelator/logs/sample1.pixelator-analysis.log", + "pixelator/logs/sample1.pixelator-collapse.log", + "pixelator/logs/sample1.pixelator-combine-collapse.log", + "pixelator/logs/sample1.pixelator-demux.log", + "pixelator/logs/sample1.pixelator-denoise.log", + "pixelator/logs/sample1.pixelator-graph.log", + "pixelator/logs/sample1.pixelator-layout.log" + ] + ], + "timestamp": "2026-05-21T13:27:10.984127921", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/pna/v2/main.nf b/subworkflows/local/pna/v2/main.nf new file mode 100644 index 00000000..4a38203e --- /dev/null +++ b/subworkflows/local/pna/v2/main.nf @@ -0,0 +1,269 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CONFIG FILES +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { PIXELATOR_AMPLICON } from '../../../../modules/local/pixelator/amplicon' +include { PIXELATOR_DEMUX } from '../../../../modules/local/pixelator/demux' +include { PIXELATOR_COLLAPSE } from '../../../../modules/local/pixelator/collapse' +include { PIXELATOR_GRAPH } from '../../../../modules/local/pixelator/graph' +include { PIXELATOR_SAMPLE_CALLING } from '../../../../modules/local/pixelator/sample_calling' +include { PIXELATOR_DENOISE } from '../../../../modules/local/pixelator/denoise' +include { PIXELATOR_ANALYSIS } from '../../../../modules/local/pixelator/analysis' +include { PIXELATOR_COMBINE_COLLAPSE } from '../../../../modules/local/pixelator/combine_collapse' +include { PIXELATOR_LAYOUT } from '../../../../modules/local/pixelator/layout' + + +include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main' +include { CAT_FASTQ } from '../../../../modules/nf-core/cat/fastq/main' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT NF-CORE MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +/* +======================================================================================== + IMPORT CUSTOM MODULES/SUBWORKFLOWS +======================================================================================== +*/ + +// + + +workflow PIXELATOR_PNA_V2 { + take: + ch_fastq // channel: [ meta, [path(sample_1.fq), path(sample_2.fq)] ] + ch_panel_files // channel: [ meta, path(panel_file) | ] + + main: + ch_versions = Channel.empty() + + + ch_fastq_grouped_by_pool = ch_fastq + .map { meta, fq -> tuple(meta.pool, [meta, fq]) } + .groupTuple() + .map { _pool, list -> + def meta = list[0][0].clone() + meta.id = meta.pool + def fq = (list as List).collect { item -> item[1] } + [meta, fq.unique()] + } + + ch_fastq_split = ch_fastq_grouped_by_pool + .branch { + meta, fastq -> + single: fastq.size() == 1 + return [ meta, fastq.flatten() ] + multiple: fastq.size() > 1 + return [ meta, fastq.flatten() ] + } + + // + // MODULE: Concatenate FastQ files from the same sample if required + // + + ch_cat_fastq = CAT_FASTQ ( ch_fastq_split.multiple ) + .reads + .mix(ch_fastq_split.single) + + // Remap panel files to use pool as id + ch_panel_files_grouped_by_pool = ch_panel_files + .map { meta, panel_file_path -> tuple(meta.pool, [meta, panel_file_path]) } + .groupTuple() + .map { _pool, list -> + def meta = list[0][0].clone() + meta.id = meta.pool + def panel_file = list[0][1] + [meta, panel_file] + } + + + // Check that multi lane samples use the same panel file + ch_checked_panel_files = ch_panel_files_grouped_by_pool + .map { meta, data -> [ meta.id, data] } + .groupTuple() + .map { id, data -> + if (!data) { + return [id, []] + } + def unique_panels = data.unique() + if (unique_panels.size() > 1) { + exit 1, "ERROR: Concatenated samples must use the same panel." + } + return [ id, unique_panels[0] ] + } + + ch_cat_panel_files = ch_cat_fastq + .map { meta, _fastq -> [meta.id, meta] } + .join(ch_checked_panel_files) + .map { id, meta, panel_files -> [meta, panel_files] } + + // + // MODULE: Run pixelator single-cell-pna amplicon + // + PIXELATOR_AMPLICON ( ch_cat_fastq ) + ch_amplicon = PIXELATOR_AMPLICON.out.amplicon + + // + // MODULE: Run pixelator single-cell demux + // + ch_demux_input = ch_amplicon + .join(ch_panel_files_grouped_by_pool) + .map { meta, fq, panel_file -> [meta, fq, panel_file, meta.panel, meta.design] } + + + PIXELATOR_DEMUX(ch_demux_input) + ch_demuxed = PIXELATOR_DEMUX.out.demuxed + + // + // MODULE: Run pixelator single-cell collapse + // + ch_collapse_input = ch_demuxed + .join(ch_panel_files_grouped_by_pool) + .map { meta, parquet, panel_file -> + // Inject the number of parts into the meta data + // to be able to group the files without waiting later + def newMeta = meta.clone() + newMeta['parts'] = parquet.size() + parquet.collect { single_parquet_file -> + [newMeta, single_parquet_file, panel_file, panel_file ? null : meta.panel, meta.design] + } + } + .flatMap() + + + PIXELATOR_COLLAPSE(ch_collapse_input) + ch_collapsed = PIXELATOR_COLLAPSE.out.collapsed + ch_collapsed_reports = PIXELATOR_COLLAPSE.out.report_json + + // Collect the partitioned collapse.parquet files in a list per sample + // use the dynamic size information from `meta.parts` to group the files + ch_collapse_collected = ch_collapsed + .join(ch_collapsed_reports) + .map { meta, collapsed, reports -> tuple(groupKey(meta.id, meta.parts), [meta, collapsed, reports]) } + .groupTuple() + .map { _key, data -> + // Remove the parts meta key again + def newMeta = data[0][0].clone() + newMeta.remove('parts') + + // Strip the duplicates meta from each element + def parquet = data.collect { it[1] }.flatten() + def reports = data.collect { it[2] }.flatten() + [newMeta, parquet, reports] + } + + ch_collapse_combine_split = ch_collapse_collected.branch { + single: it[1].size() == 1 + multi: it[1].size() > 1 + } + + + PIXELATOR_COMBINE_COLLAPSE(ch_collapse_combine_split.multi) + + ch_combined_collapsed = ch_collapse_combine_split.single + .map { meta, parquet, _reports -> [meta, parquet] } + .mix(PIXELATOR_COMBINE_COLLAPSE.out.parquet) + + // + // MODULE: Run pixelator single-cell graph + // + ch_graph_input = ch_combined_collapsed + .join(ch_panel_files_grouped_by_pool) + .map { meta, parquet, panel_file -> [meta, parquet, panel_file, panel_file ? null : meta.panel] } + + PIXELATOR_GRAPH(ch_graph_input) + ch_graph = PIXELATOR_GRAPH.out.pixelfile + + // + // MODULE: Run pixelator single-cell sample-calling + // + ch_sample_calling_input = ch_graph + .map { meta, parquet -> [meta, parquet, file(params.input)] } + + PIXELATOR_SAMPLE_CALLING (ch_sample_calling_input) + ch_sample_called = PIXELATOR_SAMPLE_CALLING.out.pixelfile + + // Extract the sample names from the pixel file names so that we can + // merge them in with the panel file names correctly + // Also filter out the undetermined samples here + ch_sample_called = ch_sample_called + .flatMap { meta, pxl_files -> + def files = pxl_files instanceof List ? pxl_files : [pxl_files] + files.findAll { file -> !file.getName().contains('undetermined') } + .collect { + file -> + def new_meta = meta.clone() + new_meta.id = file.getName().replace('.dehashed.pxl', '') + [new_meta, file] + } + } + + // + // MODULE: Run pixelator single-cell denoise + // + PIXELATOR_DENOISE ( ch_sample_called ) + ch_denoise = PIXELATOR_DENOISE.out.pixelfile + + // + // MODULE: Run pixelator single-cell analysis + // + ch_analysis_input = params.skip_denoise ? ch_sample_called : ch_denoise + PIXELATOR_ANALYSIS ( ch_analysis_input ) + ch_analysis = PIXELATOR_ANALYSIS.out.pixelfile + + // + // MODULE: Run pixelator single-cell layout + // + + PIXELATOR_LAYOUT( ch_analysis ) + + // Prepare all data needed by reporting for each pixelator step + ch_input = channel.fromPath(params.input) + ch_experiment_summary_input = channel + .topic('all_results_for_reports') + .map { stage, files -> + def values = files instanceof List ? files : [files] + values.collect { f -> tuple(stage, f) } + } + .flatMap { it } + .collect(flat: false) + .map { stageFilePairs -> + def meta = [id: 'all'] + def stages = stageFilePairs.collect { it[0] } + def files = stageFilePairs.collect { it[1] } + tuple(meta, stages, files) + } + + if (!params.skip_experiment_summary) { + EXPERIMENT_SUMMARY( + ch_input, + ch_experiment_summary_input, + ) + } + + emit: + graph = ch_graph + analysis = ch_analysis +} diff --git a/subworkflows/local/pna/v2/meta.yml b/subworkflows/local/pna/v2/meta.yml new file mode 100644 index 00000000..5b35aa11 --- /dev/null +++ b/subworkflows/local/pna/v2/meta.yml @@ -0,0 +1,55 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: pixelator_pna_v2 +description: Run the Pixelator single-cell PNA proxiome v2 workflow from FASTQ input through graph and analysis outputs. +keywords: + - pixelator + - pna + - single-cell + - fastq +components: + - cat/fastq + - pixelator/amplicon + - pixelator/demux + - pixelator/collapse + - pixelator/combine/collapse + - pixelator/graph + - pixelator/sample/calling + - pixelator/denoise + - pixelator/analysis + - pixelator/layout + - experiment/summary + - pna_generate_reports +input: + - fastq: + type: file + description: | + Input channel containing sample metadata and one or more FASTQ files. + Structure: [ val(meta), path(reads) ] + pattern: "*.{fq,fastq,fq.gz,fastq.gz,fq.zst,fastq.zst}" + - panel_files: + type: file + description: | + Input channel containing sample metadata and optional panel definition files. + Structure: [ val(meta), path(panel_file) ] + pattern: "*" +output: + - graph: + type: file + description: | + Channel containing graph-stage pixel files. + Structure: [ val(meta), path("*.pxl") ] + pattern: "*.pxl" + - analysis: + type: file + description: | + Channel containing analysis-stage pixel files. + Structure: [ val(meta), path("*.pxl") ] + pattern: "*.pxl" +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/subworkflows/local/pna/v2/tests/main.nf.test b/subworkflows/local/pna/v2/tests/main.nf.test new file mode 100644 index 00000000..59df3a91 --- /dev/null +++ b/subworkflows/local/pna/v2/tests/main.nf.test @@ -0,0 +1,50 @@ +nextflow_workflow { + + name "Test Workflow PIXELATOR_PNA_V2" + script "../main.nf" + workflow "PIXELATOR_PNA_V2" + profile "test_proxiome_v2" + + tag "subworkflows" + tag "subworkflows_pixelator" + tag "pixelator" + tag "pixelator/pna" + + test("Default parameters [design: proxiome-v2, panel: proxiome-v2-immuno-155-v1.0]") { + when { + + params { + skip_experiment_summary = true + outdir = "$outputDir" + pna_demux_output_chunk_reads = "30K" + } + + workflow { + """ + def meta = [ pool:'pool1', id:'sample1', design:'proxiome-v2', panel:'proxiome-v2-immuno-155-v1.0', technology:'proxiome-v1' ] + input[0] = Channel.of([ + meta, + [ + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/pna/fastq/pool1_R2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = Channel.of([meta, []]) + """ + } + } + + then { + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // All stable path name, with a relative path + stable_name, + ).match() } + ) + } + } +} diff --git a/subworkflows/local/pna/v2/tests/main.nf.test.snap b/subworkflows/local/pna/v2/tests/main.nf.test.snap new file mode 100644 index 00000000..9ec2f968 --- /dev/null +++ b/subworkflows/local/pna/v2/tests/main.nf.test.snap @@ -0,0 +1,125 @@ +{ + "Default parameters [design: proxiome-v2, panel: proxiome-v2-immuno-155-v1.0]": { + "content": [ + 23, + [ + "pipeline_info", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/pool1.amplicon.fq.zst", + "pixelator/amplicon/pool1.meta.json", + "pixelator/amplicon/pool1.report.json", + "pixelator/analysis", + "pixelator/analysis/sample1.analysis.pxl", + "pixelator/analysis/sample1.meta.json", + "pixelator/analysis/sample1.report.json", + "pixelator/analysis/sample2.analysis.pxl", + "pixelator/analysis/sample2.meta.json", + "pixelator/analysis/sample2.report.json", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.m1.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_000.parquet", + "pixelator/collapse/pool1.collapse.m1.part_000.report.json", + "pixelator/collapse/pool1.collapse.m1.part_001.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_001.parquet", + "pixelator/collapse/pool1.collapse.m1.part_001.report.json", + "pixelator/collapse/pool1.collapse.m1.part_002.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_002.parquet", + "pixelator/collapse/pool1.collapse.m1.part_002.report.json", + "pixelator/collapse/pool1.collapse.m1.part_003.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_003.parquet", + "pixelator/collapse/pool1.collapse.m1.part_003.report.json", + "pixelator/collapse/pool1.collapse.m1.part_004.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_004.parquet", + "pixelator/collapse/pool1.collapse.m1.part_004.report.json", + "pixelator/collapse/pool1.collapse.m1.part_005.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_005.parquet", + "pixelator/collapse/pool1.collapse.m1.part_005.report.json", + "pixelator/collapse/pool1.collapse.m2.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_000.parquet", + "pixelator/collapse/pool1.collapse.m2.part_000.report.json", + "pixelator/collapse/pool1.collapse.m2.part_001.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_001.parquet", + "pixelator/collapse/pool1.collapse.m2.part_001.report.json", + "pixelator/collapse/pool1.collapse.m2.part_002.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_002.parquet", + "pixelator/collapse/pool1.collapse.m2.part_002.report.json", + "pixelator/collapse/pool1.collapse.m2.part_003.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_003.parquet", + "pixelator/collapse/pool1.collapse.m2.part_003.report.json", + "pixelator/collapse/pool1.collapse.m2.part_004.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_004.parquet", + "pixelator/collapse/pool1.collapse.m2.part_004.report.json", + "pixelator/collapse/pool1.collapse.m2.part_005.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_005.parquet", + "pixelator/collapse/pool1.collapse.m2.part_005.report.json", + "pixelator/collapse/pool1.collapse.parquet", + "pixelator/collapse/pool1.meta.json", + "pixelator/collapse/pool1.report.json", + "pixelator/demux", + "pixelator/demux/pool1.demux.failed.fq.zst", + "pixelator/demux/pool1.demux.m1.part_000.parquet", + "pixelator/demux/pool1.demux.m1.part_001.parquet", + "pixelator/demux/pool1.demux.m1.part_002.parquet", + "pixelator/demux/pool1.demux.m1.part_003.parquet", + "pixelator/demux/pool1.demux.m1.part_004.parquet", + "pixelator/demux/pool1.demux.m1.part_005.parquet", + "pixelator/demux/pool1.demux.m2.part_000.parquet", + "pixelator/demux/pool1.demux.m2.part_001.parquet", + "pixelator/demux/pool1.demux.m2.part_002.parquet", + "pixelator/demux/pool1.demux.m2.part_003.parquet", + "pixelator/demux/pool1.demux.m2.part_004.parquet", + "pixelator/demux/pool1.demux.m2.part_005.parquet", + "pixelator/demux/pool1.demux.passed.fq.zst", + "pixelator/demux/pool1.meta.json", + "pixelator/demux/pool1.report.json", + "pixelator/denoise", + "pixelator/denoise/sample1.denoised_graph.pxl", + "pixelator/denoise/sample1.meta.json", + "pixelator/denoise/sample1.report.json", + "pixelator/denoise/sample2.denoised_graph.pxl", + "pixelator/denoise/sample2.meta.json", + "pixelator/denoise/sample2.report.json", + "pixelator/graph", + "pixelator/graph/pool1.graph.pxl", + "pixelator/graph/pool1.meta.json", + "pixelator/graph/pool1.report.json", + "pixelator/layout", + "pixelator/layout/sample1.layout.pxl", + "pixelator/layout/sample1.meta.json", + "pixelator/layout/sample1.report.json", + "pixelator/layout/sample2.layout.pxl", + "pixelator/layout/sample2.meta.json", + "pixelator/layout/sample2.report.json", + "pixelator/logs", + "pixelator/logs/pool1.pixelator-amplicon.log", + "pixelator/logs/pool1.pixelator-collapse.log", + "pixelator/logs/pool1.pixelator-combine-collapse.log", + "pixelator/logs/pool1.pixelator-demux.log", + "pixelator/logs/pool1.pixelator-graph.log", + "pixelator/logs/pool1.pixelator-sample-calling.log", + "pixelator/logs/sample1.pixelator-analysis.log", + "pixelator/logs/sample1.pixelator-denoise.log", + "pixelator/logs/sample1.pixelator-layout.log", + "pixelator/logs/sample2.pixelator-analysis.log", + "pixelator/logs/sample2.pixelator-denoise.log", + "pixelator/logs/sample2.pixelator-layout.log", + "pixelator/sample_calling", + "pixelator/sample_calling/pool1.sample_calling.report.json", + "pixelator/sample_calling/pool1_undetermined.meta.json", + "pixelator/sample_calling/pool1_undetermined.report.json", + "pixelator/sample_calling/sample1.dehashed.pxl", + "pixelator/sample_calling/sample1.meta.json", + "pixelator/sample_calling/sample1.report.json", + "pixelator/sample_calling/sample2.dehashed.pxl", + "pixelator/sample_calling/sample2.meta.json", + "pixelator/sample_calling/sample2.report.json" + ] + ], + "timestamp": "2026-05-21T13:22:23.285610507", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/utils_nfcore_pixelator_pipeline/main.nf b/subworkflows/local/utils_nfcore_pixelator_pipeline/main.nf index 805172af..321e5ccd 100644 --- a/subworkflows/local/utils_nfcore_pixelator_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pixelator_pipeline/main.nf @@ -11,10 +11,8 @@ include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' include { paramsSummaryMap } from 'plugin/nf-schema' include { samplesheetToList } from 'plugin/nf-schema' -include { paramsHelp } from 'plugin/nf-schema' include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { 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' @@ -62,6 +60,9 @@ workflow PIPELINE_INITIALISATION { // // Validate parameters and generate parameter summary to stdout // + + def before_text = "" + def after_text = "" before_text = """ -\033[2m----------------------------------------------------\033[0m- \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m @@ -79,6 +80,10 @@ workflow PIPELINE_INITIALISATION { * Software dependencies https://github.com/nf-core/pixelator/blob/master/CITATIONS.md """ + if (monochrome_logs) { + before_text = before_text.replaceAll(/\033\[[0-9;]*m/, '') + } + command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " UTILS_NFSCHEMA_PLUGIN ( @@ -90,7 +95,8 @@ workflow PIPELINE_INITIALISATION { show_hidden, before_text, after_text, - command + command, + null, ) // @@ -103,7 +109,6 @@ workflow PIPELINE_INITIALISATION { // // Create channel from input file provided through params.input // - ch_versions = channel.empty() // @@ -118,9 +123,9 @@ workflow PIPELINE_INITIALISATION { // Create channel from input file provided through params.input // ch_input = channel - .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) .map { - validate_input_samplesheet(inputBaseDir, it) + row -> validate_input_samplesheet(inputBaseDir, row) } // @@ -131,13 +136,13 @@ workflow PIPELINE_INITIALISATION { // Create a set of valid pixelator options to pass to --design ch_design_options = PIXELATOR_LIST_OPTIONS.out.designs .splitText() - .map { it.trim() } + .map { design_option -> design_option.trim() } .reduce(new HashSet()) { prev, curr -> prev << curr } // Create a set of valid pixelator panel keys to pass using --panel ch_panel_options = PIXELATOR_LIST_OPTIONS.out.panels .splitText() - .map { it.trim() } + .map { panel_option -> panel_option.trim() } .reduce(new HashSet()) { prev, curr -> prev << curr } @@ -149,17 +154,11 @@ workflow PIPELINE_INITIALISATION { .combine(ch_panel_options) .combine(ch_design_options) .map { meta, panel_options, design_options -> - { - meta = validate_panel(meta, panel_options) - meta = validate_design(meta, design_options) - return meta - } + meta = validate_panel(meta, panel_options) + meta = validate_design(meta, design_options) + return meta } .join(ch_input) - .map { meta, panel, reads -> - def newMeta = detect_technology(meta) - return [newMeta, panel, reads] - } emit: samplesheet = ch_samplesheet @@ -179,7 +178,6 @@ workflow PIPELINE_COMPLETION { 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 main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") @@ -201,13 +199,11 @@ workflow PIPELINE_COMPLETION { } 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") + log.error "Pipeline failed. Please refer to troubleshooting docs for common issues: https://nf-co.re/docs/running/troubleshooting" } } @@ -247,7 +243,7 @@ def getGenomeAttribute(attribute) { // Generate methods description for MultiQC // def toolCitationText() { - // TODO nf-core: Optionally add in-text citation tools to this list. + // nf-core: Optionally add in-text citation tools to this list. // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def citation_text = [ @@ -259,7 +255,7 @@ def toolCitationText() { } def toolBibliographyText() { - // TODO nf-core: Optionally add bibliographic entries to this list. + // nf-core: Optionally add bibliographic entries to this list. // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def reference_text = [ @@ -295,7 +291,7 @@ def methodsDescriptionText(mqc_methods_yaml) { meta["tool_citations"] = "" meta["tool_bibliography"] = "" - // TODO nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! + // nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! // meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") // meta["tool_bibliography"] = toolBibliographyText() @@ -324,7 +320,7 @@ def resolve_relative_path(relative_path, URI samplesheet_path) { try { uri = new URI(relative_path) } - catch (URISyntaxException exc) { + catch (URISyntaxException _exc) { return relative_path } @@ -394,7 +390,7 @@ def get_data_basedir(URI samplesheet, String input_basedir) { try { uri = new URI(input_basedir) } - catch (URISyntaxException exc) { + catch (URISyntaxException _exc) { return samplesheet } @@ -458,19 +454,3 @@ def validate_input_samplesheet(URI samplesheetUrl, items) { return [meta, panel_file_abs, reads] } - -// -// Inject a `technology` field into the meta map based on the design -// -def detect_technology(LinkedHashMap meta) { - def newMeta = [:] - if (meta.design.startsWith('pna')) { - newMeta = meta + [technology: 'pna'] - } - else { - error("ERROR: unsupported design: ${meta.design}") - } - // TODO For now keep this around, in order to introduce - // other technology choices later. - return newMeta -} diff --git a/subworkflows/local/utils_nfcore_pixelator_pipeline/meta.yml b/subworkflows/local/utils_nfcore_pixelator_pipeline/meta.yml new file mode 100644 index 00000000..6dadbe56 --- /dev/null +++ b/subworkflows/local/utils_nfcore_pixelator_pipeline/meta.yml @@ -0,0 +1,76 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: pipeline_initialisation +description: Provide nf-core/pixelator-specific pipeline utility subworkflows for initialization and completion hooks. +keywords: + - nf-core + - pixelator + - pipeline + - utilities +components: + - utils_nfschema_plugin + - utils_nfcore_pipeline + - utils_nextflow_pipeline + - pixelator/list/options + - completionemail + - completionsummary +input: + - version: + type: boolean + description: Boolean flag to print version information and exit. + - validate_params: + type: boolean + description: Boolean flag to validate runtime parameters against schema. + - monochrome_logs: + type: boolean + description: Boolean flag to disable ANSI colors in logging output. + - nextflow_cli_args: + type: list + description: Positional Nextflow CLI arguments. + - outdir: + type: string + description: Output directory where results are written. + - input: + type: string + description: Path to the input samplesheet. + - input_basedir: + type: string + description: Optional base path used for resolving relative input paths. + - help: + type: boolean + description: Boolean flag to display help and exit. + - help_full: + type: boolean + description: Boolean flag to display extended help and exit. + - show_hidden: + type: boolean + description: Boolean flag to include hidden parameters in help. + - email: + type: string + description: Email address for completion notifications. + - email_on_fail: + type: string + description: Email address for notifications on workflow failure. + - plaintext_email: + type: boolean + description: Boolean flag to send plain-text completion emails. +output: + - samplesheet: + type: file + description: | + Channel containing validated samplesheet entries and resolved input paths. + Structure: [ val(meta), path(panel_file), path(reads) ] + pattern: "*" + - versions: + type: file + description: | + Channel intended to collect version information generated in initialization. + Structure: [ path(versions.yml) ] + pattern: "versions.yml" +authors: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" +maintainers: + - "@Aratz" + - "@johandahlberg" + - "@fbdtemme" diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index d6e593e8..37939acd 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -73,11 +73,23 @@ def getWorkflowVersion() { 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) + def temp_pf = workflow.launchDir.resolve(".${filename}") + def jsonGenerator = new groovy.json.JsonGenerator.Options() + .excludeNulls() + .addConverter(Path) { Path path -> path.toUriString() } + .addConverter(Duration) { Duration duration -> duration.toMillis() } + .addConverter(MemoryUnit) { MemoryUnit memory -> memory.toBytes() } + .addConverter(nextflow.script.types.VersionNumber) { nextflow.script.types.VersionNumber version -> version.toString() } + .build() + def jsonStr = jsonGenerator.toJson(params) temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - - nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + if (outdir instanceof Path) { + temp_pf.copyTo(outdir.resolve("pipeline_info/${filename}")) + } else if (outdir instanceof String) { + temp_pf.copyTo("${outdir}/pipeline_info/params_${timestamp}.json") + } else { + log.warn("Could not determine type of outdir, parameters JSON file will not be copied to output directory!") + } temp_pf.delete() } 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 index 25f2017f..e3f0baf4 100644 --- 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 @@ -4,10 +4,10 @@ "v9.9.9" ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.8.4", + "nextflow": "23.10.1" }, - "timestamp": "2025-06-26T13:20:08.944676306" + "timestamp": "2024-02-28T12:02:05.308243" }, "Test Function checkCondaChannels": { "content": null, diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 2f30e9a4..afca5439 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -17,7 +17,7 @@ workflow UTILS_NFCORE_PIPELINE { checkProfileProvided(nextflow_cli_args) emit: - valid_config + valid_config = valid_config } /* @@ -353,67 +353,3 @@ def completionSummary(monochrome_logs=true) { log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") } } - -// -// Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack -// -def imNotification(summary_params, hook_url) { - def summary = [:] - summary_params - .keySet() - .sort() - .each { group -> - summary << summary_params[group] - } - - def misc_fields = [:] - misc_fields['start'] = workflow.start - misc_fields['complete'] = workflow.complete - misc_fields['scriptfile'] = workflow.scriptFile - misc_fields['scriptid'] = workflow.scriptId - if (workflow.repository) { - misc_fields['repository'] = workflow.repository - } - if (workflow.commitId) { - misc_fields['commitid'] = workflow.commitId - } - if (workflow.revision) { - misc_fields['revision'] = workflow.revision - } - misc_fields['nxf_version'] = workflow.nextflow.version - misc_fields['nxf_build'] = workflow.nextflow.build - misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp - - def msg_fields = [:] - msg_fields['version'] = getWorkflowVersion() - msg_fields['runName'] = workflow.runName - msg_fields['success'] = workflow.success - msg_fields['dateComplete'] = workflow.complete - msg_fields['duration'] = workflow.duration - msg_fields['exitStatus'] = workflow.exitStatus - msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - msg_fields['errorReport'] = (workflow.errorReport ?: 'None') - msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") - msg_fields['projectDir'] = workflow.projectDir - msg_fields['summary'] = summary << misc_fields - - // Render the JSON template - def engine = new groovy.text.GStringTemplateEngine() - // Different JSON depending on the service provider - // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format - def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" - def hf = new File("${workflow.projectDir}/assets/${json_path}") - def json_template = engine.createTemplate(hf).make(msg_fields) - def json_message = json_template.toString() - - // POST - def post = new URL(hook_url).openConnection() - post.setRequestMethod("POST") - post.setDoOutput(true) - post.setRequestProperty("Content-Type", "application/json") - post.getOutputStream().write(json_message.getBytes("UTF-8")) - def postRC = post.getResponseCode() - if (!postRC.equals(200)) { - log.warn(post.getErrorStream().getText()) - } -} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test new file mode 100644 index 00000000..8940d32d --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.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.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap new file mode 100644 index 00000000..859d1030 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.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_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf index 1df8b76f..0d9d4e0d 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -22,6 +22,7 @@ workflow UTILS_NFSCHEMA_PLUGIN { before_text // string: text to show before the help message and parameters summary after_text // string: text to show after the help message and parameters summary command // string: an example command of the pipeline + cli_typecast // boolean: whether to perform typecasting of CLI parameters. Set this to `null` to use the default behaviour main: @@ -38,7 +39,7 @@ workflow UTILS_NFSCHEMA_PLUGIN { } log.info paramsHelp( help_options, - (params.help instanceof String && params.help != "true") ? params.help : "", + (help instanceof String && help != "true") ? help : "", ) exit 0 } @@ -65,6 +66,9 @@ workflow UTILS_NFSCHEMA_PLUGIN { if(parameters_schema) { validateOptions << [parametersSchema: parameters_schema] } + if(cli_typecast != null) { + validateOptions << [cliTypecast: cli_typecast] + } validateParameters(validateOptions) } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml index f7d9f028..1d8c75a9 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml +++ b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml @@ -25,6 +25,30 @@ input: 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. + - help: + type: boolean, string + description: | + Show the help message and exit. When a parameter name is given, show the help message for that parameter instead of the general help message. + - help_full: + type: boolean + description: Show the full help message and exit. + - show_hidden: + type: boolean + description: Show hidden parameters in the help message. + - before_text: + type: string + description: Text to show before the parameters summary and help message. + - after_text: + type: string + description: Text to show after the parameters summary and help message. + - command: + type: string + description: An example command to run the pipeline, to show in the help message and the summary. + - cli_typecast: + type: boolean + description: | + Whether to apply typecasting to the parameters given via the CLI before validation. + Set this to `null` to use the default behavior. output: - dummy_emit: type: boolean diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test index c977917a..1fd1eac1 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -31,6 +31,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -63,6 +64,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -95,6 +97,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -127,6 +130,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -160,6 +164,7 @@ nextflow_workflow { input[6] = "Before" input[7] = "After" input[8] = "nextflow run test/test" + input[9] = null """ } } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index f6537cc3..fd71cb8f 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -1,5 +1,5 @@ plugins { - id "nf-schema@2.6.1" + id "nf-schema@2.7.2" } validation { diff --git a/tests/nextflow.config b/tests/nextflow.config index db57284a..1e12f8a5 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -4,49 +4,10 @@ ======================================================================================== */ -aws.client.anonymous = true // fixes S3 access issues on self-hosted runners - params { - // Base directory for nf-core/modules test data - modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' - pipelines_testdata_base_path = "https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/" - - // TODO: check if we rather do this or disable publishdir for all processes when testing modules/subworkflows + pipelines_testdata_base_path = System.getenv('NFT_TESTDATA_BASE_PATH') ?: "https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/" + modules_testdata_base_path = "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/" outdir = 'results' } -validation { - ignoreParams = ['modules_testdata_base_path', 'pipelines_testdata_base_path'] -} - -// Impose sensible resource limits for testing -process { - withName: '.*' { - cpus = 2 - memory = 3.GB - time = 2.h - } - - withName: "EXPERIMENT_SUMMARY" { - ext.args = "-P test_mode=\"TRUE\"" - } -} - -// Impose same minimum Nextflow version as the pipeline for testing -manifest { - nextflowVersion = '!>=23.10.4' -} - -// Disable all Nextflow reporting options -timeline { - enabled = false -} -report { - enabled = false -} -trace { - enabled = false -} -dag { - enabled = false -} +aws.client.anonymous = true // fixes S3 access issues on self-hosted runners diff --git a/tests/pna.nf.test.snap b/tests/pna.nf.test.snap deleted file mode 100644 index 50cfce97..00000000 --- a/tests/pna.nf.test.snap +++ /dev/null @@ -1,258 +0,0 @@ -{ - "Params: default - stub": { - "content": [ - 20, - [ - "pipeline_info", - "pipeline_info/nf_core_pixelator_software_mqc_versions.yml", - "pipeline_info/samplesheet_pna.csv", - "pixelator", - "pixelator/PNA055_Sample07_filtered_S7.pxl", - "pixelator/PNA055_Sample07_unfiltered_S7.pxl", - "pixelator/amplicon", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.report.json", - "pixelator/amplicon/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/analysis", - "pixelator/analysis/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_filtered_S7.report.json", - "pixelator/analysis/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.demux.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.demux.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.demux.m2.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.demux.m2.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.demux.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.demux.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.demux.m2.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.demux.m2.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/demux", - "pixelator/demux/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_filtered_S7.report.json", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/denoise", - "pixelator/denoise/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_filtered_S7.report.json", - "pixelator/denoise/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/experiment-summary.html", - "pixelator/graph", - "pixelator/graph/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_filtered_S7.report.json", - "pixelator/graph/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/layout", - "pixelator/layout/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_filtered_S7.report.json", - "pixelator/layout/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.demux.m1.part_000.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.demux.m2.part_000.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-amplicon.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-analysis.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-demux.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-denoise.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-graph.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-layout.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7", - "pixelator/logs/PNA055_Sample07_unfiltered_S7.pixelator-combine-collapse.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.demux.m1.part_000.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.demux.m2.part_000.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-amplicon.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-analysis.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-demux.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-denoise.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-graph.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-layout.log" - ], - { - "EXPERIMENT_SUMMARY": { - "experiment-summary": "0.6.0" - }, - "PIXELATOR_LIST_OPTIONS": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_AMPLICON": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_ANALYSIS": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_COLLAPSE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_COMBINE_COLLAPSE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_DEMUX": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_DENOISE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_GRAPH": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_LAYOUT": { - "pixelator": "0.23.0" - }, - "Workflow": { - "nf-core/pixelator": "v3.0.1" - } - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2026-01-19T08:54:43.966539669" - }, - "Params: all": { - "content": [ - 20, - { - "EXPERIMENT_SUMMARY": { - "experiment-summary": "0.6.0" - }, - "PIXELATOR_LIST_OPTIONS": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_AMPLICON": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_ANALYSIS": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_COLLAPSE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_COMBINE_COLLAPSE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_DEMUX": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_DENOISE": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_GRAPH": { - "pixelator": "0.23.0" - }, - "PIXELATOR_PNA_LAYOUT": { - "pixelator": "0.23.0" - }, - "Workflow": { - "nf-core/pixelator": "v3.0.1" - } - }, - [ - "pipeline_info", - "pipeline_info/nf_core_pixelator_software_mqc_versions.yml", - "pipeline_info/samplesheet_pna.csv", - "pixelator", - "pixelator/PNA055_Sample07_filtered_S7.layout.pxl", - "pixelator/PNA055_Sample07_unfiltered_S7.layout.pxl", - "pixelator/amplicon", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.amplicon.fq.zst", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_filtered_S7.report.json", - "pixelator/amplicon/PNA055_Sample07_unfiltered_S7.amplicon.fq.zst", - "pixelator/amplicon/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/amplicon/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/analysis", - "pixelator/analysis/PNA055_Sample07_filtered_S7.analysis.pxl", - "pixelator/analysis/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_filtered_S7.report.json", - "pixelator/analysis/PNA055_Sample07_unfiltered_S7.analysis.pxl", - "pixelator/analysis/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/analysis/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/collapse", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.m2.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/collapse/PNA055_Sample07_filtered_S7.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m1.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m1.part_000.parquet", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m1.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m2.part_000.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m2.part_000.parquet", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.m2.part_000.report.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.collapse.parquet", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/collapse/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/demux", - "pixelator/demux/PNA055_Sample07_filtered_S7.demux.failed.fq.zst", - "pixelator/demux/PNA055_Sample07_filtered_S7.demux.m1.part_000.parquet", - "pixelator/demux/PNA055_Sample07_filtered_S7.demux.m2.part_000.parquet", - "pixelator/demux/PNA055_Sample07_filtered_S7.demux.passed.fq.zst", - "pixelator/demux/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_filtered_S7.report.json", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.demux.failed.fq.zst", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.demux.m1.part_000.parquet", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.demux.m2.part_000.parquet", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.demux.passed.fq.zst", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/demux/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/denoise", - "pixelator/denoise/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_filtered_S7.report.json", - "pixelator/denoise/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/denoise/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/experiment-summary.html", - "pixelator/graph", - "pixelator/graph/PNA055_Sample07_filtered_S7.graph.pxl", - "pixelator/graph/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_filtered_S7.report.json", - "pixelator/graph/PNA055_Sample07_unfiltered_S7.graph.pxl", - "pixelator/graph/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/graph/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/layout", - "pixelator/layout/PNA055_Sample07_filtered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_filtered_S7.report.json", - "pixelator/layout/PNA055_Sample07_unfiltered_S7.meta.json", - "pixelator/layout/PNA055_Sample07_unfiltered_S7.report.json", - "pixelator/logs", - "pixelator/logs/PNA055_Sample07_filtered_S7", - "pixelator/logs/PNA055_Sample07_filtered_S7.pixelator-combine-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-amplicon.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-analysis.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-demux.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-denoise.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-graph.log", - "pixelator/logs/PNA055_Sample07_filtered_S7/PNA055_Sample07_filtered_S7.pixelator-layout.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7", - "pixelator/logs/PNA055_Sample07_unfiltered_S7.pixelator-combine-collapse.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-amplicon.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-analysis.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-collapse.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-demux.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-denoise.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-graph.log", - "pixelator/logs/PNA055_Sample07_unfiltered_S7/PNA055_Sample07_unfiltered_S7.pixelator-layout.log" - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.2" - }, - "timestamp": "2026-01-19T08:53:47.664150319" - } -} \ No newline at end of file diff --git a/tests/proxiome_v1.nf.test b/tests/proxiome_v1.nf.test new file mode 100644 index 00000000..b119b433 --- /dev/null +++ b/tests/proxiome_v1.nf.test @@ -0,0 +1,68 @@ +nextflow_pipeline { + + name "Test PNA pipeline V1" + script "../main.nf" + profile "test_proxiome_v1" + + tag "pixelator" + tag "pixelator/pna" + + test("Params: all") { + + when { + params { + outdir = "$outputDir" + } + } + + then { + // stable_path: All files + folders in ${params.outdir}/ with a stable name + def stable_path = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_content: All files in ${params.outdir}/ with stable content + def stable_content = getAllFilesFromDir(params.outdir, include: ['**/*.meta.json'], ignore: ['pixelator/collapse/*']) + + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_versions.yml"), + // All stable path name, with a relative path + stable_path, + // All files with stable contents + stable_content, + ).match() } + ) + } + } + + test("Params: default - stub") { + + options "-stub" + + when { + params { + outdir = "$outputDir" + } + } + + then { + def stable_path = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_content: All files in ${params.outdir}/ with stable content + def stable_content = getAllFilesFromDir(params.outdir, include: ['**/*.meta.json'], ignore: ['pixelator/collapse/*']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // All stable path name, with a relative path + stable_path, + // All files with stable contents + stable_content, + removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_versions.yml"), + ).match() } + ) + } + } +} diff --git a/tests/proxiome_v1.nf.test.snap b/tests/proxiome_v1.nf.test.snap new file mode 100644 index 00000000..04cc95e3 --- /dev/null +++ b/tests/proxiome_v1.nf.test.snap @@ -0,0 +1,310 @@ +{ + "Params: default - stub": { + "content": [ + 21, + [ + "pipeline_info", + "pipeline_info/nf_core_pixelator_software_versions.yml", + "pipeline_info/samplesheet_proxiome_v1.csv", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/sample_1.amplicon.fq.zst", + "pixelator/amplicon/sample_1.meta.json", + "pixelator/amplicon/sample_1.report.json", + "pixelator/amplicon/sample_2.amplicon.fq.zst", + "pixelator/amplicon/sample_2.meta.json", + "pixelator/amplicon/sample_2.report.json", + "pixelator/analysis", + "pixelator/analysis/sample_1.meta.json", + "pixelator/analysis/sample_1.pxl", + "pixelator/analysis/sample_1.report.json", + "pixelator/analysis/sample_2.meta.json", + "pixelator/analysis/sample_2.pxl", + "pixelator/analysis/sample_2.report.json", + "pixelator/collapse", + "pixelator/collapse/sample_1.collapse.meta.json", + "pixelator/collapse/sample_1.collapse.parquet", + "pixelator/collapse/sample_1.demux.m1.part_000.meta.json", + "pixelator/collapse/sample_1.demux.m1.part_000.parquet", + "pixelator/collapse/sample_1.demux.m1.part_000.report.json", + "pixelator/collapse/sample_1.demux.m2.part_000.meta.json", + "pixelator/collapse/sample_1.demux.m2.part_000.parquet", + "pixelator/collapse/sample_1.demux.m2.part_000.report.json", + "pixelator/collapse/sample_1.report.json", + "pixelator/collapse/sample_2.collapse.meta.json", + "pixelator/collapse/sample_2.collapse.parquet", + "pixelator/collapse/sample_2.demux.m1.part_000.meta.json", + "pixelator/collapse/sample_2.demux.m1.part_000.parquet", + "pixelator/collapse/sample_2.demux.m1.part_000.report.json", + "pixelator/collapse/sample_2.demux.m2.part_000.meta.json", + "pixelator/collapse/sample_2.demux.m2.part_000.parquet", + "pixelator/collapse/sample_2.demux.m2.part_000.report.json", + "pixelator/collapse/sample_2.report.json", + "pixelator/demux", + "pixelator/demux/sample_1.demux.failed.fq.zst", + "pixelator/demux/sample_1.demux.m1.part_000.parquet", + "pixelator/demux/sample_1.demux.m2.part_000.parquet", + "pixelator/demux/sample_1.demux.passed.fq.zst", + "pixelator/demux/sample_1.meta.json", + "pixelator/demux/sample_1.report.json", + "pixelator/demux/sample_2.demux.failed.fq.zst", + "pixelator/demux/sample_2.demux.m1.part_000.parquet", + "pixelator/demux/sample_2.demux.m2.part_000.parquet", + "pixelator/demux/sample_2.demux.passed.fq.zst", + "pixelator/demux/sample_2.meta.json", + "pixelator/demux/sample_2.report.json", + "pixelator/denoise", + "pixelator/denoise/sample_1.meta.json", + "pixelator/denoise/sample_1.report.json", + "pixelator/denoise/sample_2.meta.json", + "pixelator/denoise/sample_2.report.json", + "pixelator/experiment-summary.html", + "pixelator/graph", + "pixelator/graph/sample_1.meta.json", + "pixelator/graph/sample_1.pxl", + "pixelator/graph/sample_1.report.json", + "pixelator/graph/sample_2.meta.json", + "pixelator/graph/sample_2.pxl", + "pixelator/graph/sample_2.report.json", + "pixelator/layout", + "pixelator/layout/sample_1.meta.json", + "pixelator/layout/sample_1.report.json", + "pixelator/layout/sample_2.meta.json", + "pixelator/layout/sample_2.report.json", + "pixelator/logs", + "pixelator/logs/sample_1", + "pixelator/logs/sample_1.pixelator-combine-collapse.log", + "pixelator/logs/sample_1/sample_1.demux.m1.part_000.pixelator-collapse.log", + "pixelator/logs/sample_1/sample_1.demux.m2.part_000.pixelator-collapse.log", + "pixelator/logs/sample_1/sample_1.pixelator-amplicon.log", + "pixelator/logs/sample_1/sample_1.pixelator-analysis.log", + "pixelator/logs/sample_1/sample_1.pixelator-demux.log", + "pixelator/logs/sample_1/sample_1.pixelator-denoise.log", + "pixelator/logs/sample_1/sample_1.pixelator-graph.log", + "pixelator/logs/sample_1/sample_1.pixelator-layout.log", + "pixelator/logs/sample_2", + "pixelator/logs/sample_2.pixelator-combine-collapse.log", + "pixelator/logs/sample_2/sample_2.demux.m1.part_000.pixelator-collapse.log", + "pixelator/logs/sample_2/sample_2.demux.m2.part_000.pixelator-collapse.log", + "pixelator/logs/sample_2/sample_2.pixelator-amplicon.log", + "pixelator/logs/sample_2/sample_2.pixelator-analysis.log", + "pixelator/logs/sample_2/sample_2.pixelator-demux.log", + "pixelator/logs/sample_2/sample_2.pixelator-denoise.log", + "pixelator/logs/sample_2/sample_2.pixelator-graph.log", + "pixelator/logs/sample_2/sample_2.pixelator-layout.log", + "pixelator/sample_1.pxl", + "pixelator/sample_2.pxl" + ], + [ + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample_2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + { + "CAT_FASTQ": { + "cat": 9.5 + }, + "EXPERIMENT_SUMMARY": { + "experiment-summary": "0.10.1" + }, + "PIXELATOR_AMPLICON": { + "pixelator": "0.26.0" + }, + "PIXELATOR_ANALYSIS": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COMBINE_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DEMUX": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DENOISE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_GRAPH": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LAYOUT": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LIST_OPTIONS": { + "pixelator": "0.26.0" + }, + "Workflow": { + "nf-core/pixelator": "v4.0.0" + } + } + ], + "timestamp": "2026-05-22T14:45:44.906565007", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "Params: all": { + "content": [ + 21, + { + "CAT_FASTQ": { + "cat": 9.5 + }, + "EXPERIMENT_SUMMARY": { + "experiment-summary": "0.10.1" + }, + "PIXELATOR_AMPLICON": { + "pixelator": "0.26.0" + }, + "PIXELATOR_ANALYSIS": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COMBINE_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DEMUX": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DENOISE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_GRAPH": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LAYOUT": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LIST_OPTIONS": { + "pixelator": "0.26.0" + }, + "Workflow": { + "nf-core/pixelator": "v4.0.0" + } + }, + [ + "pipeline_info", + "pipeline_info/nf_core_pixelator_software_versions.yml", + "pipeline_info/samplesheet_proxiome_v1.csv", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/sample_1.amplicon.fq.zst", + "pixelator/amplicon/sample_1.meta.json", + "pixelator/amplicon/sample_1.report.json", + "pixelator/amplicon/sample_2.amplicon.fq.zst", + "pixelator/amplicon/sample_2.meta.json", + "pixelator/amplicon/sample_2.report.json", + "pixelator/analysis", + "pixelator/analysis/sample_1.analysis.pxl", + "pixelator/analysis/sample_1.meta.json", + "pixelator/analysis/sample_1.report.json", + "pixelator/analysis/sample_2.analysis.pxl", + "pixelator/analysis/sample_2.meta.json", + "pixelator/analysis/sample_2.report.json", + "pixelator/collapse", + "pixelator/collapse/sample_1.collapse.m1.part_000.meta.json", + "pixelator/collapse/sample_1.collapse.m1.part_000.parquet", + "pixelator/collapse/sample_1.collapse.m1.part_000.report.json", + "pixelator/collapse/sample_1.collapse.m2.part_000.meta.json", + "pixelator/collapse/sample_1.collapse.m2.part_000.parquet", + "pixelator/collapse/sample_1.collapse.m2.part_000.report.json", + "pixelator/collapse/sample_1.collapse.parquet", + "pixelator/collapse/sample_1.meta.json", + "pixelator/collapse/sample_1.report.json", + "pixelator/collapse/sample_2.collapse.m1.part_000.meta.json", + "pixelator/collapse/sample_2.collapse.m1.part_000.parquet", + "pixelator/collapse/sample_2.collapse.m1.part_000.report.json", + "pixelator/collapse/sample_2.collapse.m2.part_000.meta.json", + "pixelator/collapse/sample_2.collapse.m2.part_000.parquet", + "pixelator/collapse/sample_2.collapse.m2.part_000.report.json", + "pixelator/collapse/sample_2.collapse.parquet", + "pixelator/collapse/sample_2.meta.json", + "pixelator/collapse/sample_2.report.json", + "pixelator/demux", + "pixelator/demux/sample_1.demux.failed.fq.zst", + "pixelator/demux/sample_1.demux.m1.part_000.parquet", + "pixelator/demux/sample_1.demux.m2.part_000.parquet", + "pixelator/demux/sample_1.demux.passed.fq.zst", + "pixelator/demux/sample_1.meta.json", + "pixelator/demux/sample_1.report.json", + "pixelator/demux/sample_2.demux.failed.fq.zst", + "pixelator/demux/sample_2.demux.m1.part_000.parquet", + "pixelator/demux/sample_2.demux.m2.part_000.parquet", + "pixelator/demux/sample_2.demux.passed.fq.zst", + "pixelator/demux/sample_2.meta.json", + "pixelator/demux/sample_2.report.json", + "pixelator/denoise", + "pixelator/denoise/sample_1.meta.json", + "pixelator/denoise/sample_1.report.json", + "pixelator/denoise/sample_2.meta.json", + "pixelator/denoise/sample_2.report.json", + "pixelator/experiment-summary.html", + "pixelator/graph", + "pixelator/graph/sample_1.graph.pxl", + "pixelator/graph/sample_1.meta.json", + "pixelator/graph/sample_1.report.json", + "pixelator/graph/sample_2.graph.pxl", + "pixelator/graph/sample_2.meta.json", + "pixelator/graph/sample_2.report.json", + "pixelator/layout", + "pixelator/layout/sample_1.meta.json", + "pixelator/layout/sample_1.report.json", + "pixelator/layout/sample_2.meta.json", + "pixelator/layout/sample_2.report.json", + "pixelator/logs", + "pixelator/logs/sample_1", + "pixelator/logs/sample_1.pixelator-combine-collapse.log", + "pixelator/logs/sample_1/sample_1.pixelator-amplicon.log", + "pixelator/logs/sample_1/sample_1.pixelator-analysis.log", + "pixelator/logs/sample_1/sample_1.pixelator-collapse.log", + "pixelator/logs/sample_1/sample_1.pixelator-demux.log", + "pixelator/logs/sample_1/sample_1.pixelator-denoise.log", + "pixelator/logs/sample_1/sample_1.pixelator-graph.log", + "pixelator/logs/sample_1/sample_1.pixelator-layout.log", + "pixelator/logs/sample_2", + "pixelator/logs/sample_2.pixelator-combine-collapse.log", + "pixelator/logs/sample_2/sample_2.pixelator-amplicon.log", + "pixelator/logs/sample_2/sample_2.pixelator-analysis.log", + "pixelator/logs/sample_2/sample_2.pixelator-collapse.log", + "pixelator/logs/sample_2/sample_2.pixelator-demux.log", + "pixelator/logs/sample_2/sample_2.pixelator-denoise.log", + "pixelator/logs/sample_2/sample_2.pixelator-graph.log", + "pixelator/logs/sample_2/sample_2.pixelator-layout.log", + "pixelator/sample_1.layout.pxl", + "pixelator/sample_2.layout.pxl" + ], + [ + "sample_1.meta.json:md5,5e252f7062a4b444c53b1bfeb07ba9db", + "sample_2.meta.json:md5,5e252f7062a4b444c53b1bfeb07ba9db", + "sample_1.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "sample_2.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "sample_1.meta.json:md5,6ca7d2d473fee8a3ab667835f4057916", + "sample_2.meta.json:md5,e0b756a91edb80e878baa6862b2c3c6d", + "sample_1.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "sample_2.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "sample_1.meta.json:md5,9499ef2af613d6fa5cba5c91a443c726", + "sample_2.meta.json:md5,d73dc0fcfaaac01957e4611c89ef3dec", + "sample_1.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3", + "sample_2.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3" + ] + ], + "timestamp": "2026-05-22T14:44:59.750008727", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/tests/pna.nf.test b/tests/proxiome_v2.nf.test similarity index 50% rename from tests/pna.nf.test rename to tests/proxiome_v2.nf.test index c1af17cb..7d42fdf6 100644 --- a/tests/pna.nf.test +++ b/tests/proxiome_v2.nf.test @@ -1,7 +1,8 @@ nextflow_pipeline { - name "Test PNA pipeline" + name "Test PNA pipeline V2" script "../main.nf" + profile "test_proxiome_v2" tag "pixelator" tag "pixelator/pna" @@ -11,21 +12,15 @@ nextflow_pipeline { when { params { - pipelines_testdata_base_path = "https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/" - input = "$pipelines_testdata_base_path/samplesheet/pna/samplesheet_pna.csv" - input_basedir = "$pipelines_testdata_base_path/testdata/pna/" - outdir = "$outputDir" - - pna_graph_component_size_min_threshold = 100 - skip_experiment_summary = false - save_all = true - + outdir = "$outputDir" } } 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}']) + // stable_path: All files + folders in ${params.outdir}/ with a stable name + def stable_path = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_content: All files in ${params.outdir}/ with stable content + def stable_content = getAllFilesFromDir(params.outdir, include: ['**/*.meta.json'], ignore: ['pixelator/collapse/*']) assertAll( { assert workflow.success}, @@ -33,9 +28,11 @@ nextflow_pipeline { // Number of successful tasks workflow.trace.succeeded().size(), // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_mqc_versions.yml"), + removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_versions.yml"), // All stable path name, with a relative path - stable_name, + stable_path, + // All files with stable contents + stable_content, ).match() } ) } @@ -47,25 +44,25 @@ nextflow_pipeline { when { params { - pipelines_testdata_base_path = "https://raw.githubusercontent.com/nf-core/test-datasets/pixelator/" - input = "$pipelines_testdata_base_path/samplesheet/pna/samplesheet_pna.csv" - input_basedir = "$pipelines_testdata_base_path/testdata/pna/" - outdir = "$outputDir" - - skip_experiment_summary = false + outdir = "$outputDir" } } then { - def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files + folders in ${params.outdir}/ with a stable name + def stable_path = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_content: All files in ${params.outdir}/ with stable content + def stable_content = getAllFilesFromDir(params.outdir, include: ['**/*.meta.json'], ignore: ['pixelator/collapse/*']) assertAll( { assert workflow.success }, { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), // All stable path name, with a relative path - stable_name, - removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_mqc_versions.yml"), + stable_path, + // All files with stable contents + stable_content, + removeNextflowVersion("$outputDir/pipeline_info/nf_core_pixelator_software_versions.yml"), ).match() } ) } diff --git a/tests/proxiome_v2.nf.test.snap b/tests/proxiome_v2.nf.test.snap new file mode 100644 index 00000000..13270a4a --- /dev/null +++ b/tests/proxiome_v2.nf.test.snap @@ -0,0 +1,414 @@ +{ + "Params: default - stub": { + "content": [ + 41, + [ + "pipeline_info", + "pipeline_info/nf_core_pixelator_software_versions.yml", + "pipeline_info/samplesheet_proxiome_v2.csv", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/pool1.amplicon.fq.zst", + "pixelator/amplicon/pool1.meta.json", + "pixelator/amplicon/pool1.report.json", + "pixelator/amplicon/pool2.amplicon.fq.zst", + "pixelator/amplicon/pool2.meta.json", + "pixelator/amplicon/pool2.report.json", + "pixelator/analysis", + "pixelator/analysis/sample1.meta.json", + "pixelator/analysis/sample1.pxl", + "pixelator/analysis/sample1.report.json", + "pixelator/analysis/sample2.meta.json", + "pixelator/analysis/sample2.pxl", + "pixelator/analysis/sample2.report.json", + "pixelator/analysis/sample3.meta.json", + "pixelator/analysis/sample3.pxl", + "pixelator/analysis/sample3.report.json", + "pixelator/analysis/sample4.meta.json", + "pixelator/analysis/sample4.pxl", + "pixelator/analysis/sample4.report.json", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.meta.json", + "pixelator/collapse/pool1.collapse.parquet", + "pixelator/collapse/pool1.demux.m1.part_000.meta.json", + "pixelator/collapse/pool1.demux.m1.part_000.parquet", + "pixelator/collapse/pool1.demux.m1.part_000.report.json", + "pixelator/collapse/pool1.demux.m2.part_000.meta.json", + "pixelator/collapse/pool1.demux.m2.part_000.parquet", + "pixelator/collapse/pool1.demux.m2.part_000.report.json", + "pixelator/collapse/pool1.report.json", + "pixelator/collapse/pool2.collapse.meta.json", + "pixelator/collapse/pool2.collapse.parquet", + "pixelator/collapse/pool2.demux.m1.part_000.meta.json", + "pixelator/collapse/pool2.demux.m1.part_000.parquet", + "pixelator/collapse/pool2.demux.m1.part_000.report.json", + "pixelator/collapse/pool2.demux.m2.part_000.meta.json", + "pixelator/collapse/pool2.demux.m2.part_000.parquet", + "pixelator/collapse/pool2.demux.m2.part_000.report.json", + "pixelator/collapse/pool2.report.json", + "pixelator/demux", + "pixelator/demux/pool1.demux.failed.fq.zst", + "pixelator/demux/pool1.demux.m1.part_000.parquet", + "pixelator/demux/pool1.demux.m2.part_000.parquet", + "pixelator/demux/pool1.demux.passed.fq.zst", + "pixelator/demux/pool1.meta.json", + "pixelator/demux/pool1.report.json", + "pixelator/demux/pool2.demux.failed.fq.zst", + "pixelator/demux/pool2.demux.m1.part_000.parquet", + "pixelator/demux/pool2.demux.m2.part_000.parquet", + "pixelator/demux/pool2.demux.passed.fq.zst", + "pixelator/demux/pool2.meta.json", + "pixelator/demux/pool2.report.json", + "pixelator/denoise", + "pixelator/denoise/sample1.meta.json", + "pixelator/denoise/sample1.report.json", + "pixelator/denoise/sample2.meta.json", + "pixelator/denoise/sample2.report.json", + "pixelator/denoise/sample3.meta.json", + "pixelator/denoise/sample3.report.json", + "pixelator/denoise/sample4.meta.json", + "pixelator/denoise/sample4.report.json", + "pixelator/experiment-summary.html", + "pixelator/graph", + "pixelator/graph/pool1.meta.json", + "pixelator/graph/pool1.pxl", + "pixelator/graph/pool1.report.json", + "pixelator/graph/pool2.meta.json", + "pixelator/graph/pool2.pxl", + "pixelator/graph/pool2.report.json", + "pixelator/layout", + "pixelator/layout/sample1.meta.json", + "pixelator/layout/sample1.report.json", + "pixelator/layout/sample2.meta.json", + "pixelator/layout/sample2.report.json", + "pixelator/layout/sample3.meta.json", + "pixelator/layout/sample3.report.json", + "pixelator/layout/sample4.meta.json", + "pixelator/layout/sample4.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1.pixelator-combine-collapse.log", + "pixelator/logs/pool1/pool1.demux.m1.part_000.pixelator-collapse.log", + "pixelator/logs/pool1/pool1.demux.m2.part_000.pixelator-collapse.log", + "pixelator/logs/pool1/pool1.pixelator-amplicon.log", + "pixelator/logs/pool1/pool1.pixelator-demux.log", + "pixelator/logs/pool1/pool1.pixelator-graph.log", + "pixelator/logs/pool1/pool1.pixelator-sample-calling.log", + "pixelator/logs/pool2", + "pixelator/logs/pool2.pixelator-combine-collapse.log", + "pixelator/logs/pool2/pool2.demux.m1.part_000.pixelator-collapse.log", + "pixelator/logs/pool2/pool2.demux.m2.part_000.pixelator-collapse.log", + "pixelator/logs/pool2/pool2.pixelator-amplicon.log", + "pixelator/logs/pool2/pool2.pixelator-demux.log", + "pixelator/logs/pool2/pool2.pixelator-graph.log", + "pixelator/logs/pool2/pool2.pixelator-sample-calling.log", + "pixelator/logs/sample1", + "pixelator/logs/sample1/sample1.pixelator-analysis.log", + "pixelator/logs/sample1/sample1.pixelator-denoise.log", + "pixelator/logs/sample1/sample1.pixelator-layout.log", + "pixelator/logs/sample2", + "pixelator/logs/sample2/sample2.pixelator-analysis.log", + "pixelator/logs/sample2/sample2.pixelator-denoise.log", + "pixelator/logs/sample2/sample2.pixelator-layout.log", + "pixelator/logs/sample3", + "pixelator/logs/sample3/sample3.pixelator-analysis.log", + "pixelator/logs/sample3/sample3.pixelator-denoise.log", + "pixelator/logs/sample3/sample3.pixelator-layout.log", + "pixelator/logs/sample4", + "pixelator/logs/sample4/sample4.pixelator-analysis.log", + "pixelator/logs/sample4/sample4.pixelator-denoise.log", + "pixelator/logs/sample4/sample4.pixelator-layout.log", + "pixelator/sample1.pxl", + "pixelator/sample2.pxl", + "pixelator/sample3.pxl", + "pixelator/sample4.pxl", + "pixelator/sample_calling", + "pixelator/sample_calling/pool1.sample_calling.meta.json", + "pixelator/sample_calling/pool1.sample_calling.report.json", + "pixelator/sample_calling/pool2.sample_calling.meta.json", + "pixelator/sample_calling/pool2.sample_calling.report.json", + "pixelator/sample_calling/sample1.dehashed.pxl", + "pixelator/sample_calling/sample2.dehashed.pxl", + "pixelator/sample_calling/sample3.dehashed.pxl", + "pixelator/sample_calling/sample4.dehashed.pxl" + ], + [ + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample1.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample2.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample3.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "sample4.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool1.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "pool2.sample_calling.meta.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + { + "CAT_FASTQ": { + "cat": 9.5 + }, + "EXPERIMENT_SUMMARY": { + "experiment-summary": "0.10.1" + }, + "PIXELATOR_AMPLICON": { + "pixelator": "0.26.0" + }, + "PIXELATOR_ANALYSIS": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COMBINE_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DEMUX": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DENOISE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_GRAPH": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LAYOUT": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LIST_OPTIONS": { + "pixelator": "0.26.0" + }, + "Workflow": { + "nf-core/pixelator": "v4.0.0" + } + } + ], + "timestamp": "2026-05-22T14:44:24.873076953", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "Params: all": { + "content": [ + 29, + { + "CAT_FASTQ": { + "cat": 9.5 + }, + "EXPERIMENT_SUMMARY": { + "experiment-summary": "0.10.1" + }, + "PIXELATOR_AMPLICON": { + "pixelator": "0.26.0" + }, + "PIXELATOR_ANALYSIS": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_COMBINE_COLLAPSE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DEMUX": { + "pixelator": "0.26.0" + }, + "PIXELATOR_DENOISE": { + "pixelator": "0.26.0" + }, + "PIXELATOR_GRAPH": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LAYOUT": { + "pixelator": "0.26.0" + }, + "PIXELATOR_LIST_OPTIONS": { + "pixelator": "0.26.0" + }, + "Workflow": { + "nf-core/pixelator": "v4.0.0" + } + }, + [ + "pipeline_info", + "pipeline_info/nf_core_pixelator_software_versions.yml", + "pipeline_info/samplesheet_proxiome_v2.csv", + "pixelator", + "pixelator/amplicon", + "pixelator/amplicon/pool1.amplicon.fq.zst", + "pixelator/amplicon/pool1.meta.json", + "pixelator/amplicon/pool1.report.json", + "pixelator/amplicon/pool2.amplicon.fq.zst", + "pixelator/amplicon/pool2.meta.json", + "pixelator/amplicon/pool2.report.json", + "pixelator/analysis", + "pixelator/analysis/sample1.analysis.pxl", + "pixelator/analysis/sample1.meta.json", + "pixelator/analysis/sample1.report.json", + "pixelator/analysis/sample2.analysis.pxl", + "pixelator/analysis/sample2.meta.json", + "pixelator/analysis/sample2.report.json", + "pixelator/analysis/sample3.analysis.pxl", + "pixelator/analysis/sample3.meta.json", + "pixelator/analysis/sample3.report.json", + "pixelator/analysis/sample4.analysis.pxl", + "pixelator/analysis/sample4.meta.json", + "pixelator/analysis/sample4.report.json", + "pixelator/collapse", + "pixelator/collapse/pool1.collapse.m1.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m1.part_000.parquet", + "pixelator/collapse/pool1.collapse.m1.part_000.report.json", + "pixelator/collapse/pool1.collapse.m2.part_000.meta.json", + "pixelator/collapse/pool1.collapse.m2.part_000.parquet", + "pixelator/collapse/pool1.collapse.m2.part_000.report.json", + "pixelator/collapse/pool1.collapse.parquet", + "pixelator/collapse/pool1.meta.json", + "pixelator/collapse/pool1.report.json", + "pixelator/collapse/pool2.collapse.m1.part_000.meta.json", + "pixelator/collapse/pool2.collapse.m1.part_000.parquet", + "pixelator/collapse/pool2.collapse.m1.part_000.report.json", + "pixelator/collapse/pool2.collapse.m2.part_000.meta.json", + "pixelator/collapse/pool2.collapse.m2.part_000.parquet", + "pixelator/collapse/pool2.collapse.m2.part_000.report.json", + "pixelator/collapse/pool2.collapse.parquet", + "pixelator/collapse/pool2.meta.json", + "pixelator/collapse/pool2.report.json", + "pixelator/demux", + "pixelator/demux/pool1.demux.failed.fq.zst", + "pixelator/demux/pool1.demux.m1.part_000.parquet", + "pixelator/demux/pool1.demux.m2.part_000.parquet", + "pixelator/demux/pool1.demux.passed.fq.zst", + "pixelator/demux/pool1.meta.json", + "pixelator/demux/pool1.report.json", + "pixelator/demux/pool2.demux.failed.fq.zst", + "pixelator/demux/pool2.demux.m1.part_000.parquet", + "pixelator/demux/pool2.demux.m2.part_000.parquet", + "pixelator/demux/pool2.demux.passed.fq.zst", + "pixelator/demux/pool2.meta.json", + "pixelator/demux/pool2.report.json", + "pixelator/denoise", + "pixelator/denoise/sample1.meta.json", + "pixelator/denoise/sample1.report.json", + "pixelator/denoise/sample2.meta.json", + "pixelator/denoise/sample2.report.json", + "pixelator/denoise/sample3.meta.json", + "pixelator/denoise/sample3.report.json", + "pixelator/denoise/sample4.meta.json", + "pixelator/denoise/sample4.report.json", + "pixelator/experiment-summary.html", + "pixelator/graph", + "pixelator/graph/pool1.graph.pxl", + "pixelator/graph/pool1.meta.json", + "pixelator/graph/pool1.report.json", + "pixelator/graph/pool2.graph.pxl", + "pixelator/graph/pool2.meta.json", + "pixelator/graph/pool2.report.json", + "pixelator/layout", + "pixelator/layout/sample1.meta.json", + "pixelator/layout/sample1.report.json", + "pixelator/layout/sample2.meta.json", + "pixelator/layout/sample2.report.json", + "pixelator/layout/sample3.meta.json", + "pixelator/layout/sample3.report.json", + "pixelator/layout/sample4.meta.json", + "pixelator/layout/sample4.report.json", + "pixelator/logs", + "pixelator/logs/pool1", + "pixelator/logs/pool1.pixelator-combine-collapse.log", + "pixelator/logs/pool1/pool1.pixelator-amplicon.log", + "pixelator/logs/pool1/pool1.pixelator-collapse.log", + "pixelator/logs/pool1/pool1.pixelator-demux.log", + "pixelator/logs/pool1/pool1.pixelator-graph.log", + "pixelator/logs/pool1/pool1.pixelator-sample-calling.log", + "pixelator/logs/pool2", + "pixelator/logs/pool2.pixelator-combine-collapse.log", + "pixelator/logs/pool2/pool2.pixelator-amplicon.log", + "pixelator/logs/pool2/pool2.pixelator-collapse.log", + "pixelator/logs/pool2/pool2.pixelator-demux.log", + "pixelator/logs/pool2/pool2.pixelator-graph.log", + "pixelator/logs/pool2/pool2.pixelator-sample-calling.log", + "pixelator/logs/sample1", + "pixelator/logs/sample1/sample1.pixelator-analysis.log", + "pixelator/logs/sample1/sample1.pixelator-denoise.log", + "pixelator/logs/sample1/sample1.pixelator-layout.log", + "pixelator/logs/sample2", + "pixelator/logs/sample2/sample2.pixelator-analysis.log", + "pixelator/logs/sample2/sample2.pixelator-denoise.log", + "pixelator/logs/sample2/sample2.pixelator-layout.log", + "pixelator/logs/sample3", + "pixelator/logs/sample3/sample3.pixelator-analysis.log", + "pixelator/logs/sample3/sample3.pixelator-denoise.log", + "pixelator/logs/sample3/sample3.pixelator-layout.log", + "pixelator/logs/sample4", + "pixelator/logs/sample4/sample4.pixelator-analysis.log", + "pixelator/logs/sample4/sample4.pixelator-denoise.log", + "pixelator/logs/sample4/sample4.pixelator-layout.log", + "pixelator/sample1.layout.pxl", + "pixelator/sample2.layout.pxl", + "pixelator/sample3.layout.pxl", + "pixelator/sample4.layout.pxl", + "pixelator/sample_calling", + "pixelator/sample_calling/pool1.sample_calling.report.json", + "pixelator/sample_calling/pool1_undetermined.meta.json", + "pixelator/sample_calling/pool1_undetermined.report.json", + "pixelator/sample_calling/pool2.sample_calling.report.json", + "pixelator/sample_calling/pool2_undetermined.meta.json", + "pixelator/sample_calling/pool2_undetermined.report.json", + "pixelator/sample_calling/sample1.dehashed.pxl", + "pixelator/sample_calling/sample1.meta.json", + "pixelator/sample_calling/sample1.report.json", + "pixelator/sample_calling/sample2.dehashed.pxl", + "pixelator/sample_calling/sample2.meta.json", + "pixelator/sample_calling/sample2.report.json", + "pixelator/sample_calling/sample3.dehashed.pxl", + "pixelator/sample_calling/sample3.meta.json", + "pixelator/sample_calling/sample3.report.json", + "pixelator/sample_calling/sample4.dehashed.pxl", + "pixelator/sample_calling/sample4.meta.json", + "pixelator/sample_calling/sample4.report.json" + ], + [ + "pool1.meta.json:md5,41c228a0f862dd47e6b4b66b001cc44b", + "pool2.meta.json:md5,41c228a0f862dd47e6b4b66b001cc44b", + "sample1.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "sample2.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "sample3.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "sample4.meta.json:md5,2a6eaa66228775591525f74416f0b87f", + "pool1.meta.json:md5,84596e67700975fd7518a0fdeedf3168", + "pool2.meta.json:md5,84596e67700975fd7518a0fdeedf3168", + "sample1.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "sample2.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "sample3.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "sample4.meta.json:md5,d0728a1efc25964039497c7bc22cdc35", + "pool1.meta.json:md5,481df097c7b214be07def5d68f04e79d", + "pool2.meta.json:md5,481df097c7b214be07def5d68f04e79d", + "sample1.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3", + "sample2.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3", + "sample3.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3", + "sample4.meta.json:md5,82fcbb6ae5e3156c70978973c862f5f3", + "pool1_undetermined.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7", + "pool2_undetermined.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7", + "sample1.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7", + "sample2.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7", + "sample3.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7", + "sample4.meta.json:md5,f59cd8963a4760d34bd2b41e740242b7" + ] + ], + "timestamp": "2026-05-22T14:43:17.238109494", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file diff --git a/tests/scripts/run_smoke_tests.sh b/tests/scripts/run_smoke_tests.sh index 8b598603..6eed9c67 100644 --- a/tests/scripts/run_smoke_tests.sh +++ b/tests/scripts/run_smoke_tests.sh @@ -4,4 +4,4 @@ ARGS=$@ -nf-test test --profile test,docker $ARGS --tag="smoke_test" +nf-test test --profile=+docker $ARGS --tag="smoke_test" diff --git a/tests/scripts/run_tests_parallel.sh b/tests/scripts/run_tests_parallel.sh index f339c774..fd2e9e1a 100755 --- a/tests/scripts/run_tests_parallel.sh +++ b/tests/scripts/run_tests_parallel.sh @@ -5,27 +5,33 @@ ARGS=$@ echo Running tests: experiment summary... -nf-test test --profile test,docker $ARGS \ +nf-test test --profile=+docker $ARGS \ modules/local/experiment_summary/ \ &> /tmp/pixelator_es_tests.txt \ && echo "Completed tests: experiment summary" & echo Running tests: PNA modules... -nf-test test --profile test,docker $ARGS \ - modules/local/pixelator/single-cell-pna/ \ +nf-test test --profile=+docker $ARGS \ + modules/local/pixelator/ \ &> /tmp/pixelator_pna_modules_tests.txt \ && echo "Completed tests: PNA modules" & echo Running tests: subworkflows... -nf-test test --profile test,docker $ARGS \ +nf-test test --profile=+docker $ARGS \ subworkflows/ \ &> /tmp/pixelator_subworkflow_tests.txt \ && echo "Completed tests: subworkflows" & -echo Running tests: PNA pipeline... -nf-test test --profile test,docker $ARGS \ - tests/pna.nf.test \ - &> /tmp/pixelator_pna_pipeline_tests.txt \ +echo Running tests: PNA pipeline V1... +nf-test test --profile=+docker $ARGS \ + tests/proxiome_v1.nf.test \ + &> /tmp/pixelator_pna_pipeline_v1_tests.txt \ + && echo "Completed tests: PNA pipeline" & + +echo Running tests: PNA pipeline V2... +nf-test test --profile=+docker $ARGS \ + tests/proxiome_v2.nf.test \ + &> /tmp/pixelator_pna_pipeline_v2_tests.txt \ && echo "Completed tests: PNA pipeline" & wait @@ -33,4 +39,5 @@ wait cat /tmp/pixelator_es_tests.txt \ /tmp/pixelator_pna_modules_tests.txt \ /tmp/pixelator_subworkflow_tests.txt \ - /tmp/pixelator_pna_pipeline_tests.txt \ + /tmp/pixelator_pna_pipeline_v1_tests.txt \ + /tmp/pixelator_pna_pipeline_v2_tests.txt \ diff --git a/workflows/pixelator.nf b/workflows/pixelator.nf index 72378ca3..1d3c0e8b 100644 --- a/workflows/pixelator.nf +++ b/workflows/pixelator.nf @@ -8,11 +8,6 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_pixelator_pipeline' -// Inject the samplesheet SHA-1 into the params object -if (params.input) { - params.samplesheet_sha = file(params.input).bytes.digest('sha-1') -} - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CONFIG FILES @@ -28,7 +23,8 @@ if (params.input) { // // SUBWORKFLOW: Consisting of a mix of local and nf-core/modules // -include { PNA } from '../subworkflows/local/pna' +include { PIXELATOR_PNA_V1 } from '../subworkflows/local/pna/v1' +include { PIXELATOR_PNA_V2 } from '../subworkflows/local/pna/v2' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -44,8 +40,6 @@ include { PNA } from '../subworkflows/local/pna' IMPORT CUSTOM MODULES/SUBWORKFLOWS ======================================================================================== */ -include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' - /* ======================================================================================== @@ -66,67 +60,23 @@ workflow PIXELATOR { // // Split the samplesheet channel in reads and panel_files // - ch_reads = ch_samplesheet.map { meta, panel, reads -> [ meta, reads ] } - ch_panel_files = ch_samplesheet.map { meta, panel, reads -> [ meta, panel ] } - - ch_fastq_split = ch_reads - .groupTuple() - .branch { - meta, fastq -> - single: fastq.size() == 1 - return [ meta, fastq.flatten() ] - multiple: fastq.size() > 1 - return [ meta, fastq.flatten() ] - } - - // - // MODULE: Concatenate FastQ files from the same sample if required - // - ch_fastq_split.multiple - - ch_cat_fastq = CAT_FASTQ ( ch_fastq_split.multiple ) - .reads - .mix(ch_fastq_split.single) - - // Check that multi lane samples use the same panel file - ch_checked_panel_files = ch_panel_files - .map { meta, data -> [ meta.id, data] } - .groupTuple() - .map { id, data -> - if (!data) { - return [id, []] - } - def unique_panels = data.unique() - if (unique_panels.size() > 1) { - exit 1, "ERROR: Concatenated samples must use the same panel." - } - return [ id, unique_panels[0] ] - } - - ch_cat_panel_files = ch_cat_fastq - .map { meta, _ -> [meta.id, meta] } - .join(ch_checked_panel_files) - .map { id, meta, panel_files -> [meta, panel_files] } - - ch_fastq_technology_split = ch_cat_fastq - .branch { - meta, data -> - pna: meta.technology == 'pna' - return [ meta, data ] - } - - ch_panel_files_technology_split = ch_cat_panel_files - .branch { - meta, data -> - pna: meta.technology == 'pna' - return [ meta, data ] + ch_reads = ch_samplesheet.map { meta, _panel, reads -> [ meta, reads ] } + ch_panel_files = ch_samplesheet.map { meta, panel, _reads -> [ meta, panel ] } + + if (params.technology == "proxiome-v1" || params.technology == "nonhashed_samples") { + PIXELATOR_PNA_V1( + ch_reads, + ch_panel_files + ) + } else if (params.technology == "proxiome-v2" || params.technology == "hashed_samples") { + PIXELATOR_PNA_V2( + ch_reads, + ch_panel_files + ) + } else { + error "Unknown technology: \"${params.technology}\"" } - PNA( - ch_fastq_technology_split.pna, - ch_panel_files_technology_split.pna - ) - // // Collate and save software versions // @@ -151,11 +101,10 @@ workflow PIXELATOR { .mix(topic_versions_string) .collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'pixelator_software_' + 'mqc_' + 'versions.yml', + name: 'nf_core_' + 'pixelator_software_' + 'versions.yml', sort: true, newLine: true - ).set { ch_collated_versions } - + ) emit: versions = ch_versions // channel: [ path(versions.yml) ] }