diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b290e0901..237c9ed08 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,20 +1,21 @@ { + "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json", "name": "nfcore", - "image": "nfcore/gitpod:latest", - "remoteUser": "gitpod", - "runArgs": ["--privileged"], + "image": "nfcore/devcontainer:latest", - // Configure tool-specific properties. - "customizations": { - // Configure properties specific to VS Code. - "vscode": { - // Set *default* container specific settings.json values on container create. - "settings": { - "python.defaultInterpreterPath": "/opt/conda/bin/python" - }, + "remoteUser": "root", + "privileged": true, - // Add the IDs of extensions you want installed when the container is created. - "extensions": ["ms-python.python", "ms-python.vscode-pylance", "nf-core.nf-core-extensionpack"] - } + "remoteEnv": { + // Workspace path on the host for mounting with docker-outside-of-docker + "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" + }, + + "onCreateCommand": "./.devcontainer/setup.sh", + + "hostRequirements": { + "cpus": 4, + "memory": "16gb", + "storage": "32gb" } } diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 000000000..e0b37e0cd --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Customise the terminal command prompt +echo "export PROMPT_DIRTRIM=2" >> $HOME/.bashrc +echo "export PS1='\[\e[3;36m\]\w ->\[\e[0m\\] '" >> $HOME/.bashrc +export PROMPT_DIRTRIM=2 +export PS1='\[\e[3;36m\]\w ->\[\e[0m\\] ' + +# Update Nextflow +nextflow self-update + +# Update welcome message +echo "Welcome to the nf-core/raredisease devcontainer!" > /usr/local/etc/vscode-dev-containers/first-run-notice.txt diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4be355edd..de05c17e5 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -12,19 +12,40 @@ Contributions to the code are even more welcome ;) > [!NOTE] > If you need help using or modifying nf-core/raredisease then the best place to ask is on the nf-core Slack [#raredisease](https://nfcore.slack.com/channels/raredisease) channel ([join our Slack here](https://nf-co.re/join/slack)). -## Contribution workflow - -If you'd like to write some code for nf-core/raredisease, the standard workflow is as follows: - -1. Check that there isn't already an issue about your idea in the [nf-core/raredisease issues](https://github.com/nf-core/raredisease/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/raredisease repository](https://github.com/nf-core/raredisease) 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 +## Table of contents + +- [General](#general) + - [Contribution workflow](#contribution-workflow) + - [Running tests](#running-tests) + - [Patch](#patch) + - [Getting help](#getting-help) + - [Nextflow version bumping](#nextflow-version-bumping) + - [Images and figures](#images-and-figures) + - [GitHub Codespaces](#github-codespaces) +- [Pipeline-specific conventions](#pipeline-specific-conventions) + - [Architecture & structure](#architecture--structure) + - [Adding a new step](#adding-a-new-step) + - [Channel conventions](#channel-conventions) + - [Params & analysis types](#params--analysis-types) + - [Publishing](#publishing) + - [Configuration](#configuration) + - [Writing tests](#writing-tests) + - [Style](#style) + - [Adding citations](#adding-citations) + +## General + +### Contribution workflow + +1. Check that there isn't already an issue about your idea in the [nf-core/raredisease issues](https://github.com/nf-core/raredisease/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/raredisease repository](https://github.com/nf-core/raredisease) to your GitHub account. +3. Make the necessary changes / additions within your forked repository following the conventions below. +4. Use `nf-core pipelines schema build` to add any new parameters to `nextflow_schema.json`. +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 +### Running 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: @@ -37,21 +58,21 @@ Typically, pull-requests are only fully reviewed when these tests are passing, t There are typically two types of tests that run: -### Lint tests +#### 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 +#### 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 +### Patch :warning: Only in the unlikely and regretful event of a release happening with a bug. @@ -59,67 +80,185 @@ These tests are run both with the latest available version of `Nextflow` and als - Fix the bug, and bump version (X.Y.Z+1). - Open a pull-request from `patch` to `main`/`master` with the changes. -## Getting help +### Getting help For further information/help, please consult the [nf-core/raredisease documentation](https://nf-co.re/raredisease/usage) and don't hesitate to get in touch on the nf-core Slack [#raredisease](https://nfcore.slack.com/channels/raredisease) channel ([join our Slack here](https://nf-co.re/join/slack)). -## Pipeline contribution conventions +### Nextflow version bumping -To make the `nf-core/raredisease` 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. +If you are using a new feature from core Nextflow, bump the minimum required version with: -### Adding a new step +```bash +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/raredisease/codespaces) +- Tools installed + - nf-core + - Nextflow + +Devcontainer specs: + +- [DevContainer config](.devcontainer/devcontainer.json) -If you wish to contribute a new step, please use the following coding standards: +## Pipeline-specific conventions + +### Architecture & structure + +- **One subworkflow per biological task** — alignment, QC, variant calling, annotation, and ranking are each their own subworkflow under `subworkflows/local/`. Don't add logic to `workflows/raredisease.nf` that belongs in a subworkflow. +- **Reuse over duplication** — `RANK_VARIANTS`, `ANNOTATE_CSQ_PLI`, and `VCF_FILTER_BCFTOOLS_ENSEMBLVEP` are intentionally included multiple times under different aliases. Follow this pattern before creating a near-identical subworkflow. +- **nf-core modules first** — prefer a module from `modules/nf-core/` over writing a local one. Only add to `modules/local/` when no nf-core module exists or the use case is too pipeline-specific. + +### Adding a new step 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). +2. Write the process block. +3. Define the output channel if needed. +4. Add any new parameters to `nextflow.config` with a default. 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. +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://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 +### Channel conventions -Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. +- **Skip lists**: use `parseSkipList()` and the `skip_tools` / `skip_subworkflows` params. Don't gate logic with raw string comparisons against params directly. +- **Conditional channels**: always initialize to `channel.empty()` before any `if` block that may or may not assign them. Never leave a channel potentially undefined. +- **Channel helpers**: use `channelFromPath`, `channelFromPathWithMeta`, and `channelFromSamplesheet` from `utils_nfcore_raredisease_pipeline` rather than rolling your own `channel.fromPath` calls. -Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`. +### Params & analysis types -### Default processes resource requirements +- `params` must only be accessed in the main unnamed workflow (`workflow` in `main.nf`). Subworkflows and named workflows receive all values as explicit `val_*` arguments. Never reference `params` directly inside a subworkflow. +- New tools that only apply to `wgs`, `wes`, or `mito` must be gated on `val_analysis_type`. +- Skippable tools must be added to the `--skip_tools` or `--skip_subworkflows` param and handled via `parseSkipList()`. +- Default params go in `nextflow.config`. Don't hardcode values that a user might reasonably want to change. Once added, run `nf-core pipelines schema build` to register them in `nextflow_schema.json`. -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. +### Publishing -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. +The pipeline uses Nextflow's `publish:` block and `output {}` API for file publishing. Each subworkflow exposes its outputs as named typed channel emits; the top-level `publish:` block in `main.nf` mixes them into destination-named entries. -### Naming schemes +- Emit every publishable output as its own named typed channel — one emit per file type, no `ch_publish` tuple wrapping and no grouped mix inside the subworkflow. +- In `main.nf`, mix all channels that share a destination into **one** `publish:` entry and **one** `output {}` entry. The mixing belongs at the routing layer, not inside the subworkflow. +- Channels consumed by downstream processes (e.g. MultiQC) and also published are emitted once; the caller wires the same channel to both consumers. -Please use the following naming schemes, to make it easy to understand what is going where. +#### Emit naming convention -- initial process channel: `ch_output_from_` -- intermediate and terminal channels: `ch__for_` +Use `_` (lowercase, underscored) inside the subworkflow's `emit:` block: -### Nextflow version bumping +- Use the **alias name** as the prefix when a process is imported with `as` — the alias already encodes the distinction (e.g. `PICARD_COLLECTWGSMETRICS as PICARD_COLLECTWGSMETRICS_WG` → prefix `picard_collectwgsmetrics_wg`). +- Append the **module's emit name** verbatim. +- Drop obvious redundancy when the emit name exactly repeats a word already in the process/alias name (e.g. `sentieon_wgsmetrics_wg_wgs_metrics` → `sentieon_wgsmetrics_wg_metrics`). Do not rename to describe the file format — always use the emit name. +- For `VERIFYBAMID_VERIFYBAMID2`, drop the repetition: use prefix `verifybamid_`. -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]` +| Layer | Convention | Example | +| ------------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------- | +| Subworkflow `emit:` | `_` | `mosdepth_global_txt` | +| `raredisease.nf` variable | `ch__` | `ch_qc_bam_mosdepth_global_txt` | +| `NFCORE_RAREDISEASE` emit | `_` | `qc_bam_mosdepth_global_txt` | +| `publish:` entry | one entry per destination, mixing all channels for that destination | `qc_bam = NFCORE_RAREDISEASE.out.qc_bam_mosdepth_global_txt.mix(...)` | -### Images and figures +The **semantic suffix** is the part of the emit name that describes what the data is, not which tool produced it. When the subworkflow emit name starts with a process/module name, drop that prefix in the `raredisease.nf` variable if the remainder is unambiguous within the subworkflow's outputs: -For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines). +- `scatter_genome` emits `gatk4_splitintervals_split_intervals` → variable is `ch_scatter_genome_split_intervals` (drop `gatk4_splitintervals_`) +- `qc_bam` emits `mosdepth_global_txt` → variable stays `ch_qc_bam_mosdepth_global_txt` (`global_txt` alone would be ambiguous among the many txt outputs in that subworkflow) -## GitHub Codespaces +When in doubt, keep enough of the process name to remain unambiguous. -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. +> **Note:** Some subworkflows still use the legacy `ch_publish`/`subworkflow_results` pattern and are being migrated incrementally. Until a subworkflow is migrated, follow the existing pattern for that subworkflow so it continues to publish correctly via `subworkflow_results`. -To get started: +### Configuration -- Open the repo in [Codespaces](https://github.com/nf-core/raredisease/codespaces) -- Tools installed - - nf-core - - Nextflow +- Process-level options go in `conf/modules/.config`, not inline in the subworkflow `.nf` file. +- Only `ext.args`, `ext.args2`, and `ext.prefix` belong in module configs. Don't add business logic there. +- Conditional behavior (e.g. save as CRAM vs BAM) is handled in the subworkflow via `channel.empty()` gating — not via config-level flags. +- Process resource requirements (CPUs / memory / time) go in `conf/base.config` using `withLabel:` selectors so they can be shared across processes. Use `${task.cpus}` and `${task.memory}` in `script:` blocks to apply them dynamically. -Devcontainer specs: +### Writing tests -- [DevContainer config](.devcontainer/devcontainer.json) +- Every subworkflow should have a test at `subworkflows/local//tests/main.nf.test`. +- Use `-stub` in the `when:` block only when real test data is difficult to generate. Prefer running with real data where it is reasonably available. +- Snapshot files (`*.nf.test.snap`) are committed alongside tests — update them when outputs change. +- Pipeline-level tests live in `tests/` and cover `default`, `test_bam`, and `test_singleton` profiles. +- Run `nf-test test ` for a single test, `nf-test test` for all. + +### Style + +- Sort `include` statements alphabetically by the name inside the braces. Right-pad each name with spaces so all closing `}` align to the same column (the longest name in the block sets the width): + + ```groovy + include { ALIGN_BWA_BWAMEM2_BWAMEME } from '../align_bwa_bwamem2_bwameme' + include { ALIGN_MT } from '../align_MT' + include { ALIGN_MT as ALIGN_MT_SHIFT } from '../align_MT' + include { SAMTOOLS_VIEW as CONVERTTOCRAM_ALTFILTERED } from '../../../modules/nf-core/samtools/view/main' + include { SAMTOOLS_VIEW as CONVERTTOCRAM_UNFILTERED } from '../../../modules/nf-core/samtools/view/main' + include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_EXCLUDE_ALT } from '../../../modules/nf-core/samtools/view/main' + ``` + +- Both `take:` and `emit:` block entries require an inline type comment. Use `name // type: [mandatory|optional] description` for `take:` and `name = value // channel: [type description]` for `emit:`. Always include the comment — never leave an entry uncommented. + + ```groovy + take: + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + ch_reduced_penetrance // channel: [optional] [ path(penetrance) ] + val_aligner // string: [mandatory] aligner name (bwa/bwamem2/bwameme) + process_with_sort // Boolean + + emit: + vcf = ch_vcf // channel: [ val(meta), path(vcf) ] + ``` + +### Adding citations + +When adding a new tool to the pipeline, update the following three locations: + +#### 1. `CITATIONS.md` + +Add an entry for the tool in alphabetical order under `## Pipeline tools`. If the tool has a publication, include a `>` citation block: + +```markdown +- [ToolName](https://link-to-paper-or-repo) + + > Author A, Author B. Title. Journal. Year;vol(issue):pages. doi:... +``` + +If the tool has no publication, list only the link: + +```markdown +- [ToolName](https://github.com/org/toolname) +``` + +#### 2. `subworkflows/local/utils_nfcore_raredisease_pipeline/main.nf` + +Add citation text and bibliography entries inside `toolCitationText()` and `toolBibliographyText()`. Both functions are structured identically — group the tool's entry under the relevant category variable (e.g. `align_text`, `qc_bam_text`, `preprocessing_text`, `snv_annotation_text`). Mirror any conditional logic that gates the tool's execution (e.g. skip params, analysis type, or input content) so the citation only appears when the tool actually runs: + +```groovy +// toolCitationText() +qc_bam_text = [ + ..., + (condition) ? "ToolName (Author et al., Year)," : "" +] + +// toolBibliographyText() +qc_bam_text = [ + ..., + (condition) ? "
  • Author A, Author B. Title. Journal. Year. doi:...
  • " : "" +] +``` + +For tools that run only when the input samplesheet contains a particular file type, use a helper function rather than a param check — see `hasSpringInput()` as an example. + +#### 3. `README.md` + +Add the tool to the relevant numbered section in the **Pipeline summary**. If the tool belongs to a new category not yet represented, add a new numbered section in the appropriate position. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 266a933f7..3cdf5a96b 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/raredisease/tree/master/.github/CONTRIBUTING.md) +Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/raredisease/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/raredisease/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/raredisease/tree/master/docs/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/raredisease _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 34085279f..e2833ee97 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 75abf76c3..827a66110 100644 --- a/.github/actions/nf-test/action.yml +++ b/.github/actions/nf-test/action.yml @@ -20,14 +20,14 @@ 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@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.13" + python-version: "3.14" - name: Install pdiff shell: bash @@ -35,14 +35,14 @@ runs: python -m pip install pdiff - 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') @@ -53,20 +53,30 @@ 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 + channels: conda-forge + channel-priority: strict conda-remove-defaults: true + # Set up secrets + - name: Set up Nextflow secrets + if: env.SENTIEON_ENCRYPTION_KEY != '' && env.SENTIEON_LICENSE_MESSAGE != '' + shell: bash + run: | + python -m pip install cryptography + nextflow secrets set SENTIEON_AUTH_DATA $(python3 bin/license_message.py encrypt --key "$SENTIEON_ENCRYPTION_KEY" --message "$SENTIEON_LICENSE_MESSAGE") + # TODO Skip failing conda tests and document their failures # https://github.com/nf-core/modules/issues/7017 - name: Run nf-test shell: bash env: - NFT_DIFF: ${{ env.NFT_DIFF }} - NFT_DIFF_ARGS: ${{ env.NFT_DIFF_ARGS }} NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + SENTIEON_LICSRVR_IP: ${{ env.SENTIEON_LICSRVR_IP }} + SENTIEON_AUTH_MECH: "GitHub Actions - token" run: | nf-test test \ --profile=+${{ inputs.profile }} \ diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 20acdfe97..cda3bb0dd 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -23,25 +23,45 @@ 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 + # TODO nf-core: You can customise AWS full pipeline tests as required # Add full size test data (but still relatively small datasets for few samples) # on the `test_full.config` test runs with only one set of parameters with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + workspace_id: ${{ vars.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} + compute_env: ${{ vars.TOWER_COMPUTE_ENV }} revision: ${{ steps.revision.outputs.revision }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/raredisease/work-${{ steps.revision.outputs.revision }} + workdir: s3://${{ vars.AWS_S3_BUCKET }}/work/raredisease/work-${{ steps.revision.outputs.revision }} + nextflow_config: | + plugins { + id 'nf-slack@0.5.0' + } + slack { + enabled = true + bot { + token = '${{ secrets.NFSLACK_BOT_TOKEN }}' + channel = 'raredisease' + } + onStart { + enabled = false + } + onComplete { + message = ':white_check_mark: *raredisease/test_full* completed successfully! :tada:' + } + onError { + message = ':x: *raredisease/test_full* failed :crying_cat_face:' + } + } parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/raredisease/results-${{ steps.revision.outputs.revision }}" + "outdir": "s3://${{ vars.AWS_S3_BUCKET }}/raredisease/results-${{ steps.revision.outputs.revision }}" } profiles: test_full - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: Seqera Platform debug log file path: | - seqera_platform_action_*.log - seqera_platform_action_*.json + tower_action_*.log + tower_action_*.json diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 78f48f475..3a35ecdb4 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -12,22 +12,22 @@ 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: ${{ secrets.TOWER_WORKSPACE_ID }} + workspace_id: ${{ vars.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} + compute_env: ${{ vars.TOWER_COMPUTE_ENV }} revision: ${{ github.sha }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/raredisease/work-${{ github.sha }} + workdir: s3://${{ vars.AWS_S3_BUCKET }}/work/raredisease/work-${{ github.sha }} parameters: | { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/raredisease/results-test-${{ github.sha }}" + "outdir": "s3://${{ vars.AWS_S3_BUCKET }}/raredisease/results-test-${{ github.sha }}" } profiles: test - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: Seqera Platform debug log file path: | - seqera_platform_action_*.log - seqera_platform_action_*.json + tower_action_*.log + tower_action_*.json diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index a7f9e1bad..6629f3ef5 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 ac030fd58..172de6f37 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@5bef64f19d7facfb25b37b414482c7164d639639 # v9 + - 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 999bcc382..a7bf4fc21 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -38,15 +38,18 @@ 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@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.13" + python-version: "3.14" architecture: "x64" - name: Setup Apptainer @@ -54,10 +57,15 @@ jobs: with: apptainer-version: 1.3.4 + - 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@dev + 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + 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 b5f9f22f3..bbacef323 100644 --- a/.github/workflows/fix_linting.yml +++ b/.github/workflows/fix_linting.yml @@ -13,13 +13,13 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} # indication that the linting is being fixed - name: React on comment - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{ github.event.comment.id }} reactions: eyes @@ -31,30 +31,26 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - # Install and run pre-commit - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 - with: - python-version: "3.13" - - - 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' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + if: steps.prek.outcome == 'success' + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{ github.event.comment.id }} reactions: "+1" - 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" @@ -67,21 +63,21 @@ jobs: - name: react if linting errors were fixed id: react-if-fixed if: steps.commit-and-push.outcome == 'success' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{ github.event.comment.id }} reactions: hooray - name: react if linting errors were not fixed if: steps.commit-and-push.outcome == 'failure' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{ github.event.comment.id }} reactions: confused - name: react if linting errors were not fixed if: steps.commit-and-push.outcome == 'failure' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: issue-number: ${{ github.event.issue.number }} body: | diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index f2d7d1dd7..8738ffc99 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: Set up Python 3.12 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 - with: - python-version: "3.13" - - - 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + 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@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.13" + 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + 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 7e8050fb8..5b0c24f75 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@4c1e823582f43b179e2cbb49c3eade4e41f992e2 # v10 + 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@52423e01640425a022ef5fd42c6fb5f633a02728 # 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 5a604ff24..935d58c5d 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -1,12 +1,5 @@ name: Run nf-test on: - push: - paths-ignore: - - "docs/**" - - "**/meta.yml" - - "**/*.md" - - "**/*.png" - - "**/*.svg" pull_request: paths-ignore: - "docs/**" @@ -25,7 +18,7 @@ concurrency: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NFT_VER: "0.9.2" + NFT_VER: "0.9.4" NFT_WORKDIR: "~" NXF_ANSI_LOG: false NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity @@ -35,7 +28,7 @@ jobs: nf-test-changes: name: nf-test-changes runs-on: # use self-hosted runners - - runs-on=$-nf-test-changes + - runs-on=${{ github.run_id }}-nf-test-changes - runner=4cpu-linux-x64 outputs: shard: ${{ steps.set-shards.outputs.shard }} @@ -47,7 +40,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 @@ -57,7 +50,7 @@ jobs: env: NFT_VER: ${{ env.NFT_VER }} with: - max_shards: 7 + max_shards: 20 - name: debug run: | @@ -69,9 +62,9 @@ jobs: needs: [nf-test-changes] if: ${{ needs.nf-test-changes.outputs.total_shards != '0' }} runs-on: # use self-hosted runners - - runs-on=$-nf-test + - runs-on=${{ github.run_id }}-nf-test - runner=4cpu-linux-x64 - - disk=large + - volume=80gb strategy: fail-fast: false matrix: @@ -84,14 +77,14 @@ jobs: - isMain: false profile: "singularity" NXF_VER: - - "24.04.2" + - "25.10.4" - "latest-everything" env: NXF_ANSI_LOG: false TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 @@ -99,21 +92,44 @@ jobs: uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - name: Run nf-test + id: run_nf_test uses: ./.github/actions/nf-test + continue-on-error: ${{ matrix.NXF_VER == 'latest-everything' }} env: NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + NXF_VERSION: ${{ matrix.NXF_VER }} + SENTIEON_AUTH_MECH: "GitHub Actions - token" + SENTIEON_ENCRYPTION_KEY: ${{ secrets.SENTIEON_ENCRYPTION_KEY }} + SENTIEON_LICENSE_MESSAGE: ${{ secrets.SENTIEON_LICENSE_MESSAGE }} + SENTIEON_LICSRVR_IP: ${{ secrets.SENTIEON_LICSRVR_IP }} with: profile: ${{ matrix.profile }} shard: ${{ matrix.shard }} total_shards: ${{ env.TOTAL_SHARDS }} + + - name: Report test status + if: ${{ always() }} + run: | + if [[ "${{ steps.run_nf_test.outcome }}" == "failure" ]]; then + echo "::error::Test with ${{ matrix.NXF_VER }} failed" + # Add to workflow summary + echo "## ❌ Test failed: ${{ matrix.profile }} | ${{ matrix.NXF_VER }} | Shard ${{ matrix.shard }}/${{ env.TOTAL_SHARDS }}" >> $GITHUB_STEP_SUMMARY + if [[ "${{ matrix.NXF_VER }}" == "latest-everything" ]]; then + echo "::warning::Test with latest-everything failed but will not cause workflow failure. Please check if the error is expected or if it needs fixing." + fi + if [[ "${{ matrix.NXF_VER }}" != "latest-everything" ]]; then + exit 1 + fi + fi + confirm-pass: needs: [nf-test] if: always() runs-on: # use self-hosted runners - - runs-on=$-confirm-pass + - runs-on=${{ github.run_id }}-confirm-pass - runner=2cpu-linux-x64 steps: - - name: One or more tests failed + - name: One or more tests failed (excluding latest-everything) if: ${{ contains(needs.*.result, 'failure') }} run: exit 1 @@ -132,11 +148,3 @@ jobs: echo "DEBUG: toJSON(needs) = ${{ toJSON(needs) }}" echo "DEBUG: toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}" echo "::endgroup::" - - - name: Clean Workspace # Purge the workspace in case it's running on a self-hosted runner - if: always() - run: | - ls -la ./ - rm -rf ./* || true - rm -rf ./.??* || true - ls -la ./ diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index 4abaf4843..78d5dbe05 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -14,7 +14,11 @@ jobs: run: | echo "topics=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ')" | sed 's/-//g' >> $GITHUB_OUTPUT - - uses: rzr/fediverse-action@master + - name: get description + 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@563159eb8d45f70ab6aaba36ed55cd037e51f441 # master with: access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }} host: "mstdn.science" # custom host if not "mastodon.social" (default) @@ -22,7 +26,7 @@ jobs: # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#release message: | Pipeline release! ${{ github.repository }} v${{ github.event.release.tag_name }} - ${{ github.event.release.name }}! - + ${{ steps.get_description.outputs.description }} Please see the changelog: ${{ github.event.release.html_url }} ${{ steps.get_topics.outputs.topics }} #nfcore #openscience #nextflow #bioinformatics @@ -30,7 +34,7 @@ jobs: bsky-post: runs-on: ubuntu-latest steps: - - uses: zentered/bluesky-post-action@4aa83560bb3eac05dbad1e5f221ee339118abdd2 # v0.2.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 beb5c77fb..ea30827ec 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + 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 e4fcdb390..19878a5e8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,7 @@ testing/ testing* *.pyc null/ +.lineage/ .prettierignore -.nf-test +.nf-test/ +.nf-test.log diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 83599f633..000000000 --- a/.gitpod.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nfcore/gitpod:latest -tasks: - - name: Update Nextflow and setup pre-commit - command: | - pre-commit install --install-hooks - nextflow self-update - -vscode: - extensions: - - nf-core.nf-core-extensionpack # https://github.com/nf-core/vscode-extensionpack diff --git a/.nf-core.yml b/.nf-core.yml index 3f5bbbb34..e2811f0a6 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -8,7 +8,7 @@ lint: - docs/images/nf-core-raredisease_logo_light.png - assets/nf-core-raredisease_logo_light.png modules_config: false -nf_core_version: 3.3.1 +nf_core_version: 4.0.2 repository_type: pipeline template: author: Clinical Genomics Stockholm @@ -18,4 +18,4 @@ template: name: raredisease org: nf-core outdir: . - version: 2.6.0 + version: 3.2.0dev diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d0b248d3..f51e1a28d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,24 +4,30 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.5.0 + - prettier@3.8.3 - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace args: [--markdown-linebreak-ext=md] 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 edd29f01e..63cde500e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,4 @@ email_template.html -adaptivecard.json -slackreport.json .nextflow* work/ data/ @@ -10,4 +8,7 @@ testing/ testing* *.pyc bin/ +.nf-test/ ro-crate-metadata.json +modules/nf-core/ +subworkflows/nf-core/ diff --git a/CHANGELOG.md b/CHANGELOG.md index cb7fb320b..fb031ede7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,227 @@ 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.2.0dev - Luigi [XXXX-XX-XX] + +### `Added` + +- Update saltshaker classification reporting by adding customer ID to samples' reports and displaying them as tabs in html [#856](https://github.com/nf-core/raredisease/pull/856) +- Added non-stub tests for `annotate_mt_snvs` [#890](https://github.com/nf-core/raredisease/pull/890) +- Added GATK contamination check for WES/WGS samples as complement to VerifyBamID2, enabled by providing `contamination_sites` and skippable via `--skip_tools gatkcontamination` [#758](https://github.com/nf-core/raredisease/pull/758) +- GATK Contamination results displayed in MultiQC with color-coded thresholds [#758](https://github.com/nf-core/raredisease/pull/758) + +### `Changed` + +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for gens and generate_cytosure_files subworkflows [#899](https://github.com/nf-core/raredisease/pull/899) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for `rank_variants` subworkflow [#896](https://github.com/nf-core/raredisease/pull/896) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for `variant_evaluation` subworkflow [#897](https://github.com/nf-core/raredisease/pull/897) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for `prepare_references` subworkflow [#900](https://github.com/nf-core/raredisease/pull/900) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for call_repeat_expansions subworkflow [#893](https://github.com/nf-core/raredisease/pull/893) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for call_mobile_elements and annotate_consequence_pli subworkflows; remove `val_publish_dir` parameter from annotate_consequence_pli [#894](https://github.com/nf-core/raredisease/pull/894) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for `annotate_mt_snvs` subworkflow [#895](https://github.com/nf-core/raredisease/pull/895) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for call_snv, call_snv_deepvariant, and postprocess_MT_calls subworkflows [#863](https://github.com/nf-core/raredisease/pull/863) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for annotate_rhocallviz and annotate_genome_snvs subworkflows [#858](https://github.com/nf-core/raredisease/pull/858) +- Expand annotate_rhocallviz test with snapshot assertions [#858](https://github.com/nf-core/raredisease/pull/858) +- Refactor scatter_genome subworkflow: alias GAWK as `GENOME_FAI_TO_BED`, remove `val_save_reference` parameter, move interval flattening into `annotate_genome_snvs` [#857](https://github.com/nf-core/raredisease/pull/857) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for qc_bam subworkflow [#853](https://github.com/nf-core/raredisease/pull/853) +- Replace `ch_publish`/`subworkflow_results` with named typed channel emits for alignment and subsample-MT subworkflows [#850](https://github.com/nf-core/raredisease/pull/850) +- Update saltshaker modules to version 1.1.1 so they can run on empty mitosalt output [#856](https://github.com/nf-core/raredisease/pull/856) +- Update metromap to reflect the addition of mitosalt + saltshaker and removal of eklipse [#892](https://github.com/nf-core/raredisease/pull/892) + +### `Fixed` + +- Fix intermittent `CALL_SNV_DEEPVARIANT - wgs` test failure caused by non-deterministic GLnexus quality scores by replacing `variantsMD5` with `vcf.summary` [#850](https://github.com/nf-core/raredisease/pull/850) +- Fix swapped `run_mt_for_wes`/`skip_split_multiallelics` arguments in the `CALL_SNV` call, which disabled multiallelic splitting (and inverted MT-for-WES) when `--run_mt_for_wes` was set [#854](https://github.com/nf-core/raredisease/issues/854) + +### Parameters + +| Old parameter | New parameter | +| ------------- | ----------------------- | +| | contamination_sites | +| | contamination_sites_tbi | + +### Tool updates + +| Tool | Old version | New version | +| ---------------------------- | ----------- | ----------- | +| gatk4/calculatecontamination | | 4.6.2.0 | +| gatk4/getpileupsummaries | | 4.6.2.0 | +| Saltshaker | 1.0.0 | 1.1.1 | + +## 3.1.1 - Princess Peach (patch) [2026-06-24] + +### `Fixed` + +- Patch `deepvariant/rundeepvariant` to tee stdout/stderr to a log file and exit non-zero when `queue.Empty` or `BrokenPipeError` is detected, catching silent failures that previously caused the process to appear successful [#889](https://github.com/nf-core/raredisease/pull/889) + +## 3.1.0 - Princess Peach [2026-06-16] + +### `Added` + +- Parameter `cadd_prescored` to pass a directory of pre-scored CADD indel annotations to the CADD process in genome and mitochondrial SNV annotation subworkflows [#866](https://github.com/nf-core/raredisease/pull/866) +- Parameter `manta_call_regions` to restrict Manta SV calling to specified regions (e.g. primary chromosomes) via a bgzipped, tabix-indexed BED file, reducing runtime without affecting other callers [#867](https://github.com/nf-core/raredisease/pull/867) +- Local `FILTERVEP` module using a Python reimplementation of Ensembl's `filter_vep`, replacing the `ENSEMBLVEP_FILTERVEP` module with a lighter cyvcf2-based alternative [#870](https://github.com/nf-core/raredisease/pull/870) +- `bwafastalign/index` nf-core module and `bwafastalign` parameter to support index preparation for the bwa-fastalign genome aligner [#877](https://github.com/nf-core/raredisease/pull/877) +- `bwafastalign/mem` nf-core module to support genome alignment with bwa-fastalign when `--aligner bwafastalign` is set [#880](https://github.com/nf-core/raredisease/pull/880) + +### `Changed` + +- Replace `ENSEMBLVEP_FILTERVEP` with local `FILTERVEP` in the clinical set subworkflow, renamed from `VCF_FILTER_BCFTOOLS_ENSEMBLVEP` to `VCF_FILTER_BCFTOOLS_FILTERVEP` [#870](https://github.com/nf-core/raredisease/pull/870) +- Increase default mbuffer memory value from 3GB to 8GB [#880](https://github.com/nf-core/raredisease/pull/880) +- Update `bwameme/mem` to new nf-core module signature: `val mbuffer` and `val samtools_threads` replaced by `ext.args2` and `ext.args3` [#881](https://github.com/nf-core/raredisease/pull/881) + +### `Fixed` + +- Add a bcftools norm split-multiallelics step after merging standard and shifted MT calls to handle new multiallelic sites introduced by bcftools merge [#855](https://github.com/nf-core/raredisease/pull/855) + +### Parameters + +| Old parameter | New parameter | +| ------------- | ---------------------- | +| | bwafastalign | +| | cadd_prescored | +| | manta_call_regions | +| | manta_call_regions_tbi | + +### Tool updates + +| Tool | Old version | New version | +| ------------- | ----------- | ----------- | +| bwa-fastalign | | 1.0.0 | +| saltshaker | 1.0.0 | 1.1.1 | + +## 3.0.0 - Mario [2026-05-12] + +### `Added` + +- Interval parameter in the default retroseq call [#717](https://github.com/nf-core/raredisease/pull/717) +- Tests for call_repeat_expansions and qc_bam subworkflows [#713](https://github.com/nf-core/raredisease/pull/713) +- Feature to subsample mitochondrial alignments based on number of reads [#748](https://github.com/nf-core/raredisease/pull/748) +- Functionality to generate coverage information using Sambamba depth [#752](https://github.com/nf-core/raredisease/pull/752) +- Parameter to pass a file containing new sample ids to use with multiqc [#764](https://github.com/nf-core/raredisease/pull/764) +- A helper function channelFromPath to create channels in a readable fashion in main.nf [#766](https://github.com/nf-core/raredisease/pull/766) +- A helper function channelFromPathWithMeta to create channels in a readable fashion in main.nf [#767](https://github.com/nf-core/raredisease/pull/767) +- A helper function channelFromSamplesheet to create channels in a readable fashion in main.nf [#767](https://github.com/nf-core/raredisease/pull/767) +- A parameter `homoplasmy_af_threshold` to set genotypes of MT SNVs to 1/1 (homoplasmic) when AF >=`homoplasmy_af_threshold` [#768](https://github.com/nf-core/raredisease/pull/768) +- Topic channels to local modules to caputure versions [#774](https://github.com/nf-core/raredisease/pull/774) +- MitoSalt to detect mitochondrial deletions [#743](https://github.com/nf-core/raredisease/pull/743) +- Tests for some of the subworkflows [#780](https://github.com/nf-core/raredisease/pull/780) +- Tests for some of the subworkflows [#782](https://github.com/nf-core/raredisease/pull/782) +- Tests for some of the subworkflows [#783](https://github.com/nf-core/raredisease/pull/783) +- Test tags for dependent modules in subworkflow tests [#800](https://github.com/nf-core/raredisease/pull/800) +- Stub test for scatter_genome subworkflow [#802](https://github.com/nf-core/raredisease/pull/802) +- Add CAT_FASTQ before SEQTK_SAMPLE in call_sv_MT to merge reads across lanes before subsampling for MitoSalt [#799](https://github.com/nf-core/raredisease/pull/799) +- Add new local SPLIT_CHR module to split reference FASTA by chromosome for CNVnator, and pass genome flag to all CNVnator steps [#799](https://github.com/nf-core/raredisease/pull/799) +- Add peddy --sites hg38 argument when running with GRCh38 [#799](https://github.com/nf-core/raredisease/pull/799) +- Saltshaker for downstream processing of mitochondrial SV calls from MitoSAlt [#775](https://github.com/nf-core/raredisease/pull/775) +- Env variable NXF_SINGULARITY_NEW_PID_NAMESPACE = false to accommodate hisat2 running with latest Nextflow and Singularity [#775](https://github.com/nf-core/raredisease/pull/775) +- Parameter `exclude_alt` to filter alignments to alt/unplaced contigs after alignment using samtools view, retaining only primary chromosomes (GRCh37: 1-22,X,Y,MT / GRCh38: chr1-chr22,chrX,chrY,chrM). Note that enabling this will restrict variant calling to these chromosomes [#803](https://github.com/nf-core/raredisease/pull/803) +- Stub test for all the remaning subworkflows that were lacking it: align_bwa_bwamem2_bwameme, align_MT, align (bwameme - wes), align_sentieon, call_repeat_expansions, prepare_references, qc_bam [#820](https://github.com/nf-core/raredisease/pull/820) +- Parameters `save_all_mapped_as_cram` and `save_noalt_mapped_as_cram` to replace `save_mapped_as_cram`, allowing independent control over publishing unfiltered and alt-filtered alignment files as CRAM [#807](https://github.com/nf-core/raredisease/pull/807) +- Parameter `run_vcfanno_db_sanity_check` to check vcfanno database files for zero records and remove the corresponding annotation blocks from the TOML config before running vcfanno [#821](https://github.com/nf-core/raredisease/pull/821) +- Added `--skip_split_multiallelics` parameter to allow users to skip the `bcftools norm --multiallelics -both` step in SNV calling (DeepVariant and Sentieon), which can cause indel quality degradation in single-interval runs [#823](https://github.com/nf-core/raredisease/pull/823) +- Add find/concatenate step to concatenate saltshaker classification files before creating the html report, so the final report is case-level. [#826](https://github.com/nf-core/raredisease/pull/826) +- Extended vcfanno database sanity check to include extra vcfanno resources (`vcfanno_extra`) alongside the main resources, and moved the check upstream to `raredisease.nf` so it covers both genome and mitochondrial SNV annotation subworkflows [#834](https://github.com/nf-core/raredisease/pull/834) +- Add full test to call_sv_MT subworkflow [#874](https://github.com/nf-core/raredisease/pull/874) + +### `Changed` + +- Use distinct output filenames for bcfools (in call_mobile_elements subworkflow) and svdb (in call_sv_tiddit subworkflow) [#716](https://github.com/nf-core/raredisease/pull/716) +- Use nf-core's most severe consequence & pli scripts instead of local ones [#732](https://github.com/nf-core/raredisease/pull/732) +- Use nf-core's VCF_FILTER_BCFTOOLS_ENSEMBLVEP subworkflow to generate clinical set instead of a local subworkflow [#727](https://github.com/nf-core/raredisease/pull/727) +- Don't call mobile elements in mitochondrial DNA. [#741](https://github.com/nf-core/raredisease/pull/741) +- Call SVs in mitochondria using mitochondrial alignments in the genome alignment files instead of from BAM files generated by the mitochondrial subworkflow. [#742](https://github.com/nf-core/raredisease/pull/742) +- Update gens-preproc script [#747](https://github.com/nf-core/raredisease/pull/747) +- Removed parameter `bwa_as_fallback` [#763](https://github.com/nf-core/raredisease/pull/763) +- Sambamba depth now filters on not duplicates and not failed_quality_control [#768](https://github.com/nf-core/raredisease/pull/768) +- Removed eKLIPse [#743](https://github.com/nf-core/raredisease/pull/743) +- Removed haplocheck [#778](https://github.com/nf-core/raredisease/pull/778) +- Removed HmtNote [#779](https://github.com/nf-core/raredisease/pull/779) +- Updated svbd module [#781](https://github.com/nf-core/raredisease/pull/781) +- Migrate file publishing from publishDir to a centralized output {} block for some workflows [#784](https://github.com/nf-core/raredisease/pull/784) +- Replace local gens module with nf-core module [#785](https://github.com/nf-core/raredisease/pull/785) +- Migrate file publishing from publishDir to a centralized output {} block for some workflows [#787](https://github.com/nf-core/raredisease/pull/787) +- Migrate file publishing from publishDir to a centralized output {} block for some workflows [#788](https://github.com/nf-core/raredisease/pull/788) +- Migrate file publishing from publishDir to a centralized output {} block for some workflows [#789](https://github.com/nf-core/raredisease/pull/789) +- Remove redundant TABIX processes, and update configs for nf-test [#790](https://github.com/nf-core/raredisease/pull/790) +- Migrate file publishing from publishDir to a centralized output {} block for some workflows [#791](https://github.com/nf-core/raredisease/pull/791) +- Remove redundant ZIP_TABIX steps after VCFANNO in annotate_genome_snvs and annotate_mt_snvs by using VCFANNO's direct tbi output [#799](https://github.com/nf-core/raredisease/pull/799) +- Collect genome fasta/fai channel in call_sv_tiddit to prevent per-sample re-emission [#799](https://github.com/nf-core/raredisease/pull/799) +- Update cadd_resources channel to use channelFromPathWithMeta and set channelFromSamplesheet calls for svdb/ME resources as non-mandatory [#799](https://github.com/nf-core/raredisease/pull/799) +- Run MitoSAlt.pl from bin rather than within container [#775](https://github.com/nf-core/raredisease/pull/775) +- Include mitochonrdial SV calls in combined SV vcf, change call_sv output directory structure to remove mitochondria/ and genome/ [#775](https://github.com/nf-core/raredisease/pull/775) +- Remove Qualimap and Haplogrep3 as they were made redundant by Picard and VerifyBamID2 [#801](https://github.com/nf-core/raredisease/pull/801) +- Remove env variable NXF_SINGULARITY_NEW_PID_NAMESPACE from the config since this has to be set outside the subworkflow [#804](https://github.com/nf-core/raredisease/pull/804) +- Run UPD_SITES, UPD_REGIONS, and CHROMOGRAPH for UPD only when analysis type is WGS [#806](https://github.com/nf-core/raredisease/pull/806) +- Change saltshaker classification output from txt to html [#808](https://github.com/nf-core/raredisease/pull/808) +- Sort parameters of `CALL_STRUCTURAL_VARIANTS` and `CALL_SV_MANTA` alphabetically [#821](https://github.com/nf-core/raredisease/pull/821) + +### `Fixed` + +- Fixed argument order of `ch_genome_fai` and `ch_genome_fasta` in the `CALL_SNV_SENTIEON` subworkflow [#811](https://github.com/nf-core/raredisease/pull/811) +- Ensure deterministic sample ordering in Manta SV output by sorting BAM/BAI channel inputs [#815](https://github.com/nf-core/raredisease/pull/815) +- Fixed inconsistencies in JSON schema [#714](https://github.com/nf-core/raredisease/pull/714) +- Fixed conda declaration in the add_varcallername_to_bed module [#733](https://github.com/nf-core/raredisease/pull/733) +- Fixed CADD annotation to support chr prefix [#745](https://github.com/nf-core/raredisease/pull/745) +- Fixed mismatch between VCF and ROH calls when analysing multiple samples [#755](https://github.com/nf-core/raredisease/pull/755) +- Fixed pipeline to run variant calling even with bait_padding set to 0 [#757](https://github.com/nf-core/raredisease/pull/757) +- Fixed mitosalt channel handling so it runs on all samples in a trio [#826](https://github.com/nf-core/raredisease/pull/826) +- Fixed runtime errors in `call_sv_MT` and `call_structural_variants` when MitoSAlt produces no structural variant calls [#837](https://github.com/nf-core/raredisease/pull/837) +- Fixed vcfanno sanity check map closure to handle `ch_vcfanno_resources` emitting a list of paths [#837](https://github.com/nf-core/raredisease/pull/837) +- Fixed `PREP_MITOSALT` msconfig output being consumed as a queue channel by converting it to a value channel with `.collect()` before passing to `MITOSALT` [#837](https://github.com/nf-core/raredisease/pull/843) + +### Parameters + +| Old parameter | New parameter | +| ------------------- | --------------------------- | +| | sambamba_regions | +| bwa_as_fallback | | +| | multiqc_samples | +| | homoplasmy_af_threshold | +| | exclude_alt | +| save_mapped_as_cram | | +| | save_all_mapped_as_cram | +| | save_noalt_mapped_as_cram | +| | run_vcfanno_db_sanity_check | +| | skip_split_multiallelics | + +### Tool updates + +| Tool | Old version | New version | +| --------------------- | ----------- | ----------- | +| bcftools | 1.20 | 1.21 | +| bwa | 0.7.18 | 0.7.19 | +| deepvariant | 1.8.0 | 1.9.0 | +| eKLIPse | 1.8 | | +| ensemblvep/vep | 110 | 110.1 | +| ensemblvep/filtervep | 113 | 115.2 | +| fastp | 0.23.4 | 1.0.1 | +| gatk4 | 4.5.0.0 | 4.6.2.0 | +| gawk | 5.3.0 | 5.3.1 | +| genmod | 3.9 | 3.10.2 | +| gens-preproc | 1.0.11 | | +| gens/preparecovandbaf | | 1.1.5 | +| haplocheck | 1.3.3 | | +| haplogrep3 | 3.2.2 | | +| hmtnote | 0.7.2 | | +| htslib | 1.20 | 1.21 | +| MitoSalt | | 1.1.1 | +| mosdepth | 0.3.8 | 0.3.11 | +| multiqc | 1.32 | 1.33 | +| ngsbits | 202411 | 202512 | +| picard | 3.3.0 | 3.4.0 | +| pigz | 2.3.4 | 2.8 | +| qualimap | 2.3 | | +| sambamba | | 1.0.1 | +| samtools | 1.21 | 1.22.1 | +| sentieon | 202503 | 202503.02 | +| stranger | 0.9.4 | 0.10.0 | +| svdb | 2.8.3 | 2.8.4 | +| tiddit | 3.6.1 | 3.9.5 | +| ucsc | 447 | 482 | +| vcfanno | 0.3.5 | 0.3.7 | +| vcf2cytosure | 0.9.1 | 0.9.3 | + ## 2.6.0 - Cacofonix [2025-06-25] ### `Added` diff --git a/CITATIONS.md b/CITATIONS.md index bd5c97d4f..854af10d4 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -42,9 +42,7 @@ > Poplin R, Chang PC, Alexander D, et al. A universal SNP and small-indel variant caller using deep neural networks. Nat Biotechnol. 2018;36(10):983-987. doi:10.1038/nbt.4235 -- [eKLIPse](https://www.nature.com/articles/s41436-018-0350-8) - - > Goudenège D, Bris C, Hoffmann V, et al. eKLIPse: a sensitive tool for the detection and quantification of mitochondrial DNA deletions from next-generation sequencing data. Genet Med 21, 1407–1416 (2019). doi:10.1038/s41436-018-0350-8 +- [Chromograph](https://github.com/Clinical-Genomics/chromograph) - [Ensembl VEP](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-016-0974-4) @@ -76,22 +74,14 @@ > Yun T, Li H, Chang PC, Lin MF, Carroll A, McLean CY. Accurate, scalable cohort variant calls using DeepVariant and GLnexus. Robinson P, ed. Bioinformatics. 2021;36(24):5582-5589. doi:10.1093/bioinformatics/btaa1081 -- [Haplocheck](https://genome.cshlp.org/content/31/2/309.long) - - > Weissensteiner H, Forer L, Fendt L, et al. Contamination detection in sequencing studies using the mitochondrial phylogeny. Genome Res. 2021;31(2):309-316. doi:10.1101/gr.256545.119 - -- [HaploGrep 2](https://academic.oup.com/nar/article/44/W1/W58/2499296) - - > Weissensteiner H, Pacher D, Kloss-Brandstätter A, et al. HaploGrep 2: mitochondrial haplogroup classification in the era of high-throughput sequencing. Nucleic Acids Res. 2016;44(W1):W58-W63. doi:10.1093/nar/gkw233 - -- [Hmtnote](https://doi.org/10.1101/600619) - - > Preste R, Clima R, Attimonelli M. Human mitochondrial variant annotation with HmtNote. bioRxiv 600619; doi:10.1101/600619 - - [Manta](https://academic.oup.com/bioinformatics/article/32/8/1220/1743909?login=true) > Chen X, Schulz-Trieglaff O, Shaw R, et al. Manta: rapid detection of structural variants and indels for germline and cancer sequencing applications. Bioinformatics. 2016;32(8):1220-1222. doi:10.1093/bioinformatics/btv710 +- [Mitosalt](https://sourceforge.net/projects/mitosalt/) + + > Basu S, Xie X, Uhler JP, et al. Accurate mapping of mitochondrial DNA deletions and duplications using deep sequencing. PLoS Genet. 2020;16(12):e1009242. doi: 10.1371/journal.pgen.1009242 + - [Mosdepth](https://academic.oup.com/bioinformatics/article/34/5/867/4583630?login=true) > Pedersen BS, Quinlan AR. Mosdepth: quick coverage calculation for genomes and exomes. Hancock J, ed. Bioinformatics. 2018;34(5):867-868. doi:10.1093/bioinformatics/btx699 @@ -108,10 +98,6 @@ - [Picard](https://broadinstitute.github.io/picard/) -- [Qualimap](https://academic.oup.com/bioinformatics/article/32/2/292/1744356?login=true) - - > Okonechnikov K, Conesa A, García-Alcalde F. Qualimap 2: advanced multi-sample quality control for high-throughput sequencing data. Bioinformatics. 2016;32(2):292-294. doi:10.1093/bioinformatics/btv566 - - [RetroSeq](https://academic.oup.com/bioinformatics/article/29/3/389/257479) > Thomas M. Keane, Kim Wong, David J. Adams, RetroSeq: transposable element discovery from next-generation sequencing data. Bioinformatics.2013 Feb 1;29(3):389-90. doi: 10.1093/bioinformatics/bts697 @@ -122,6 +108,12 @@ > John G. Cleary, Ross Braithwaite, Kurt Gaastra, Brian S. Hilbush, Stuart Inglis, Sean A. Irvine, Alan Jackson, Richard Littin, Mehul Rathod, David Ware, Justin M. Zook, Len Trigg, and Francisco M. De La Vega. "Comparing Variant Call Files for Performance Benchmarking of Next-Generation Sequencing Variant Calling Pipelines." bioRxiv, 2015. doi:10.1101/023754. +- [saltshaker](https://gitlab.com/genomedx/annotation/saltshaker) + +- [Sambamba](https://academic.oup.com/bioinformatics/article/31/12/2032/213831) + + > Tarasov A, Vilella AJ, Cuppen E, Nijman IJ, Prins P. Sambamba: fast processing of NGS alignment formats. Bioinformatics. 2015;31(12):2032-2034. doi:10.1093/bioinformatics/btv098 + - [Sentieon DNAscope](https://www.biorxiv.org/content/10.1101/2022.05.20.492556v1.abstract) > Freed D, Pan R, Chen H, Li Z, Hu J, Aldana R. DNAscope: High Accuracy Small Variant Calling Using Machine Learning. Bioinformatics; 2022. doi:10.1101/2022.05.20.492556 @@ -134,6 +126,10 @@ > Chen X, Sanchis-Juan A, French CE, Connel AJ, Delon I, Kingsbury Z, Chawla A, Halpern AL, Taft RJ, NIHR BioResource, Bentley DR, Butchbach MER, Raymond FL, Eberle MA. Spinal muscular atrophy diagnosis and carrier screening from genome sequencing data. Genet Med. February 2020:1-9. doi:10.1038/s41436-020-0754-0 +- [Spring](https://academic.oup.com/bioinformatics/article/35/15/2674/5232998) + + > Chandak S, Tatwawadi K, Ochoa I, Hernaez M, Weissman T. SPRING: a next-generation compressor for FASTQ data. Bioinformatics. 2019;35(15):2674-2676. doi:10.1093/bioinformatics/bty1015 + - [stranger](https://github.com/Clinical-Genomics/stranger) > Nilsson D, Magnusson M. moonso/stranger v0.7.1. Published online February 18, 2021. doi:10.5281/ZENODO.4548873 @@ -150,6 +146,8 @@ > Eisfeldt J, Vezzi F, Olason P, Nilsson D, Lindstrand A. TIDDIT, an efficient and comprehensive structural variant caller for massive parallel sequencing data. F1000Res. 2017;6:664. doi:10.12688/f1000research.11168.2 +- [UPD](https://github.com/bjhall/upd) + - [UCSC Bigwig and Bigbed](https://academic.oup.com/bioinformatics/article/26/17/2204/199001?login=true) > Kent WJ, Zweig AS, Barber G, Hinrichs AS, Karolchik D. BigWig and BigBed: enabling browsing of large distributed datasets. Bioinformatics. 2010;26(17):2204-2207. doi:10.1093/bioinformatics/btq351 @@ -160,7 +158,7 @@ > Pedersen BS, Layer RM, Quinlan AR. Vcfanno: fast, flexible annotation of genetic variants. Genome Biol. 2016;17(1):118. doi:10.1186/s13059-016-0973-5 -- [VerifyBamID2]() +- [VerifyBamID2](https://genome.cshlp.org/content/30/2/185) > Zhang F, Flickinger M, Taliun SAG, Consortium IPG, Abecasis GR, Scott LJ, McCaroll SA, Pato CN, Boehnke M, & Kang HM. (2020). Ancestry-agnostic estimation of DNA sample contamination from sequence reads. Genome Research, 30(2), 185–194. https://doi.org/10.1101/gr.246934.118 diff --git a/README.md b/README.md index c0f261ecc..8cdfe1045 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ -[![GitHub Actions CI Status](https://github.com/nf-core/raredisease/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/ci.yml) - +[![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/raredisease) +[![GitHub Actions CI Status](https://github.com/nf-core/raredisease/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/nf-test.yml) [![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) [![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/) -[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.1) +[![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/) @@ -48,38 +48,52 @@ On release, automated continuous integration tests run the pipeline on a full-si nf-core/raredisease workflow -**1. Metrics:** +**1. Preprocessing:** + +- [fastp](https://github.com/OpenGene/fastp) +- [Spring](https://github.com/shubhamchandak94/Spring) + +**2. Alignment:** + +- [Bwa-mem2](https://github.com/bwa-mem2/bwa-mem2) +- [BWA-MEME](https://github.com/kaist-ina/BWA-MEME) +- [BWA](https://github.com/lh3/bwa) +- [Sentieon DNAseq](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/) + +**3. Metrics:** - [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) - [Mosdepth](https://github.com/brentp/mosdepth) - [MultiQC](http://multiqc.info/) -- [Picard's CollectMutipleMetrics, CollectHsMetrics, and CollectWgsMetrics](https://broadinstitute.github.io/picard/) -- [Qualimap](http://qualimap.conesalab.org/) +- [Picard's CollectMultipleMetrics, CollectHsMetrics, and CollectWgsMetrics](https://broadinstitute.github.io/picard/) +- [Sambamba](https://github.com/biod/sambamba) - [Sentieon's WgsMetricsAlgo](https://support.sentieon.com/manual/usages/general/) - [TIDDIT's cov](https://github.com/J35P312/) - [VerifyBamID2](https://github.com/Griffan/VerifyBamID) -**2. Alignment:** +**4. Sex check:** -- [Bwa-mem2](https://github.com/bwa-mem2/bwa-mem2) -- [BWA-MEME](https://github.com/kaist-ina/BWA-MEME) -- [BWA](https://github.com/lh3/bwa) -- [Sentieon DNAseq](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/) +- [NGSbits SampleGender](https://github.com/imgag/ngs-bits) +- [Peddy](https://github.com/brentp/peddy) -**3. Variant calling - SNV:** +**5. Variant calling - SNV:** - [DeepVariant](https://github.com/google/deepvariant) - [Sentieon DNAscope](https://support.sentieon.com/manual/DNAscope_usage/dnascope/) -**4. Variant calling - SV:** +**6. Variant calling - SV:** - [Manta](https://github.com/Illumina/manta) - [TIDDIT's sv](https://github.com/SciLifeLab/TIDDIT) - Copy number variant calling: - [CNVnator](https://github.com/abyzovlab/CNVnator) - [GATK GermlineCNVCaller](https://github.com/broadinstitute/gatk) + - [SMNCopyNumberCaller](https://github.com/Illumina/SMNCopyNumberCaller) +- Mitochondrial SV calling: + - [MitoSAlt](https://mitosalt.sourceforge.io/) + - [Saltshaker](https://gitlab.com/genomedx/annotation/saltshaker) -**5. Annotation - SNV:** +**7. Annotation - SNV:** - [bcftools roh](https://samtools.github.io/bcftools/bcftools.html#roh) - [vcfanno](https://github.com/brentp/vcfanno) @@ -88,36 +102,33 @@ On release, automated continuous integration tests run the pipeline on a full-si - [UPD](https://github.com/bjhall/upd) - [Chromograph](https://github.com/Clinical-Genomics/chromograph) -**6. Annotation - SV:** +**8. Annotation - SV:** - [SVDB query](https://github.com/J35P312/SVDB#Query) - [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html) -**7. Mitochondrial analysis:** +**9. Mitochondrial analysis:** - [Alignment and variant calling - GATK Mitochondrial short variant discovery pipeline ](https://gatk.broadinstitute.org/hc/en-us/articles/4403870837275-Mitochondrial-short-variant-discovery-SNVs-Indels-) -- [eKLIPse](https://github.com/dooguypapua/eKLIPse/tree/master) - Annotation: - - [HaploGrep2](https://github.com/seppinho/haplogrep-cmd) - - [Hmtnote](https://github.com/robertopreste/HmtNote) - [vcfanno](https://github.com/brentp/vcfanno) - [CADD](https://cadd.gs.washington.edu/) - [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html) -**8. Variant calling - repeat expansions:** +**10. Variant calling - repeat expansions:** - [Expansion Hunter](https://github.com/Illumina/ExpansionHunter) - [Stranger](https://github.com/Clinical-Genomics/stranger) -**9. Variant calling - mobile elements:** +**11. Variant calling - mobile elements:** - [RetroSeq](https://github.com/tk2/RetroSeq) -**10. Rank variants - SV and SNV:** +**12. Rank variants - SV and SNV:** - [GENMOD](https://github.com/Clinical-Genomics/genmod) -**11. Variant evaluation:** +**13. Variant evaluation:** - [RTG Tools](https://github.com/RealTimeGenomics/rtg-tools) @@ -126,7 +137,7 @@ Note that it is possible to include/exclude certain tools or 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: @@ -151,7 +162,7 @@ nextflow run nf-core/raredisease \ ``` > [!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/raredisease/usage) and the [parameter documentation](https://nf-co.re/raredisease/parameters). @@ -170,7 +181,7 @@ We thank the nf-core community for their extensive assistance in the development ## 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 `#raredisease` channel](https://nfcore.slack.com/channels/raredisease) (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 cf30cdad4..000000000 --- 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/raredisease v${version} - ${runName}", - "wrap": true - }, - { - "type": "TextBlock", - "spacing": "None", - "text": "Completed at ${dateComplete} (duration: ${duration})", - "isSubtle": true, - "wrap": true - }, - { - "type": "TextBlock", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors. The full error message was: ${errorReport}.<% } %>", - "wrap": true - }, - { - "type": "TextBlock", - "text": "The command used to launch the workflow was as follows:", - "wrap": true - }, - { - "type": "TextBlock", - "text": "${commandLine}", - "isSubtle": true, - "wrap": true - } - ], - "actions": [ - { - "type": "Action.ShowCard", - "title": "Pipeline Configuration", - "card": { - "type": "AdaptiveCard", - "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "body": [ - { - "type": "FactSet", - "facts": [<% out << summary.collect{ k,v -> "{\"title\": \"$k\", \"value\" : \"$v\"}"}.join(",\n") %> - ] - } - ] - } - } - ] - } - } - ] -} diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 98820ad71..d76c55b48 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -2,10 +2,7 @@ custom_logo: "nf-core-raredisease_logo_light.png" custom_logo_url: https://github.com/nf-core/raredisease/ custom_logo_title: "nf-core/raredisease" report_comment: > - This report has been generated by the nf-core/raredisease analysis pipeline. For information about - how to interpret these results, please see the documentation. + This report has been generated by the nf-core/raredisease analysis pipeline. For information about how to interpret these results, please see the documentation. report_section_order: "nf-core-raredisease-methods-description": @@ -14,21 +11,18 @@ report_section_order: order: -1001 "nf-core-raredisease-summary": order: -1002 - + gatk_contamination: + order: 1050 export_plots: true - run_modules: - fastqc - fastp - - haplocheck - - qualimap - picard - mosdepth - ngsbits - peddy - verifybamid - custom_content - module_order: - fastqc: name: "FastQC" @@ -36,14 +30,10 @@ module_order: - "*.zip" - picard: name: "Picard" - - qualimap: - name: "Qualimap" - fastp: name: "fastp" - mosdepth: name: "Mosdepth" - - haplocheck: - name: "haplocheck" - ngsbits: name: "ngsbits" - peddy: @@ -51,9 +41,59 @@ module_order: - verifybamid: name: "VerifyBamID2" +# Custom content configuration for GATK contamination +custom_data: + gatk_contamination: + id: "gatk_contamination" + section_name: "GATK Contamination" + description: "Sample contamination estimates from GATK CalculateContamination based on common variant allele frequencies" + plot_type: "generalstats" + pconfig: + contamination_pct: + title: "Contamination" + description: "Estimated sample contamination percentage" + max: 10 + min: 0 + scale: "RdYlGn-rev" + suffix: "%" + format: "{:,.2f}" + shared_key: "contamination" + +# Make contamination visible in general stats by default +table_columns_visible: + gatk_contamination: + contamination_pct: true + +# Color coding thresholds for contamination +table_cond_formatting_rules: + contamination_pct: + pass: + - s_eq: "pass" + - lt: 2.0 + warn: + - s_eq: "warn" + - lt: 5.0 + - gte: 2.0 + fail: + - s_eq: "fail" + - gte: 5.0 + +# Add to General Statistics table configuration +table_columns_placement: + gatk_contamination: + contamination_pct: 900 + extra_fn_clean_exts: - "_sorted_md" + - "_contamination" + - "_pileups" + - "_mosdepth" + - "_sorted" - type: regex pattern: "_LNUMBER[0-9]{1,}" +table_sample_merge: + "(R1)": "_1" + "(R2)": "_2" + disable_version_detection: true diff --git a/assets/rtg_truthvcfs_schema.json b/assets/rtg_truthvcfs_schema.json index e0630455a..5695ad566 100644 --- a/assets/rtg_truthvcfs_schema.json +++ b/assets/rtg_truthvcfs_schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/mobile_element_references_schema.json", + "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/rtg_truthvcfs_schema.json", "title": "Schema for RTGTOOLS/VCFEVAL VCFs", "description": "Schema for the vcfeval's vcf input", "type": "array", diff --git a/assets/sample_id_map.json b/assets/sample_id_map.json index c69fa645e..ffe19f809 100644 --- a/assets/sample_id_map.json +++ b/assets/sample_id_map.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/mobile_element_references_schema.json", + "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/sample_id_map.json", "title": "Schema for customerid_internalid_map", "description": "Schema for the file provided with params.customerid_internalid_map", "type": "array", @@ -8,13 +8,27 @@ "type": "object", "properties": { "customer_id": { - "type": "string", - "pattern": "^\\S+$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string", + "pattern": "^\\S+$" + } + ], "errorMessage": "Customer id cannot contain spaces" }, "internal_id": { - "type": "string", - "pattern": "^\\S+$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string", + "pattern": "^\\S+$" + } + ], "errorMessage": "Internal id cannot contain spaces", "meta": ["id"] } diff --git a/assets/schema_input.json b/assets/schema_input.json index 08f832334..902e67881 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -14,7 +14,7 @@ "errorMessage": "Sample name must be provided and must be a string that cannot contain spaces" }, "lane": { - "oneOf": [ + "anyOf": [ { "type": "integer" }, @@ -27,18 +27,18 @@ "errorMessage": "Lane must be an interger or a string that cannot contain spaces" }, "fastq_1": { - "errorMessage": "Gzipped FastQ file for reads 1 must be provided, has to exist, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'", "type": "string", - "pattern": "^\\S+\\.f(ast)?q\\.gz$", "format": "file-path", - "exists": true + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$" }, "fastq_2": { - "errorMessage": "Gzipped FastQ file for reads 2, has to exist, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'", "type": "string", - "pattern": "^\\S+\\.f(ast)?q\\.gz$", "format": "file-path", - "exists": true + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$" }, "spring_1": { "errorMessage": "Gzipped and spring-compressed FastQ file for reads 1 cannot contain spaces, has to exist and must have extension '.spring'", @@ -69,7 +69,7 @@ "exists": true }, "sex": { - "oneOf": [ + "anyOf": [ { "type": "integer", "enum": [0, 1, 2] diff --git a/assets/slackreport.json b/assets/slackreport.json deleted file mode 100644 index 84f87e9bd..000000000 --- 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/raredisease ${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/svdb_query_bedpe_schema.json b/assets/svdb_query_bedpe_schema.json index b220bce5b..a9fbedbe8 100644 --- a/assets/svdb_query_bedpe_schema.json +++ b/assets/svdb_query_bedpe_schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/mobile_element_references_schema.json", + "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/svdb_query_bedpe_schema.json", "title": "Schema for SVDB query - BEDPE", "description": "Schema for the SVDB query database input, bedpe version", "type": "array", diff --git a/assets/svdb_query_vcf_schema.json b/assets/svdb_query_vcf_schema.json index a927a1f38..1176fccf0 100644 --- a/assets/svdb_query_vcf_schema.json +++ b/assets/svdb_query_vcf_schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/mobile_element_references_schema.json", + "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/svdb_query_vcf_schema.json", "title": "Schema for SVDB query - VCF", "description": "Schema for the SVDB query database input, VCF version", "type": "array", diff --git a/assets/vep_plugin_files_schema.json b/assets/vep_plugin_files_schema.json index 34fe41983..65ba49342 100644 --- a/assets/vep_plugin_files_schema.json +++ b/assets/vep_plugin_files_schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/mobile_element_references_schema.json", + "$id": "https://raw.githubusercontent.com/nf-core/raredisease/master/assets/vep_plugin_files_schema.json", "title": "Schema for VEP plugin files and their indices", "description": "Schema for VEP plugin files and their indices", "type": "array", diff --git a/bin/MitoSAlt1.1.1.pl b/bin/MitoSAlt1.1.1.pl new file mode 100755 index 000000000..bbaf37d9b --- /dev/null +++ b/bin/MitoSAlt1.1.1.pl @@ -0,0 +1,1035 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use List::Util qw(first min max sum); +use Data::Dumper; + +#INPUT +my $config_file = $ARGV[0]; +my $p1 = $ARGV[1]; +my $p2 = $ARGV[2]; +my $tag = $ARGV[3]; + +#LOG +open (STDOUT, "| tee -ai log/$tag.log"); + +my $usage = "usage: perl mitopoint.pl "; +die "Configuration file missing, $usage" unless $config_file; +die "Pair 1 file missing, $usage" unless $p1; +die "Pair 2 file missing, $usage" unless $p2; +die "Study name not given, $usage" unless $tag; + +die "check path to fastq 1, script exit.\n" unless -e $p1; +die "check path to fastq 2, script exit.\n" unless -e $p2; + + +#LOAD CONFIGURATION FILE +open(CONFIG, "<$config_file"); +my $User_Preferences; +while () { + chomp; # no newline + s/#.*//; # no comments + s/^\s+//; # no leading white + s/\s+$//; # no trailing white + next unless length; # anything left? + my ($var, $value) = split(/\s*=\s*/, $_, 2); + $User_Preferences->{$var} = $value; + my $line = $_; + print $line."\n"; +} + +#PROGRAMS +my $hisat2 = $User_Preferences->{hisat2}; +my $lastal = $User_Preferences->{lastal}; +my $lastsp = $User_Preferences->{lastsp}; +my $mfcv = $User_Preferences->{mfcv}; +my $b2fq = $User_Preferences->{b2fq}; +my $reformat = $User_Preferences->{reformat}; +my $samtools = $User_Preferences->{samtools}; +my $sambamba = $User_Preferences->{sambamba}; +my $gcov = $User_Preferences->{gcov}; +my $intersectBed = $User_Preferences->{intersectBed}; +my $sortBed = $User_Preferences->{sortBed}; +my $clusterBed = $User_Preferences->{clusterBed}; +my $randomBed = $User_Preferences->{randomBed}; +my $groupBy = $User_Preferences->{groupBy}; +my $bg2bw = $User_Preferences->{bg2bw}; + +#DATABASES +my $hsindex = $User_Preferences->{hsindex}; +my $faindex = $User_Preferences->{faindex}; +my $lastindex = $User_Preferences->{lastindex}; +my $mtfaindex = $User_Preferences->{mtfaindex}; +my $gsize = $User_Preferences->{gsize}; +my $MT_fasta = $User_Preferences->{MT_fasta}; + +#COMPUTATION +my $threads = $User_Preferences->{threads}; + +#MITOCHONDRIA FEATURES +my $refchr = $User_Preferences->{refchr}; +my $msize = $User_Preferences->{msize}; +my $orihs = $User_Preferences->{orihs}; +my $orihe = $User_Preferences->{orihe}; +my $orils = $User_Preferences->{orils}; +my $orile = $User_Preferences->{orile}; +my $exclude = $User_Preferences->{exclude}; +my $dloop1 = $exclude; +my $dloop2 = $msize - $exclude; +my $hash; + +#SCORING AND FILTERING FEATURES +my $score_threshold = $User_Preferences->{score_threshold}; +my $evalue_threshold = $User_Preferences->{evalue_threshold}; +my $split_length = $User_Preferences->{split_length}; +my $paired_distance = $User_Preferences->{paired_distance}; +my $deletion_threshold_min = $User_Preferences->{deletion_threshold_min}; +my $deletion_threshold_max = $User_Preferences->{deletion_threshold_max}; +my $breakthreshold = $User_Preferences->{breakthreshold}; +my $cluster_threshold = $User_Preferences->{cluster_threshold}; +my $breakspan = $User_Preferences->{breakspan}; +my $sizelimit = $User_Preferences->{sizelimit}; +my $hplimit = $User_Preferences->{hplimit}; +my $flank = $User_Preferences->{flank}; +my $split_distance_threshold = $User_Preferences->{split_distance_threshold}; + +#STEPS +my $dna = $User_Preferences->{dna}; #USE SPECIFIC HISAT PARAMETERS FOR DNA AND RNA SEQUENCING +my $enriched = $User_Preferences->{enriched}; #IF THE SEQUENCING IS MITOCHONDRIAL DNA ENRICHED THEN SKIP THE INITIAL NUCLEAR GENOME ALIGNMENT STEP +my $nu_mt = $User_Preferences->{nu_mt}; #MAPPING TO NUCLEAR AND MITOCHONDRIAL GENOME WITH BOWTIE2 +my $rmtmp = $User_Preferences->{rmtmp}; #REMOVE TEMPORARY FILES +my $o_mt = $User_Preferences->{o_mt}; #MITOCHONDRIAL READ EXTRACTION AND REMAPPING TO ONLY MITOCHONDRIAL GENOME WITH LASTAL +my $i_del = $User_Preferences->{i_del}; #IDENTIFICATION AND CLUSTERING OF DELETIONS/DUPLICATIONS +my $cn_mt = $User_Preferences->{cn_mt}; #ESTIMATION OF MT DNA COPY NUMBER + +#EXIT IF THE CONFIGURATION STEPS DO NOT MATCH +if(($nu_mt eq 'yes' && $enriched eq 'yes')||($nu_mt eq 'no' && $o_mt eq 'no' && $i_del eq 'no')||($cn_mt eq 'yes' && $nu_mt eq 'no')||($cn_mt eq 'yes' && $o_mt eq 'no')||($i_del eq 'yes' && $o_mt eq 'no' && $nu_mt eq 'yes')){ + print scalar(localtime).": Check config file for correct STEP combination\n"; + die; +} + +#MAP TO NU+MT GENOME +if($nu_mt eq 'yes' && $enriched eq 'no'){ + print scalar(localtime).": Map to NU+MT genome\n"; + if($dna eq 'yes'){system("$hisat2 -p $threads -x $hsindex --no-temp-splicesite --no-spliced-alignment --max-intronlen 5000 -1 $p1 -2 $p2 -S tmp_$tag.sam 2>> log/$tag.log");} + if($dna eq 'no'){system("$hisat2 -p $threads -x $hsindex -1 $p1 -2 $p2 -S tmp_$tag.sam 2>> log/$tag.log");} + + #EXTRACT READS + print scalar(localtime).": Extract reads\n"; + system("$samtools view -@ $threads -bt $faindex tmp_$tag.sam|$samtools sort -@ $threads -o tmp_$tag.bam -"); + system("$samtools index tmp_$tag.bam"); + system("$samtools idxstats tmp_$tag.bam > indel/$tag.count.txt"); + system("$samtools view -u -@ $threads -f 12 tmp_$tag.bam > tmp1_$tag.bam"); #flag to extract unmapped reads with mate also unmapped + system("$samtools view -u -@ $threads tmp_$tag.bam $refchr> tmp2_$tag.bam"); + system("$samtools merge -@ $threads tmp_final_$tag.bam tmp1_$tag.bam tmp2_$tag.bam"); + + #EXTRACT FASTQ + print scalar(localtime).": Create FASTQ\n"; + system("$samtools fastq tmp_final_$tag.bam > tmp_$tag.fq"); #ADDS PAIR /1, /2 TO THE READ NAMES HENCE BBMAP REFORMAT NOT REQUIRED + #system("$reformat in=tmp.fq out=tmp1.fq overwrite=true -uniquenames -Xmx100g &>> log/$tag.log"); +} + +if($nu_mt eq 'yes' && $o_mt eq 'yes' && $enriched eq 'no'){ + #REMAP ON MT GENOME + print scalar(localtime).": Map to MT genome\n"; + system("$lastal -Q1 -e80 -P$threads $lastindex tmp_$tag.fq|$lastsp > tmp_$tag.maf"); + system("$mfcv sam -d tmp_$tag.maf|$samtools view -@ $threads -bt $mtfaindex -|$samtools sort -@ $threads -o bam/$tag.bam -"); + system("$samtools index bam/$tag.bam"); + system("$mfcv tab tmp_$tag.maf > tab/$tag.tab"); + + #COMPRESS TAB + system("gzip -f tab/$tag.tab"); + + #GENERATE BIGWIG + print scalar(localtime).": Generate Bigwig\n"; + system("$gcov -split -ibam bam/$tag.bam -bg|sort -k1,1 -k2,2n > tmp_$tag.bg"); + system("$bg2bw tmp_$tag.bg $mtfaindex bw/$tag.bw"); + #unlink("tmp_$tag.bg"); +} + +if($nu_mt eq 'no' && $o_mt eq 'yes' && $enriched eq 'yes'){ + #REMAP ON MT GENOME + print scalar(localtime).": Map to MT genome\n"; + system("$reformat in=$p1 in2=$p2 out=tmp_$tag.fq overwrite=true addslash=t trimreaddescription=t spaceslash=f -Xmx100g 2>> log/$tag.log"); + system("$lastal -Q1 -e80 -P$threads $lastindex tmp_$tag.fq|$lastsp > tmp_$tag.maf"); + system("$mfcv sam -d tmp_$tag.maf|$samtools view -@ $threads -bt $mtfaindex -|$samtools sort -@ $threads -o bam/$tag.bam -"); + system("$samtools index bam/$tag.bam"); + system("$mfcv tab tmp_$tag.maf > tab/$tag.tab"); + + #COMPRESS TAB + system("gzip -f tab/$tag.tab"); + + #GENERATE BIGWIG + print scalar(localtime).": Generate Bigwig\n"; + system("$gcov -split -ibam bam/$tag.bam -bg|sort -k1,1 -k2,2n > tmp_$tag.bg"); + system("$bg2bw tmp_$tag.bg $mtfaindex bw/$tag.bw"); + #unlink("tmp_$tag.bg"); +} + +if($cn_mt eq 'yes' && $enriched eq 'no' && $o_mt eq 'yes' && $nu_mt eq 'yes'){ + system("$sambamba depth window -w $msize bam/$tag.bam|cut -f 1,5 > indel/$tag.cnmt.txt"); + system("$randomBed -l 1000 -n 3000 -g $gsize > tmp_random_$tag.bed"); + system("$sambamba depth region -L tmp_random_$tag.bed -t $threads -o tmp_random_$tag.cov tmp_$tag.bam"); + system("$groupBy -g 5 -c 8 -o mean -i tmp_random_$tag.cov >> indel/$tag.cnmt.txt"); +} + +#IDENTIFY DELETIONS/DUPLICATIONS +if($i_del eq 'yes'){ + my $infile = "tab/$tag.tab"; + my $bedfile = "indel/$tag.bed"; + my $breakpointfile = "indel/$tag.breakpoint"; + my $clusterfile = "indel/$tag.cluster"; + + my $check_paired = &check_paired($infile); + print scalar(localtime).": Build split read hash\n"; + $hash = &build_hash($infile,$check_paired); + &remove_duplicates(); + + print scalar(localtime).": Generate non-split read BED\n"; + my $nosplitbed_file = &print_bed($hash,$tag,$refchr); + + print scalar(localtime).": Process hash to get best deletion/duplication candidates\n"; + my $delhash = &process_hash($hash,$bedfile,$breakpointfile,$msize,$tag); + + print scalar(localtime).": Build split read clusters\n"; + my $clusterhash = &get_cluster($delhash,$breakthreshold,$tag); + + print scalar(localtime).": Generate and print results\n"; + my $clustercount = &build_results($hash,$clusterhash,$infile,$refchr,$cluster_threshold,$tag); + &print_result($clustercount,$clusterfile); + + #PLOT DELETIONS + print scalar(localtime).":Plot deletions/duplications\n"; + system("R CMD BATCH --no-save --no-restore \'--args $msize $orihs $orihe $orils $orile $sizelimit indel/$tag.cluster indel/$tag.breakpoint $tag $hplimit $MT_fasta $flank\' delplot.R"); +} + +if($rmtmp eq 'yes'){ + if($nu_mt eq 'yes'){system("rm tmp_$tag* tmp1_$tag* tmp2_$tag* tmp_final_$tag*");} + if($o_mt eq 'yes' && $enriched eq 'yes'){if(glob("tmp_$tag*")){system("rm tmp_$tag*");}} + if($i_del eq 'yes'){if(glob("tmp_$tag*")){system("rm tmp_$tag*");}} + if($cn_mt eq 'yes'){system("rm tmp_random_$tag*");} +} + +print scalar(localtime).":Finished\n"; +###########################################################SUBROUTINES################################################################ +sub check_paired{ + my $check_paired = 0; + my $path = shift; + my $line = `zcat $path|tail -n 1`; + my @elements = split(/\t/, $line); + + $check_paired = 1 if $elements[6]=~m/\/.$/; + return $check_paired; +} + +sub build_hash{ + my $file = shift; + my $check_paired = shift; + + open(IN, "gunzip -c $file |") || die "can’t open pipe to $file"; + my $hash; + my $check_hash; + while(){ + my $line = $_; + chomp($line); + next if $line=~m/^\#/; + + my @elements = split(" ",$line); + my $score = $elements[0]; + my $chr = $elements[1]; + + my $start = $elements[2]; + my $length = $elements[3]; + my $end = $start + $length; + + my $read_start = $elements[7]; + my $id; + my $mate = 1; + + if($check_paired==0){ + $id = $elements[6]; + if($id=~m/\_.$/){ + $mate = $id; + $mate =~s/.*\_(.)$/$1/; + $id =~s/\_.$//; + } + } + elsif($check_paired == 1){ + my @name = split(/\//,$elements[6]); $id = $name[0]; + $mate = $name[1]; + } + + my $strand = $elements[9]; + my $evalue = $elements[12]; + $evalue=~s/.*\=//; + next if exists $check_hash->{$id}->{$start.$length}; + $check_hash->{$id}->{$start.$length}++; + $mate = 2 if $mate > 1; + #print "$id\t$mate\t$start\t$end\t$strand\t$len\t$score\t$eval\n"; + + #FILTER BY SCORE AND MAP EVALUE + next if $score < $score_threshold; + next if $evalue > $evalue_threshold; + + push(@{$hash->{$id}->{$mate}->{starts}},$start); + push(@{$hash->{$id}->{$mate}->{ends}},$end); + push(@{$hash->{$id}->{$mate}->{rstarts}},$read_start); + push(@{$hash->{$id}->{$mate}->{strands}},$strand); + push(@{$hash->{$id}->{$mate}->{scores}},$score); + push(@{$hash->{$id}->{$mate}->{evalue}},$evalue); + push(@{$hash->{$id}->{$mate}->{lengths}},$length); + } + undef $check_hash; + close(IN); + return $hash; +} + +sub remove_duplicates{ + my $check_duplicates; + + for my $id (keys %{$hash}){ + my $starts1='NULL'; + my $ends1='NULL'; + my $lengths1='NULL'; + my $starts2='NULL'; + my $ends2='NULL'; + my $lengths2='NULL'; + my $count1 = 0; + my $count2 = 0; + + if(exists $hash->{$id}->{1}){ + $starts1 = join("",@{$hash->{$id}->{1}->{starts}}); + $ends1 = join("",@{$hash->{$id}->{1}->{ends}}); + $lengths1 = join("",@{$hash->{$id}->{1}->{lengths}}); + $count1 = @{$hash->{$id}->{1}->{starts}}; + + } + if(exists $hash->{$id}->{2}){ + $starts2 = join("",@{$hash->{$id}->{2}->{starts}}); + $ends2 = join("",@{$hash->{$id}->{2}->{ends}}); + $lengths2 = join("",@{$hash->{$id}->{2}->{lengths}}); + $count2 = @{$hash->{$id}->{2}->{starts}}; + } + + my $signature1 = $starts1.":".$ends1.":".$lengths1; + my $signature2 = $starts2.":".$ends2.":".$lengths2; + + my @signatures = ($signature1,$signature2); + @signatures = sort @signatures; + my $signature = join("",@signatures); + + + if(exists $check_duplicates->{$signature} && $count1>0 && $count2>0){ + delete $hash->{$id}; + } + else{ + $check_duplicates->{$signature}++; + } + } +} + +#PRINT NON-SPLIT BED +sub print_bed{ + my $hash = shift; + my $tag = shift; + my $refchr = shift; + my $filename = "tmp_".$tag."_nosplit.bed"; + open(ABED,">$filename"); + for my $id (keys %{$hash}){ + #print $id."\n"; + + for my $read(keys %{$hash->{$id}}){ + my $name = $id."_".$read; + + #CHECK IF READ IS SPLIT ALIGNED + my $count = @{$hash->{$id}->{$read}->{starts}}; + next if $count > 1; + my $start = @{$hash->{$id}->{$read}->{starts}}[0]; + my $end = @{$hash->{$id}->{$read}->{ends}}[0]; + print ABED "$refchr\t$start\t$end\t$name\n"; + } + } + system("sort -k2,2n $filename -o $filename"); + close(ABED); + return $filename; +} + +sub process_hash{ + my $hash = shift; + my $bedfile = shift; + my $breakpointfile = shift; + my $size = shift; + my $tag = shift; + my $bps = "tmp_".$tag."_bps.bed"; + my $bpe = "tmp_".$tag."_bpe.bed"; + my $delhash=&process_hash1($hash,$bedfile,$breakpointfile,$msize,$bps,$bpe); + + for my $id (keys %{$hash}){ + #print $id."\n"; + for my $read(keys %{$hash->{$id}}){ + #CHECK IF READ IS SPLIT ALIGNED + my $name = $id."_".$read; + my $count = @{$hash->{$id}->{$read}->{starts}}; + next unless $count == 2; + #next unless $name eq 'C1LUFACXX130228:4:1312:19820:41898_1'; + #CHECK IF THE SPLIT READ FRAGMENTS ARE ABOVE LENGTH THRESHOLD + my $min_len = min @{$hash->{$id}->{$read}->{lengths}}; + next unless $min_len >= $split_length; + + #GET DISTANCE BETWEEN THE FRAGMENTS AND THE BREAKPOINTS + my @read_starts = @{$hash->{$id}->{$read}->{starts}}; + my @read_ends = @{$hash->{$id}->{$read}->{ends}}; + my @read_strands = @{$hash->{$id}->{$read}->{strands}}; + my @read_lengths = @{$hash->{$id}->{$read}->{lengths}}; + my @read_local_starts = @{$hash->{$id}->{$read}->{rstarts}}; + + #LOOK FOR SPLIT READS WHICH MAP INVERSELY SPANNING THE D'LOOP + my $read_check = 'no'; + if($read_starts[0]<$read_starts[1] && $read_local_starts[0]>$read_local_starts[1]){$read_check = 'yes';} + elsif($read_starts[0]>$read_starts[1] && $read_local_starts[0]<$read_local_starts[1]){$read_check = 'yes';} + elsif($read_starts[0]<=$read_starts[1] && $read_local_starts[0]<$read_local_starts[1] && $read_starts[1]<$read_ends[0] ){$read_check = 'yes';} + elsif($read_starts[0]>=$read_starts[1] && $read_local_starts[0]>$read_local_starts[1] && $read_ends[1]>$read_starts[0] ){$read_check = 'yes';} + + #CHECK IF THE SPLIT READ FRAGMENTS SPAN THE DLOOP + my $min_start = min @{$hash->{$id}->{$read}->{starts}}; + my $max_end = max @{$hash->{$id}->{$read}->{ends}}; + next if $min_start <= $dloop1 && $max_end >= $dloop2; + + my ($size,$start,$end) = &get_frag_distance(\@read_starts,\@read_ends,$read_check,$msize); + next if $size < $deletion_threshold_min; + next if $size > $deletion_threshold_max; + next if $read_strands[0] ne $read_strands[1];#SPLIT READS IN OPPOSITE STRANDS MAY INDICATE INVERSION + #print "$name\t$start\t$end\t$size\n"; + + $start = 1 if $start == 0; + $end = 1 if $end == 0; + + #CHECK IF PAIRED READ EXISTS AND ITS ALIGNMENT POSITION SUPPORTS THE SPLIT READ + my $pair = 1 if $read == 2; + $pair = 2 if $read == 1; + my $paired_support = 'no'; + my $distance_paired_support = &paired_support($hash,$id,$read,$pair); + $paired_support = 'yes' if $distance_paired_support <= $paired_distance; + + #LOOK FOR SPLIT READS WITH LARGE UNMAPPED AREA + my ($split_distance) = &get_split_distance(\@read_local_starts,\@read_lengths); + next if $split_distance > $split_distance_threshold; + + #PRINT SPLIT READ IN BED FORMAT + my @read_scores = @{$hash->{$id}->{$read}->{scores}}; + my @len = &generate_bed($id,$read,\@read_starts,\@read_ends,\@read_lengths,\@read_scores,$read_strands[0]); + + my $readid = $id."_".$read; + my $clusterid = "cluster_".$count; + $delhash->{$readid}->{breakstart}=$len[2]; + $delhash->{$readid}->{breakend}=$len[3]; + $delhash->{$readid}->{breaksize}=$len[4]; + $delhash->{$readid}->{readcheck}=$read_check; + $delhash->{$readid}->{lenstart}=$len[0]; + $delhash->{$readid}->{lenend}=$len[1]; + + $start = $len[2]; + $end = $len[3]; + $size = $len[4]; + + print BP "$refchr\t$name\t$size\t$start\t$end\t$read_lengths[0]\t$read_lengths[1]\t$paired_support\t$distance_paired_support\t$read_check\n"; + print BPS "$refchr\t$start\t$start\t$name\t0\t+\n" if $read_check eq 'no'; + print BPS "$refchr\t$start\t$start\t$name\t0\t-\n" if $read_check eq 'yes'; + print BPE "$refchr\t$end\t$end\t$name\t0\t+\n" if $read_check eq 'no'; + print BPE "$refchr\t$end\t$end\t$name\t0\t-\n" if $read_check eq 'yes'; + } + } + close(BP); + close(BED); + close(BPS); + close(BPE); + return $delhash; +} + +sub process_hash1{ + my $hash = shift; + my $bedfile = shift; + my $breakpointfile = shift; + my $size = shift; + my $bps = shift; + my $bpe = shift; + + my $delhash; + + open(BP,">$breakpointfile"); + open(BED,">$bedfile"); + open(BPS,">$bps"); + open(BPE,">$bpe"); + + for my $id (keys %{$hash}){ + #print $id."\n"; + for my $read(keys %{$hash->{$id}}){ + #CHECK IF READ IS SPLIT ALIGNED + my $name = $id."_".$read; + my $count = @{$hash->{$id}->{$read}->{starts}}; + next unless $count == 3; + + #GET DISTANCE BETWEEN THE FRAGMENTS AND THE BREAKPOINTS + my @read_starts = @{$hash->{$id}->{$read}->{starts}}; + my @read_ends = @{$hash->{$id}->{$read}->{ends}}; + my @read_strands = @{$hash->{$id}->{$read}->{strands}}; + my @read_lengths = @{$hash->{$id}->{$read}->{lengths}}; + my @read_scores = @{$hash->{$id}->{$read}->{scores}}; + my @read_local_starts = @{$hash->{$id}->{$read}->{rstarts}}; + + + my %strands=map {$_ => 1} @read_strands; + my $count_read_strands = keys(%strands); + next unless $count_read_strands == 1; + + my $as=join(';',@read_starts);my $ae=join(';',@read_ends);my $asr=join(';',@read_strands);my $als=join(';',@read_local_starts); + my @pos = (1000,1000,1000,1000); + #CHECK FOR FALSE SPLITS AT ORIGIN WITH A REAL DELETION + $pos[0] = 0 if grep {$_ == 0} @read_starts; + $pos[1] = $msize if grep {$_ == $msize} @read_starts; + $pos[2] = 0 if grep {$_ == 0} @read_ends; + $pos[3] = $msize if grep {$_ == $msize} @read_ends; + + #print "$name\t$as\t$ae\t$asr\t$als\t$pos[0]\t$pos[1]\t$pos[2]\t$pos[3]\n"; + if(($pos[0] != 1000||$pos[1] != 1000)&&($pos[2] != 1000||$pos[3] != 1000)){ + my $sort_hash; + for(my $i=0;$i<3;$i++){ + $sort_hash->{$read_local_starts[$i]}->{start}=$read_starts[$i]; + $sort_hash->{$read_local_starts[$i]}->{end}=$read_ends[$i]; + $sort_hash->{$read_local_starts[$i]}->{strand}=$read_strands[$i]; + $sort_hash->{$read_local_starts[$i]}->{length}=$read_lengths[$i]; + $sort_hash->{$read_local_starts[$i]}->{score}=$read_scores[$i]; + } + my $order_count=1; + foreach my $local_start (sort { $a <=> $b } keys %{$sort_hash}){ + my $start_check=$sort_hash->{$local_start}->{start}; + my $end_check=$sort_hash->{$local_start}->{end}; + my $pos_check='no'; + $pos_check='yes' unless($start_check==0||$start_check==$msize||$end_check==0||$end_check==$msize); + if($pos_check eq 'yes'){last;} + $order_count++; + } + + my $delete_count=3 if $order_count==1; + $delete_count=1 if $order_count==3; + $order_count=1; + foreach my $local_start (sort { $a <=> $b } keys %{$sort_hash}){ + delete $sort_hash->{$local_start} if($order_count==$delete_count); + $order_count++; + } + my @read_startsN; + my @read_endsN; + my @read_strandsN; + my @read_local_startsN; + my @read_scoresN; + my @read_lengthsN; + foreach my $local_start (sort { $a <=> $b } keys %{$sort_hash}){ + my $start = $sort_hash->{$local_start}->{start}; + my $end = $sort_hash->{$local_start}->{end}; + my $score = $sort_hash->{$local_start}->{score}; + my $length = $sort_hash->{$local_start}->{length}; + my $strand = $sort_hash->{$local_start}->{strand}; + push @read_startsN,$start; + push @read_endsN,$end; + push @read_local_startsN,$local_start; + push @read_strandsN,$strand; + push @read_scoresN,$score; + push @read_lengthsN,$length; + } + + #CHECK IF THE SPLIT READ FRAGMENTS ARE ABOVE LENGTH THRESHOLD + my $min_len = min @read_lengthsN; + next unless $min_len >= $split_length; + + + #LOOK FOR SPLIT READS WHICH MAP INVERSELY SPANNING THE D'LOOP + my $read_check = 'no'; + if($read_startsN[0]<$read_startsN[1] && $read_local_startsN[0]>$read_local_startsN[1]){$read_check = 'yes';} + elsif($read_startsN[0]>$read_startsN[1] && $read_local_startsN[0]<$read_local_startsN[1]){$read_check = 'yes';} + my ($size,$start,$end) = &get_frag_distance(\@read_startsN,\@read_endsN,$read_check,$msize); + next if $size < $deletion_threshold_min; + next if $size > $deletion_threshold_max; + + #CHECK IF PAIRED READ EXISTS AND ITS ALIGNMENT POSITION SUPPORTS THE SPLIT READ + my $pair = 1 if $read == 2; + $pair = 2 if $read == 1; + my $paired_support = 'no'; + my $distance_paired_support = &paired_support($hash,$id,$read,$pair); + $paired_support = 'yes' if $distance_paired_support <= $paired_distance; + + $start = 1 if $start == 0; + $end = 1 if $end == 0; + + #LOOK FOR SPLIT READS WITH LARGE UNMAPPED AREA + my ($split_distance) = &get_split_distance(\@read_local_startsN,\@read_lengthsN); + next if $split_distance > 5; + + #PRINT SPLIT READ IN BED FORMAT + my @len = &generate_bed1($id,$read,\@read_startsN,\@read_endsN,\@read_lengthsN,\@read_scoresN,$read_strandsN[0]); + my $readid = $id."_".$read; + my $clusterid = "cluster_".$count; + $delhash->{$readid}->{breakstart}=$start; + $delhash->{$readid}->{breakend}=$end; + $delhash->{$readid}->{breaksize}=$size; + $delhash->{$readid}->{readcheck}=$read_check; + $delhash->{$readid}->{lenstart}=$len[0]; + $delhash->{$readid}->{lenend}=$len[1]; + + #$start = $len[2]; + #$end = $len[3]; + #$size = $len[4]; + + print BP "$refchr\t$name\t$size\t$start\t$end\t$read_lengths[0]\t$read_lengths[1]\t$paired_support\t$distance_paired_support\t$read_check\n"; + print BPS "$refchr\t$start\t$start\t$name\t0\t+\n" if $read_check eq 'no'; + print BPS "$refchr\t$start\t$start\t$name\t0\t-\n" if $read_check eq 'yes'; + print BPE "$refchr\t$end\t$end\t$name\t0\t+\n" if $read_check eq 'no'; + print BPE "$refchr\t$end\t$end\t$name\t0\t-\n" if $read_check eq 'yes'; + + } + } + } + return $delhash; +} + +#CHECK IF THE PAIR OF A SPLIT READ LIES WITHIN A GIVEN THRESHOLD DISTANCE TO A FRAGMENT OF THE SPLIT READ +sub paired_support{ + my $hash = shift; + my $id = shift; + my $read = shift; + my $pair = shift; + my $distance = 1000; + + if(exists $hash->{$id}->{$pair}){ + my $distance1 = 0; + my $distance2=0; + + my @read_starts = @{$hash->{$id}->{$read}->{starts}}; + my @read_ends = @{$hash->{$id}->{$read}->{ends}}; + + my $pair_start = @{$hash->{$id}->{$pair}->{starts}}[0]; + my $pair_end = @{$hash->{$id}->{$pair}->{ends}}[0]; + + $distance1 = $read_starts[0] - $pair_end if $read_starts[0] > $pair_end; + $distance1 = $pair_start - $read_ends[0] if $pair_start > $read_ends[0]; + + $distance2 = $read_starts[1] - $pair_end if $read_starts[1] > $pair_end; + $distance2 = $pair_start - $read_ends[1] if $pair_start > $read_ends[1]; + $distance = min ($distance1,$distance2); + } + return $distance; +} + +#GET THE SIZE OF PUTATIVE DELETION AND THE BREAKPOINTS +sub get_frag_distance{ + my $starts = shift; + my $ends = shift; + my $read_check = shift; + my $msize = shift; + my @res; + + my $frag1_start = @{$starts}[0]; + my $frag2_start = @{$starts}[1]; + + my $frag1_end = @{$ends}[0]; + my $frag2_end = @{$ends}[1]; + + if($read_check eq 'no'){ + if($frag1_start > $frag2_end){ + my $size = $frag1_start - $frag2_end; + @res = ($size,$frag2_end,$frag1_start); + } + elsif($frag2_start > $frag1_end){ + my $size = $frag2_start - $frag1_end; + @res = ($size,$frag1_end,$frag2_start); + } + elsif($frag1_start < $frag2_start && $frag2_end <= $frag1_end){ + my $size = $msize - $frag2_end + $frag1_start; + @res = ($size,$frag1_start,$frag2_end); + } + elsif($frag2_start < $frag1_start && $frag1_end <= $frag2_end){ + my $size = $msize - $frag2_end + $frag1_start; + @res = ($size,$frag1_start,$frag2_end); + } + elsif($frag1_start <= $frag2_start && $frag1_end <= $frag2_end){ + my $size = $msize - $frag2_start + $frag1_end ; + @res = ($size,$frag1_end,$frag2_start); + } + elsif($frag2_start <= $frag1_start && $frag2_end <= $frag1_end){ + my $size = $msize - $frag1_end + $frag2_start ; + @res = ($size,$frag2_start,$frag1_end); + } + } + + if($read_check eq 'yes'){ + if($frag1_start > $frag2_end){ + my $size = ($msize -$frag1_end) + $frag2_start; + @res = ($size,$frag2_start,$frag1_end); + } + elsif($frag2_start > $frag1_end){ + my $size = ($msize-$frag2_end) + $frag1_start; + @res = ($size,$frag1_start,$frag2_end); + } + elsif($frag1_start <= $frag2_start && $frag1_end <= $frag2_end){ + my $size = $msize - $frag2_start + $frag1_end ; + @res = ($size,$frag1_end,$frag2_start); + } + elsif($frag2_start <= $frag1_start && $frag2_end <= $frag1_end){ + my $size = $msize - $frag1_end + $frag2_start ; + @res = ($size,$frag2_start,$frag1_end); + } + elsif($frag1_start < $frag2_start && $frag2_end <= $frag1_end){ + my $size = $msize - $frag2_end + $frag1_start; + @res = ($size,$frag1_start,$frag2_end); + } + elsif($frag2_start < $frag1_start && $frag1_end <= $frag2_end){ + my $size = $msize - $frag2_end + $frag1_start; + @res = ($size,$frag1_start,$frag2_end); + } + } + return @res; +} + +#GET THE DISTANCE BETWEEN SPLIT READS +sub get_split_distance{ + my $starts = shift; + my $lengths = shift; + my @res; + + my $local1_start = @{$starts}[0]; + my $local2_start = @{$starts}[1]; + + my $local1_length = @{$lengths}[0]; + my $local2_length = @{$lengths}[1]; + + if($local1_start>$local2_start){ + my $distance = $local1_start - $local2_start - $local2_length; + @res = ($distance); + } + if($local2_start>$local1_start){ + my $distance = $local2_start - $local1_start - $local1_length; + @res = ($distance); + } + return @res; +} + +#GENERATE A BED FILE FOR THE SPLIT READS FOR IGV VISUALIZATION +sub generate_bed{ + my $id = shift; + my $read = shift; + my $starts = shift; + my $ends = shift; + my $lengths = shift; + my $scores = shift; + my $strand = shift; + + my $size = shift; + my $bstart = shift; + my $bend = shift; + my @len; + + my $start; + my $end; + + my $frag1_start = @{$starts}[0]; + my $frag2_start = @{$starts}[1]; + + my $frag1_end = @{$ends}[0]; + my $frag2_end = @{$ends}[1]; + + my $frag1_length = @{$lengths}[0]; + my $frag2_length = @{$lengths}[1]; + + my $frag1_score = @{$scores}[0]; + my $frag2_score = @{$scores}[1]; + my $score = int(($frag1_score+$frag2_score)/2); + + if($frag1_start > $frag2_end && $strand eq '-'){ + $start = $frag2_start; + $end = $frag1_end; + $bstart = $frag2_end; + $bend = $frag1_start; + $size = $frag1_start - $frag2_end; + my $block_start=$frag1_start-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag2_length\,$frag1_length\t0\,$block_start\n"; + @len = ($frag2_length,$frag1_length,$bstart,$bend,$size); + } + elsif($frag1_start > $frag2_end && $strand eq '+'){ + $start = $frag2_start; + $end = $frag1_end; + $bstart = $frag2_start; + $bend = $frag1_end; + $size = 1 + $msize- $frag1_end + $frag2_start; + my $block_start=$frag1_start-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag2_length\,$frag1_length\t0\,$block_start\n"; + @len = ($frag1_length,$frag2_length,$bstart,$bend,$size); + } + elsif($frag2_start > $frag1_end && $strand eq '+'){ + $start = $frag1_start; + $end = $frag2_end; + $bstart = $frag1_end; + $bend = $frag2_start; + $size = $frag2_start - $frag1_end; + my $block_start=$frag2_start-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag1_length\,$frag2_length\t0\,$block_start\n"; + @len = ($frag1_length,$frag2_length,$bstart,$bend,$size); + } + elsif($frag2_start > $frag1_end && $strand eq '-'){ + $start = $frag1_start; + $end = $frag2_end; + $bstart = $frag1_start; + $bend = $frag2_end; + $size = 1 + $msize - $frag2_end + $frag1_start; + my $block_start=$frag2_start-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag1_length\,$frag2_length\t0\,$block_start\n"; + @len = ($frag2_length,$frag1_length,$bstart,$bend,$size); + } + elsif($frag2_start < $frag1_end && $strand eq '+'){ + $start = $frag1_start; + $end = $frag2_end; + $bstart = $frag2_start; + $bend = $frag1_end; + $size = $msize - $frag1_end + $frag2_start; + my $block_start=$frag1_end-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag1_length\,$frag2_length\t0\,$block_start\n"; + @len = ($frag2_length,$frag1_length,$bstart,$bend,$size); + } + elsif($frag1_start < $frag2_end && $strand eq '-'){ + $start = $frag2_start; + $end = $frag1_end; + $bstart = $frag1_start; + $bend = $frag2_end; + $size = $msize - $frag2_end + $frag1_start; + my $block_start=$frag2_end-$start; + $start = 1 if $start == 0;$end = 1 if $end == 0;$bstart = 1 if $bstart == 0;$bend = 1 if $bend == 0; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag1_length\,$frag2_length\t0\,$block_start\n"; + @len = ($frag2_length,$frag1_length,$bstart,$bend,$size); + } + + return @len; +} + +#GENERATE A BED FILE FOR THE SPLIT READS FOR IGV VISUALIZATION (reads which split twice, once due to deletion/duplication and once due to genome circularity) +sub generate_bed1{ + my $id = shift; + my $read = shift; + my $starts = shift; + my $ends = shift; + my $lengths = shift; + my $scores = shift; + my $strand = shift; + my @len; + + my $start; + my $end; + + my $frag1_start = @{$starts}[0]; + my $frag2_start = @{$starts}[1]; + + my $frag1_end = @{$ends}[0]; + my $frag2_end = @{$ends}[1]; + + my $frag1_length = @{$lengths}[0]; + my $frag2_length = @{$lengths}[1]; + + my $frag1_score = @{$scores}[0]; + my $frag2_score = @{$scores}[1]; + my $score = int(($frag1_score+$frag2_score)/2); + + if($frag1_start > $frag2_end){ + $start = $frag2_start; + $end = $frag1_end; + my $block_start=$frag1_start-$start; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag2_length\,$frag1_length\t0\,$block_start\n"; + @len = ($frag2_length,$frag1_length); + } + elsif($frag2_start > $frag1_end){ + $start = $frag1_start; + $end = $frag2_end; + my $block_start=$frag2_start-$start; + print BED "$refchr\t$start\t$end\t$id\_$read\t$score\t$strand\t$start\t$end\t0\t2\t$frag1_length\,$frag2_length\t0\,$block_start\n"; + @len = ($frag1_length,$frag2_length); + } + return @len; +} + +sub get_cluster{ + my $delhash = shift; + my $breakthreshold = shift; + my $tag = shift; + my $bps = "tmp_".$tag."_bps.bed"; + my $bpe = "tmp_".$tag."_bpe.bed"; + my $bpsc = "tmp_".$tag."_bps.cls"; + my $bpec = "tmp_".$tag."_bpe.cls"; + my $clusterhash; + + system("$sortBed -i $bps|$clusterBed -s -d $breakthreshold -i stdin > $bpsc"); + system("$sortBed -i $bpe|$clusterBed -s -d $breakthreshold -i stdin > $bpec"); + + open(BPS, "<$bpsc"); + my @bps=; + my $bps_hash; + foreach my $line(@bps){ + chomp $line; + my @fields=split(/\t/,$line); + my $readid=$fields[3]; + my $clusterid=$fields[6]; + $bps_hash->{$readid} = $clusterid; + } + close(BPS); + + open(BPE, "<$bpec"); + my @bpe=; + my $bpe_hash; + foreach my $line(@bpe){ + chomp $line; + my @fields=split(/\t/,$line); + my $readid=$fields[3]; + my $clusterid=$fields[6]; + $bpe_hash->{$readid} = $clusterid; + } + close(BPE); + + for my $readid(keys %{$delhash}){ + next unless exists $bps_hash->{$readid}; + next unless exists $bpe_hash->{$readid}; + my $clusterids = $bps_hash->{$readid}; + my $clusteride = $bpe_hash->{$readid}; + my $clusterid="cluster".$clusterids.$clusteride; + $clusterhash->{$clusterid}->{$readid} = $delhash->{$readid}; + } + return $clusterhash; +} + +sub build_results{ + my $hash = shift; + my $clusterhash = shift; + my $infile = shift; + my $refchr = shift; + my $cluster_read_count_threshold = shift; + my $tag = shift; + my $clustercount; + + my $nosplitbed_file = "tmp_".$tag."_nosplit.bed";; + for my $clusterid (keys %{$clusterhash}){ + my $cluster_read_count = scalar keys %{$clusterhash->{$clusterid}}; + next if $cluster_read_count < $cluster_read_count_threshold; + + print "Check $clusterid\n"; + my $clustercheck; + $clustercount->{$clusterid}->{wt} = 0; + $clustercount->{$clusterid}->{mt} = scalar keys %{$clusterhash->{$clusterid}}; + + my $splitbed_fileS = "tmp_".$tag.".split.start.bed"; + my $splitbed_fileE = "tmp_".$tag.".split.end.bed"; + + open(SBEDS,">$splitbed_fileS"); + open(SBEDE,">$splitbed_fileE"); + + for my $readid (keys %{$clusterhash->{$clusterid}}){ + my $breakstart = $clusterhash->{$clusterid}->{$readid}->{breakstart}; + my $breakend = $clusterhash->{$clusterid}->{$readid}->{breakend}; + my $lenstart = $clusterhash->{$clusterid}->{$readid}->{lenstart}; + my $lenend = $clusterhash->{$clusterid}->{$readid}->{lenend}; + + push(@{$clustercount->{$clusterid}->{starts}},$breakstart); + push(@{$clustercount->{$clusterid}->{ends}},$breakend); + push(@{$clustercount->{$clusterid}->{names}},$readid); + push(@{$clustercount->{$clusterid}->{lenstarts}},$lenstart); + push(@{$clustercount->{$clusterid}->{lenends}},$lenend); + + print SBEDS "$refchr\t$breakstart\t$breakstart\n"; + print SBEDE "$refchr\t$breakend\t$breakend\n"; + } + + system("sort -u -k2,2n -k3 $splitbed_fileS -o $splitbed_fileS"); + system("sort -u -k2,2n -k3 $splitbed_fileE -o $splitbed_fileE"); + + my $intersectbed_fileS = "tmp_".$tag.".intersect.start.bed"; + my $intersectbed_fileE = "tmp_".$tag.".intersect.end.bed"; + + + system("$intersectBed -wo -sorted -a $nosplitbed_file -b $splitbed_fileS > $intersectbed_fileS"); + open(IS,"<$intersectbed_fileS"); + while(){ + my $line = $_; + chomp($line); + my @crd = split(/\t/,$line); + my $start = $crd[1]; + my $end = $crd[2]; + my $name = $crd[3]; + my $breakstart = $crd[5]; + next if exists $clustercheck->{$name}; + my $diffstart = $breakstart - $start; + my $diffend = $end - $breakstart; + next if $diffstart <= $breakspan || $diffend <= $breakspan; + $clustercount->{$clusterid}->{wt1}++; + $clustercheck->{$name}++; + } + close(SBEDS); + close(IS); + unlink $splitbed_fileS,$intersectbed_fileS; + + system("$intersectBed -wo -sorted -a $nosplitbed_file -b $splitbed_fileE > $intersectbed_fileE"); + open(IE,"<$intersectbed_fileE"); + while(){ + my $line = $_; + chomp($line); + my @crd = split(/\t/,$line); + my $start = $crd[1]; + my $end = $crd[2]; + my $name = $crd[3]; + my $breakend = $crd[5]; + next if exists $clustercheck->{$name}; + my $diffstart = $breakend - $start; + my $diffend = $end - $breakend; + next if $diffstart <= $breakspan || $diffend <= $breakspan; + $clustercount->{$clusterid}->{wt2}++; + $clustercheck->{$name}++; + } + close(SBEDE); + close(IE); + unlink $splitbed_fileE,$intersectbed_fileE; + } + return $clustercount; +} + +sub print_result{ + my $clustercount = shift; + my $clusterfile = shift; + open(CF,">$clusterfile"); + + for my $clusterid(keys %{$clustercount}){ + my $names = $clustercount->{$clusterid}->{names}; + my $starts = $clustercount->{$clusterid}->{starts}; + my $ends = $clustercount->{$clusterid}->{ends}; + my $lenstarts = $clustercount->{$clusterid}->{lenstarts}; + my $lenends = $clustercount->{$clusterid}->{lenends}; + my $mt = $clustercount->{$clusterid}->{mt}; + my $wt1 = 0; + $wt1 = $clustercount->{$clusterid}->{wt1} if exists $clustercount->{$clusterid}->{wt1}; + my $wt2 = 0; + $wt2 = $clustercount->{$clusterid}->{wt2} if exists $clustercount->{$clusterid}->{wt2}; + my $sum_wt = $wt1 + $wt2; + my $mean_wt = sprintf "%.0f",$sum_wt/2; + + my $names_print = join("\,",@$names); + my $starts_print = join("\,",@$starts); + my $ends_print = join("\,",@$ends); + + #if fragments overlap, then lenstart and and lenend are committed to NA + my $lenstarts_print = "NA"; + my $lenends_print = "NA"; + if(defined(@$lenstarts[0])){$lenstarts_print = join("\,",@$lenstarts);} + if(defined(@$lenends[0])){$lenends_print = join("\,",@$lenends);} + + my $perc_hp = $mt*100/($mt+$mean_wt); + + print CF "$clusterid\t$names_print\t$starts_print\t$ends_print\t$lenstarts_print\t$lenends_print\t$mt\t$mean_wt\t$perc_hp\n"; + } + close(CF); +} diff --git a/bin/add_most_severe_consequence.py b/bin/add_most_severe_consequence.py index 78dcfb947..a3902c062 100755 --- a/bin/add_most_severe_consequence.py +++ b/bin/add_most_severe_consequence.py @@ -7,7 +7,7 @@ import gzip import sys from pathlib import Path -from typing import Tuple, TextIO +from typing import TextIO, Tuple def parse_vep_csq_transcripts( @@ -68,6 +68,7 @@ def construct_most_severe_consequence_info( columns = line.strip().split() info_fields = columns[7].split(";") + transcripts = [] for field in info_fields: if field.startswith("CSQ="): transcripts = field.split("CSQ=")[1].split(",") diff --git a/bin/add_most_severe_pli.py b/bin/add_most_severe_pli.py index abb1f5b7b..8c0b3d00d 100755 --- a/bin/add_most_severe_pli.py +++ b/bin/add_most_severe_pli.py @@ -46,6 +46,7 @@ def construct_most_severe_pli_info(line: str, pli_ind: int) -> list: columns = line.strip().split() info_fields = columns[7].split(";") + transcripts = [] for field in info_fields: if field.startswith("CSQ="): transcripts = field.split("CSQ=")[1].split(",") @@ -56,7 +57,7 @@ def construct_most_severe_pli_info(line: str, pli_ind: int) -> list: except ValueError: pli_max = "" if pli_max: - columns[7] += ";most_severe_pli={:.2f}".format(float(pli_max)) + columns[7] += f";most_severe_pli={float(pli_max):.2f}" return columns diff --git a/bin/create_hgncids_file.py b/bin/create_hgncids_file.py new file mode 100755 index 000000000..3bd7f358c --- /dev/null +++ b/bin/create_hgncids_file.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Written by Ramprasad Neethiraj and released under the MIT license. +# See git repository (https://github.com/nf-core/raredisease) for full license text. + +from pathlib import Path +import argparse + +def main(): + parser = argparse.ArgumentParser( + description="Extract HGNC IDs from a VEP filter file. Supports Scout gene panel format " + "(tab-delimited, HGNC ID in column 4) and standard format (one HGNC ID per " + "non-comment line). Pass --meta-id scout for Scout format, any other value " + "for standard format." + ) + parser.add_argument( + "--input", + required=True, + help="Path to input file" + ) + parser.add_argument( + "--meta-id", + required=True, + help="Value of meta.id (e.g. scout)" + ) + + args = parser.parse_args() + + input_path = Path(args.input) + output_fn = input_path.stem + "_reformatted.txt" + + with input_path.open() as input_file, open(output_fn, "w") as output: + if args.meta_id == "scout": + for line in input_file: + if not line.startswith("#") and line.strip(): + spl = line.rstrip("\n").split("\t") + if len(spl) > 3: + output.write(spl[3] + "\n") + else: + for line in input_file: + if not line.startswith("#"): + output.write(line) + +if __name__ == "__main__": + main() diff --git a/bin/filter_vep b/bin/filter_vep new file mode 100755 index 000000000..32b072399 --- /dev/null +++ b/bin/filter_vep @@ -0,0 +1,885 @@ +#!/usr/bin/env python3 +""" +filter_vep - Fast Python reimplementation of Ensembl's filter_vep. + +Fast Python reimplementation of the Perl filter_vep script distributed with +Ensembl VEP (EMBL-EBI). Validated against VEP 110 and 115.2, which are +functionally identical for VCF filtering. +Uses cyvcf2 for VCF parsing when available (significant speedup for large +VCF / bgzipped files via htslib). + +All filter operators are supported except is_child, which requires a live +Ensembl Ontology DB. Use the original filter_vep --ontology for +ontology-aware filtering, or replace is_child with an explicit 'in' list +of consequence terms. +""" + +import sys +import re +import gzip +import argparse +import os + +try: + import cyvcf2 + HAS_CYVCF2 = True +except ImportError: + HAS_CYVCF2 = False + + +# --------------------------------------------------------------------------- +# Filter expression parser / evaluator +# --------------------------------------------------------------------------- + +class FilterSet: + """Parse and evaluate VEP filter expressions. + + Multiple filter strings are ANDed (all must pass). + Within a string: 'and' / 'or' / 'not' and parentheses are supported. + + Operators (with documented synonyms): + is / = / eq case-insensitive equality + is not / != / ne inequality + > / gt greater than + < / lt less than + >= / gte greater than or equal + <= / lte less than or equal + match / matches / re / regex regex search (case-insensitive) + in list or file membership + exists / ex / defined field has a non-null value + is_child SO ontology child (not supported; see --ontology) + + Special value syntax: + #FieldName compare against another field's value + bare field name equivalent to 'exists' + + Numeric extraction: + Mixed-content values like "deleterious(0.05)" have the number + extracted automatically when a numeric operator is used. + + Source-prefix stripping: + "HGNC:28706" matches "28706" for is/in comparisons. + """ + + # Canonical operator names after synonym normalisation + _OP_SYNONYMS = { + 'eq': 'is', + 'ne': '!=', + 'lt': '<', + 'gt': '>', + 'lte': '<=', + 'gte': '>=', + 'matches': 'match', + 're': 'match', + 'regex': 'match', + 'ex': 'exists', + 'defined': 'exists', + } + # Words that should be tokenised as OP rather than field names + _OP_WORDS = frozenset( + ['is', 'match', 'in', 'exists', 'is_child'] + + list(_OP_SYNONYMS.keys()) + ) + + _file_cache: dict = {} # shared across all instances + + def __init__(self, *filter_strings): + self._parsed = [self._parse(filter_string) for filter_string in filter_strings] + + # -- tokeniser ----------------------------------------------------------- + + def _tokenize(self, expr): + tokens = [] + char_idx = 0 + expr_length = len(expr) + while char_idx < expr_length: + char = expr[char_idx] + if char.isspace(): + char_idx += 1 + continue + if char == '(': + tokens.append(('LP', None)); char_idx += 1; continue + if char == ')': + tokens.append(('RP', None)); char_idx += 1; continue + if char in ('>', '<', '!', '='): + two_char = expr[char_idx:char_idx+2] + if two_char in ('>=', '<=', '!='): + tokens.append(('OP', two_char)); char_idx += 2 + else: + tokens.append(('OP', char)); char_idx += 1 + continue + word_match = re.match(r'[^\s()]+', expr[char_idx:]) + if word_match: + word = word_match.group() + word_lower = word.lower() + if word_lower == 'and': tokens.append(('AND', None)) + elif word_lower == 'or': tokens.append(('OR', None)) + elif word_lower == 'not': tokens.append(('NOT', None)) + elif word_lower in self._OP_WORDS: + tokens.append(('OP', self._OP_SYNONYMS.get(word_lower, word_lower))) + else: + tokens.append(('W', word)) + char_idx += len(word) + continue + char_idx += 1 + tokens.append(('EOF', None)) + return tokens + + # -- recursive-descent parser -> AST ------------------------------------- + + def _parse(self, expr): + tokens = self._tokenize(expr) + token_pos = [0] + + def peek(): + return tokens[token_pos[0]] + + def eat(): + token = tokens[token_pos[0]] + token_pos[0] += 1 + return token + + def parse_or(): + left_node = parse_and() + while peek()[0] == 'OR': + eat() + right_node = parse_and() + left_node = ('or', left_node, right_node) + return left_node + + def parse_and(): + left_node = parse_not() + while peek()[0] == 'AND': + eat() + right_node = parse_not() + left_node = ('and', left_node, right_node) + return left_node + + def parse_not(): + if peek()[0] == 'NOT': + eat() + return ('not', parse_atom()) + return parse_atom() + + def parse_atom(): + if peek()[0] == 'LP': + eat() + node = parse_or() + if peek()[0] == 'RP': + eat() + return node + if peek()[0] != 'W': + raise SyntaxError(f"Expected field name, got {peek()!r} in: {expr!r}") + field = eat()[1] + next_token = peek() + if next_token[0] in ('EOF', 'RP', 'AND', 'OR'): + return ('exists', field, None) + if next_token[0] != 'OP': + return ('exists', field, None) + operator = eat()[1].lower() + if operator == 'is' and peek()[0] == 'NOT': + eat() + operator = 'is not' + if operator == 'exists': + return ('exists', field, None) + if peek()[0] in ('EOF', 'AND', 'OR', 'RP'): + value = None + else: + value = eat()[1] + return (operator, field, value) + + return parse_or() + + # -- evaluator ----------------------------------------------------------- + + def evaluate(self, data): + return all(self._eval(ast_node, data) for ast_node in self._parsed) + + def _fetch_field_value(self, data, field): + """Fetch field value with case-insensitive fallback.""" + value = data.get(field) + if value is not None: + return value + field_lower = field.lower() + for existing_key, existing_value in data.items(): + if existing_key is not None and existing_key.lower() == field_lower: + return existing_value + return None + + @staticmethod + def _normalize_missing(field, value): + """Treat '' and '-' (except for Allele) as missing.""" + if value is None or value == '': + return None + if field != 'Allele' and value == '-': + return None + return value + + # Regex for VEP mixed-type field values: e.g. "HGNC:28706", "deleterious(0.05)" + _MIXED_RE = re.compile(r'^([\w.\-]+)?:?\(?([-\d.e]*)\)?', re.IGNORECASE) + _NUM_RE = re.compile(r'^-?\d+\.?\d*(e-?\d+)?$', re.IGNORECASE) + _PURE_NUM = re.compile(r'^[-\d.e]+$', re.IGNORECASE) + + def _get_input(self, field_value, representative_value): + """Replicate VEP 115 FilterSet.get_input() value-extraction logic. + + Given a raw field value and a representative comparison value, + returns the part of field_value that should be compared. + + - If field_value has the form TEXT:NUM or TEXT(NUM): + - and representative_value is purely numeric → return the NUM part + - otherwise → return field_value unchanged + - If field_value is plain (no numeric part) → return field_value unchanged + """ + if field_value is None: + return None + field_str = str(field_value) + mixed_match = self._MIXED_RE.match(field_str) + if not mixed_match: + return field_str + text_part = mixed_match.group(1) or '' + numeric_part = mixed_match.group(2) or '' + if not numeric_part: + return field_str + representative_str = str(representative_value) if representative_value is not None else '' + if self._PURE_NUM.match(representative_str): + if not self._NUM_RE.match(text_part): + return numeric_part + return text_part + return field_str + + def _resolve_value(self, value, data): + """If value starts with '#', resolve it to the named field's value.""" + if value and value.startswith('#'): + field_name = value[1:] + return self._normalize_missing(field_name, self._fetch_field_value(data, field_name)) + return value + + def _eval(self, node, data): + operator = node[0] + if operator == 'and': return self._eval(node[1], data) and self._eval(node[2], data) + if operator == 'or': return self._eval(node[1], data) or self._eval(node[2], data) + if operator == 'not': return not self._eval(node[1], data) + + field = node[1] + value = self._resolve_value(node[2] if len(node) > 2 else None, data) + field_value = self._normalize_missing(field, self._fetch_field_value(data, field)) + + if operator == 'exists': + return field_value is not None + + if operator in ('is', '='): + if value is None: return field_value is None + if field_value is None: return False + processed_input = self._get_input(field_value, value) + return processed_input.lower() == str(value).lower() + + if operator in ('is not', '!='): + if value is None: return field_value is not None + if field_value is None: return True + processed_input = self._get_input(field_value, value) + return processed_input.lower() != str(value).lower() + + if field_value is None: + return False + + if operator == 'match': + return bool(re.search(str(value or ''), str(field_value), re.IGNORECASE)) + + if operator == 'in': + if value is None: return False + in_set = self._in_set(value) + representative = next(iter(in_set), None) + processed_input = self._get_input(field_value, representative).lower() + return processed_input in in_set + + if operator == 'is_child': + raise NotImplementedError( + "is_child requires a live Ensembl Ontology DB (--ontology). " + "Use the original filter_vep with --ontology, or replace " + "is_child with an explicit 'in' list of the consequence terms you need." + ) + + # Ordered comparisons — use _get_input for numeric extraction + processed_input = self._get_input(field_value, value) + str_field_val = processed_input + str_target_val = str(value or '') + try: + field_num = float(str_field_val) + target_num = float(str_target_val) + if operator == '>': return field_num > target_num + if operator == '<': return field_num < target_num + if operator == '>=': return field_num >= target_num + if operator == '<=': return field_num <= target_num + except (ValueError, TypeError): + pass + if operator == '>': return str_field_val > str_target_val + if operator == '<': return str_field_val < str_target_val + if operator == '>=': return str_field_val >= str_target_val + if operator == '<=': return str_field_val <= str_target_val + return False + + def limit_synonym_search(self, _value=True): + """No-op shim (kept for API parity with the Perl module).""" + + def _in_set(self, value): + """Return a set of lowercase values for the 'in' operator. + If value looks like a readable file path, read one value per line. + Otherwise split on commas. + """ + if value in self._file_cache: + return self._file_cache[value] + if os.path.isfile(value): + with open(value) as file_handle: + value_set = {line.strip().lower() for line in file_handle if line.strip()} + self._file_cache[value] = value_set + return value_set + value_set = {item.strip().lower() for item in value.split(',')} + return value_set + + +# --------------------------------------------------------------------------- +# Parsing helpers +# --------------------------------------------------------------------------- + +def parse_headers(raw_headers, vcf_info_field='CSQ'): + """Return (vep_headers, col_headers, allowed_fields_dict).""" + vep_headers = None + col_headers = None + allowed_fields = {} + for raw_header in raw_headers: + hash_count = len(raw_header) - len(raw_header.lstrip('#')) + stripped_header = raw_header.lstrip('#') + if hash_count >= 2: + if re.match(r'INFO== 5 + and re.match(r'(chr)?\w+', fields[0]) + and re.match(r'^\d+$', fields[1]) + and fields[3] and re.match(r'^[ACGTN\-.]+$', fields[3], re.IGNORECASE) + and fields[4]): + return 'vcf' + return 'tab' + + +def open_input(path, force_gz=False): + if path is None: + return sys.stdin + if path.endswith('.gz') or force_gz: + return gzip.open(path, 'rt') + with open(path, 'rb') as file_handle: + magic_bytes = file_handle.read(2) + if magic_bytes == b'\x1f\x8b': + return gzip.open(path, 'rt') + return open(path, 'r') + + +# --------------------------------------------------------------------------- +# cyvcf2 fast path (VCF only) +# --------------------------------------------------------------------------- + +def process_cyvcf2(args, output_fh): + vcf_info_field = args.vcf_info_field + filter_set = args.filter_set + + vcf = cyvcf2.VCF(args.input_file or '-') + + raw_header_lines = vcf.raw_header.rstrip('\n').split('\n') + + vep_headers = None + for header_line in raw_header_lines: + regex_match = re.search(r'ID=' + re.escape(vcf_info_field) + r'.*?Format: (.+?)"', header_line) + if regex_match: + vep_headers = regex_match.group(1).split('|') + break + + col_headers = None + for header_line in reversed(raw_header_lines): + if header_line.startswith('#') and not header_line.startswith('##'): + col_headers = header_line.lstrip('#').split('\t') + break + + all_fields = set() + if vep_headers: all_fields.update(vep_headers) + if col_headers: all_fields.update(col_headers) + for header_line in raw_header_lines: + regex_match = re.match(r'##INFO=') + output_header_lines.insert(idx, '##FILTER=') + break + + if not args.count: + output_fh.write('\n'.join(output_header_lines) + '\n') + + column_names = col_headers or ['CHROM', 'POS', 'ID', 'REF', 'ALT', 'QUAL', 'FILTER', 'INFO'] + count = 0 + line_number = 0 + missing_csq = 0 + + for variant in vcf: + line_number += 1 + if args.test and line_number > args.test: + break + + vcf_line = str(variant).rstrip('\n') + vcf_parts = vcf_line.split('\t') + + main_data = {column_names[idx]: (vcf_parts[idx] if idx < len(vcf_parts) else None) + for idx in range(len(column_names))} + if len(vcf_parts) > 7: + for info_field in vcf_parts[7].split(';'): + if '=' in info_field: + info_key, info_value = info_field.split('=', 1) + if info_key != vcf_info_field: + main_data[info_key] = info_value + elif info_field: + main_data[info_field] = None # Flag: Perl sets to undef, so exists-check fails + + csq_value = variant.INFO.get(vcf_info_field) + chunks = [] + data_list = [] + + if csq_value: + chunks = csq_value.split(',') + data_list = [parse_csq_chunk(chunk, vep_headers or [], main_data) for chunk in chunks] + else: + missing_csq += 1 + data_list = [main_data] + + line_pass = 0 + new_chunks = [] + for blob_index, parsed_blob in enumerate(data_list): + if filter_set.evaluate(parsed_blob): + line_pass += 1 + if blob_index < len(chunks): + new_chunks.append(chunks[blob_index]) + + count += bool(line_pass) + + if not args.soft_filter and count < args.start: + continue + + if args.soft_filter: + filter_tag = 'filter_vep_pass' if line_pass else 'filter_vep_fail' + existing_filter = vcf_parts[6] if len(vcf_parts) > 6 else '.' + vcf_parts[6] = f"{existing_filter};{filter_tag}" if existing_filter and existing_filter != '.' else filter_tag + output_fh.write('\t'.join(vcf_parts) + '\n') + elif line_pass and not args.count: + out_line = vcf_line + if args.only_matched and new_chunks and len(new_chunks) != len(chunks): + new_csq = ','.join(new_chunks) + vcf_parts_rw = out_line.split('\t') + vcf_parts_rw[7] = re.sub(re.escape(vcf_info_field) + r'=[^;]*', + vcf_info_field + '=' + new_csq, vcf_parts_rw[7], count=1) + out_line = '\t'.join(vcf_parts_rw) + output_fh.write(out_line + '\n') + + if not args.soft_filter and count >= args.limit + args.start - 1: + break + + vcf.close() + + if line_number == 0 and not args.count: + output_fh.write('\n'.join(output_header_lines) + '\n') + + if args.count: + output_fh.write(f"{count}\n") + + if missing_csq: + sys.stderr.write( + f"WARNING: filter_vep couldn't find VEP annotations field " + f"{vcf_info_field} in {missing_csq} line(s) of the input file\n" + ) + + +# --------------------------------------------------------------------------- +# Generic path (tab or VCF without cyvcf2) +# --------------------------------------------------------------------------- + +def process_generic(args, output_fh): + vcf_info_field = args.vcf_info_field + filter_set = args.filter_set + + input_fh = open_input(args.input_file, args.gz) + + raw_headers = [] + vep_headers = None + col_headers = None + file_format = args.format + count = 0 + line_number = 0 + missing_csq = 0 + headers_initialised = False + + csq_re = re.compile(re.escape(vcf_info_field) + r'=(.+?)(?:;|\s|$)') + + for raw_line in input_fh: + line = raw_line.rstrip('\n') + + if line.startswith('#'): + raw_headers.append(line) + continue + + line_number += 1 + if args.test and line_number > args.test: + break + + # -- initialise on first data line -- + if not headers_initialised: + if not raw_headers: + sys.exit("ERROR: No headers found in input file") + + if args.soft_filter: + chrom_header = raw_headers.pop() + raw_headers.append('##FILTER=') + raw_headers.append('##FILTER=') + raw_headers.append(chrom_header) + + if not args.count and not args.list: + output_fh.write('\n'.join(raw_headers) + '\n') + + vep_headers, col_headers, extra_allowed = parse_headers(raw_headers, vcf_info_field) + + all_fields = set() + if vep_headers: all_fields.update(vep_headers) + if col_headers: all_fields.update(col_headers) + all_fields.update(extra_allowed) + + if args.list: + print("Available fields:\n") + for field_name in sorted(all_fields): + print(field_name) + if input_fh is not sys.stdin: + input_fh.close() + return + + headers_initialised = True + + # -- format detection -- + if not file_format: + file_format = detect_format(line) + if file_format not in ('vcf', 'tab'): + sys.exit(f"ERROR: Unable to parse data in format {file_format}") + if file_format != 'vcf' and args.only_matched: + sys.exit("ERROR: --only_matched is compatible only with VCF files") + if file_format != 'vcf' and args.soft_filter: + sys.exit("ERROR: --soft_filter is compatible only with VCF files") + + if args.soft_filter: + args.start = 0 + + chunks = [] + data_list = [] + + if file_format == 'tab': + tab_headers = col_headers or vep_headers or [] + data_list.append(parse_tab_line(line, tab_headers)) + chunks.append(line) + if not any(header == 'Extra' for header in tab_headers): + filter_set.limit_synonym_search(True) + + else: # vcf + vcf_parts = line.split('\t') + column_headers = col_headers or ['CHROM', 'POS', 'ID', 'REF', 'ALT', 'QUAL', 'FILTER', 'INFO'] + main_data = {column_headers[idx]: (vcf_parts[idx] if idx < len(vcf_parts) else None) + for idx in range(len(column_headers))} + + if len(vcf_parts) > 7: + for info_field in vcf_parts[7].split(';'): + if '=' in info_field: + info_key, info_value = info_field.split('=', 1) + if info_key != vcf_info_field: + main_data[info_key] = info_value + elif info_field: + main_data[info_field] = None # Flag: Perl sets to undef, so exists-check fails + + regex_match = csq_re.search(line) + if regex_match: + raw_csq_value = regex_match.group(1) + chunks = raw_csq_value.split(',') + data_list = [parse_csq_chunk(chunk, vep_headers or [], main_data) for chunk in chunks] + else: + missing_csq += 1 + data_list = [main_data] + + filter_set.limit_synonym_search(True) + + # -- evaluate -- + line_pass = 0 + new_chunks = [] + for blob_index, parsed_blob in enumerate(data_list): + if filter_set.evaluate(parsed_blob): + line_pass += 1 + if blob_index < len(chunks): + new_chunks.append(chunks[blob_index]) + + count += bool(line_pass) + + if not args.soft_filter and count < args.start: + continue + + # -- output -- + if args.soft_filter: + split_parts = line.split('\t') + filter_tag = 'filter_vep_pass' if line_pass else 'filter_vep_fail' + existing_filter = split_parts[6] if len(split_parts) > 6 else '.' + split_parts[6] = f"{existing_filter};{filter_tag}" if existing_filter and existing_filter != '.' else filter_tag + output_fh.write('\t'.join(split_parts) + '\n') + + elif line_pass and not args.count: + out_line = line + if args.only_matched and new_chunks and len(new_chunks) != len(chunks): + new_csq = ','.join(new_chunks) + vcf_parts_rw = out_line.split('\t') + vcf_parts_rw[7] = re.sub(re.escape(vcf_info_field) + r'=[^;]*', + vcf_info_field + '=' + new_csq, vcf_parts_rw[7], count=1) + out_line = '\t'.join(vcf_parts_rw) + output_fh.write(out_line + '\n') + + if not args.soft_filter and count >= args.limit + args.start - 1: + break + + # -- empty file -- + if not line_number: + if not args.count and not args.list: + output_fh.write('\n'.join(raw_headers) + '\n') + if args.list: + vep_headers_parsed, col_headers_parsed, allowed_parsed = parse_headers(raw_headers, vcf_info_field) + all_fields = set() + if vep_headers_parsed: all_fields.update(vep_headers_parsed) + if col_headers_parsed: all_fields.update(col_headers_parsed) + all_fields.update(allowed_parsed) + print("Available fields:\n") + for field_name in sorted(all_fields): + print(field_name) + if input_fh is not sys.stdin: + input_fh.close() + return + + if args.count: + output_fh.write(f"{count}\n") + + if missing_csq: + sys.stderr.write( + f"WARNING: filter_vep couldn't find VEP annotations field " + f"{vcf_info_field} in {missing_csq} line(s) of the input file\n" + ) + + if input_fh is not sys.stdin: + input_fh.close() + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +USAGE = """\ +#------------# +# filter_vep # +#------------# + +http://www.ensembl.org/info/docs/tools/vep/script/vep_filter.html + +Usage: +./filter_vep [arguments] + +--help -h Print usage message and exit + +--input_file [file] -i Input file (VEP results). Reads from STDIN if + not specified. Supports gzip (auto-detected or + force with --gz). +--format [vcf|tab] Input format (tab = any tab-delimited format, + including default VEP output format) + +--output_file [file] -o Output file. Defaults to STDOUT. +--force_overwrite Overwrite existing output file. + +--filter [filters] -f Filter expression. Multiple --filter flags are + treated as logical ANDs, e.g.: + -f "Consequence is missense_variant" + -f "AF < 0.01 or not AF" + -f "HGNC_ID in gene_panels.txt" + -f "(AFR_AF gt #EUR_AF) and SIFT lt 0.05" + + Operators: + is / = / eq case-insensitive equality + != / ne inequality + > / gt greater than + < / lt less than + >= / gte greater than or equal + <= / lte less than or equal + match/matches/re/regex regex (case-insensitive) + in list or file (one value/line) + exists/ex/defined field is present and non-null + is_child SO ontology child (not supported here) + Logical: and or not ( ) + Value can be #Field to compare two fields. + Mixed content (e.g. "deleterious(0.05)") has its + number extracted for numeric comparisons. + Source prefixes (e.g. "HGNC:34") are stripped + automatically in is/in comparisons. + +--list -l List available fields from the input file. +--count -c Print only a count of matched lines. + +--only_matched In VCF files, rewrite the CSQ field to contain + only annotation blobs that passed the filters. + +--vcf_info_field [key] VCF INFO key for VEP annotations (default: CSQ). + +--soft_filter Add filter_vep_pass / filter_vep_fail to the VCF + FILTER column instead of excluding variants. + +--ontology -y Accepted for compatibility but not implemented. + is_child requires a live Ensembl Ontology DB; use + the original filter_vep --ontology for that feature, + or replace is_child with an explicit 'in' list. +--host / --user / --pass / --port / --version / --registry + Database connection options (accepted, not used). + +--start [N] -s Skip first N passing results (1-based, default 1) +--limit [N] Return at most N passing results. +--test [N] Process only the first N non-header lines. +""" + + +def main(): + arg_parser = argparse.ArgumentParser(add_help=False) + arg_parser.add_argument('--help', '-h', action='store_true') + arg_parser.add_argument('--test', type=int) + arg_parser.add_argument('--count', '-c', action='store_true') + arg_parser.add_argument('--list', '-l', action='store_true') + arg_parser.add_argument('--input_file', '-i') + arg_parser.add_argument('--output_file', '-o', default='stdout') + arg_parser.add_argument('--force_overwrite', action='store_true') + arg_parser.add_argument('--format', choices=['vcf', 'tab']) + arg_parser.add_argument('--gz', action='store_true') + arg_parser.add_argument('--only_matched', action='store_true') + arg_parser.add_argument('--vcf_info_field', default='CSQ') + arg_parser.add_argument('--soft_filter', action='store_true') + arg_parser.add_argument('--ontology', '-y', action='store_true') + arg_parser.add_argument('--host', default='ensembldb.ensembl.org') + arg_parser.add_argument('--user', default='anonymous') + arg_parser.add_argument('--pass', dest='password', default=None) + arg_parser.add_argument('--port', type=int, default=3306) + arg_parser.add_argument('--version', type=int) + arg_parser.add_argument('--registry') + arg_parser.add_argument('--start', '-s', type=int, default=1) + arg_parser.add_argument('--limit', type=int, default=int(1e12)) + arg_parser.add_argument('--filter', '-f', action='append') + + args = arg_parser.parse_args() + + if args.help or (not args.filter and not args.list): + print(USAGE) + if not args.help: + sys.exit("ERROR: No valid filters given") + sys.exit(0) + + if args.ontology: + sys.stderr.write( + "WARNING: --ontology is accepted for compatibility but is_child is not " + "implemented. Use the original filter_vep --ontology for ontology-aware " + "filtering, or replace is_child with an explicit 'in' list.\n" + ) + + args.filter_set = FilterSet(*(args.filter or [])) + + if args.output_file.lower() != 'stdout': + if os.path.exists(args.output_file) and not args.force_overwrite: + sys.exit( + f"ERROR: Output file {args.output_file} already exists. " + "Use --force_overwrite to overwrite." + ) + output_fh = open(args.output_file, 'w') + else: + output_fh = sys.stdout + + try: + use_cyvcf2 = ( + HAS_CYVCF2 + and args.format != 'tab' + and (args.format == 'vcf' + or (args.input_file and + re.search(r'\.vcf(\.gz)?$|\.bcf$', args.input_file, re.IGNORECASE))) + ) + if use_cyvcf2: + process_cyvcf2(args, output_fh) + else: + process_generic(args, output_fh) + finally: + if output_fh is not sys.stdout: + output_fh.close() + + +if __name__ == '__main__': + main() diff --git a/bin/license_message.py b/bin/license_message.py new file mode 100644 index 000000000..9ba2abba3 --- /dev/null +++ b/bin/license_message.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +######################################### +# Author: [DonFreed](https://github.com/DonFreed) +# File: license_message.py +# Source: https://github.com/DonFreed/docker-actions-test/blob/main/.github/scripts/license_message.py +# Source+commit: https://github.com/DonFreed/docker-actions-test/blob/aa1051a9f53b3a1e801953748d062cad74dca9a9/.github/scripts/license_message.py +# Download Date: 2023-07-04, commit: aa1051a +# This source code is licensed under the BSD 2-Clause license +######################################### + +""" +Functions for generating and sending license messages +""" + +# Modified from - https://stackoverflow.com/a/59835994 + +import argparse +import base64 +import calendar +import re +import secrets +import sys + +from cryptography.hazmat.primitives.ciphers.aead import AESGCM +from datetime import datetime as dt + +MESSAGE_TIMEOUT = 60 * 60 * 24 # Messages are valid for 1 day +NONCE_BYTES = 12 + + +class DecryptionTimeout(Exception): + # Decrypting a message that is too old + pass + + +def generate_key(): + key = secrets.token_bytes(32) + return key + + +def handle_generate_key(args): + key = generate_key() + key_b64 = base64.b64encode(key) + print(key_b64.decode("utf-8"), file=args.outfile) + + +def encrypt_message(key, message): + nonce = secrets.token_bytes(NONCE_BYTES) + timestamp = calendar.timegm(dt.now().utctimetuple()) + data = timestamp.to_bytes(10, byteorder="big") + b"__" + message + ciphertext = nonce + AESGCM(key).encrypt(nonce, data, b"") + return ciphertext + + +def handle_encrypt_message(args): + key = base64.b64decode(args.key.encode("utf-8")) + message = args.message.encode("utf-8") + ciphertext = encrypt_message(key, message) + ciphertext_b64 = base64.b64encode(ciphertext) + print(ciphertext_b64.decode("utf-8"), file=args.outfile) + + +def decrypt_message(key, ciphertext, timeout=MESSAGE_TIMEOUT): + nonce, ciphertext = ciphertext[:NONCE_BYTES], ciphertext[NONCE_BYTES:] + message = AESGCM(key).decrypt(nonce, ciphertext, b"") + + msg_timestamp, message = re.split(b"__", message, maxsplit=1) + msg_timestamp = int.from_bytes(msg_timestamp, byteorder="big") + timestamp = calendar.timegm(dt.now().utctimetuple()) + if (timestamp - msg_timestamp) > timeout: + raise DecryptionTimeout("The message has an expired timeout") + return message.decode("utf-8") + + +def handle_decrypt_message(args): + key = base64.b64decode(args.key.encode("utf-8")) + ciphertext = base64.b64decode(args.message.encode("utf-8")) + message = decrypt_message(key, ciphertext, timeout=args.timeout) + print(str(message), file=args.outfile) + + +def parse_args(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--outfile", default=sys.stdout, type=argparse.FileType("w"), help="The output file") + + subparsers = parser.add_subparsers(help="Available sub-commands") + + gen_parser = subparsers.add_parser("generate_key", help="Generate a random key string") + gen_parser.set_defaults(func=handle_generate_key) + + encrypt_parser = subparsers.add_parser("encrypt", help="Encrypt a message") + encrypt_parser.add_argument("--key", required=True, help="The encryption key") + encrypt_parser.add_argument("--message", required=True, help="Message to encrypt") + encrypt_parser.set_defaults(func=handle_encrypt_message) + + decrypt_parser = subparsers.add_parser("decrypt", help="Decyrpt a message") + decrypt_parser.add_argument("--key", required=True, help="The encryption key") + decrypt_parser.add_argument("--message", required=True, help="Message to decrypt") + decrypt_parser.add_argument( + "--timeout", + default=MESSAGE_TIMEOUT, + type=int, + help="A message timeout. Decryption will fail for older messages", + ) + decrypt_parser.set_defaults(func=handle_decrypt_message) + + return parser.parse_args(argv) + + +if __name__ == "__main__": + args = parse_args() + args.func(args) diff --git a/bin/parse_contamination.py b/bin/parse_contamination.py new file mode 100755 index 000000000..5f5b3f1e0 --- /dev/null +++ b/bin/parse_contamination.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +"""Parse GATK CalculateContamination output for MultiQC.""" + +import argparse + + +def parse_contamination(contamination_table, sample_id, prefix): + """Parse contamination table and write MultiQC output.""" + with open(contamination_table, 'r') as f: + lines = f.readlines() + data_line = lines[1].strip().split('\t') + contamination = float(data_line[1]) + contamination_pct = contamination * 100 + + with open(f"{prefix}_contamination_mqc.tsv", 'w') as out: + out.write("# id: 'gatk_contamination'\n") + out.write("# section_name: 'GATK Contamination'\n") + out.write("# description: 'Sample contamination estimates from GATK CalculateContamination'\n") + out.write("# plot_type: 'generalstats'\n") + out.write("# pconfig:\n") + out.write("# contamination_pct:\n") + out.write("# title: 'Contamination'\n") + out.write("# description: 'Estimated sample contamination percentage'\n") + out.write("# max: 10\n") + out.write("# min: 0\n") + out.write("# scale: 'RdYlGn-rev'\n") + out.write("# suffix: '%'\n") + out.write("# format: '{:,.2f}'\n") + out.write("Sample\tcontamination_pct\n") + out.write(f"{sample_id}\t{contamination_pct:.4f}\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Parse GATK contamination output for MultiQC") + parser.add_argument("--input", required=True, help="GATK contamination table") + parser.add_argument("--sample_id", required=True, help="Sample ID") + parser.add_argument("--prefix", required=True, help="Output prefix") + args = parser.parse_args() + + parse_contamination(args.input, args.sample_id, args.prefix) diff --git a/bin/replace_spaces_in_vcfinfo.py b/bin/replace_spaces_in_vcfinfo.py new file mode 100755 index 000000000..5263cdc6f --- /dev/null +++ b/bin/replace_spaces_in_vcfinfo.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + + +# Written by Ramprasad Neethiraj and released under the MIT license. +# See git repository (https://github.com/nf-core/raredisease) for full license text. + +from pathlib import Path +import argparse + +def main(): + parser = argparse.ArgumentParser( + description="Reformat VCF by replacing spaces with underscores in INFO field" + ) + parser.add_argument( + "--input", + required=True, + help="Path to input VCF file" + ) + + args = parser.parse_args() + + input_path = Path(args.input) + output_fn = input_path.stem + "_reformatted.vcf" + + with input_path.open() as input_file, open(output_fn, "w") as output: + for line in input_file: + if line.startswith("#"): + output.write(line) + else: + spl = line.rstrip("\n").split("\t") + if len(spl) > 7: + spl[7] = spl[7].replace(" ", "_") #update INFO column + output.write("\t".join(spl) + "\n") + + +if __name__ == "__main__": + main() diff --git a/bin/saltshaker_to_html.py b/bin/saltshaker_to_html.py new file mode 100755 index 000000000..07d3a6b1d --- /dev/null +++ b/bin/saltshaker_to_html.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +import re +import typer +from pathlib import Path +from typing import List, Optional + + +CSS = """.tabcontent { display: none; } +.tabcontent.active { display: block; } +.tablinks { padding: 12px 20px; cursor: pointer; background-color: #f1f1f1; border: 1px solid #ccc; } +.tablinks.active { background-color: #4CAF50; color: white; } +.tablinks:hover { background-color: #ddd; } +""" + + +JS = """ +function openTab(evt, tabName) { + var i, tabcontent, tablinks; + tabcontent = document.getElementsByClassName("tabcontent"); + for (i = 0; i < tabcontent.length; i++) { + tabcontent[i].classList.remove("active"); + } + tablinks = document.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].classList.remove("active"); + } + document.getElementById(tabName).classList.add("active"); + evt.currentTarget.classList.add("active"); +} +document.getElementsByClassName("tablinks")[0].click(); +""" + +def sort_inputs(inputs, sample_ids): + zipped = list(zip(inputs, sample_ids)) + sorted_zipped = sorted(zipped, key=lambda x: x[0].name) + sorted_inputs = [x[0] for x in sorted_zipped] + sorted_sample_ids = [x[1] for x in sorted_zipped] + return sorted_inputs, sorted_sample_ids + + +def txt_to_html(txt_file): + with open(txt_file) as tf: + content = tf.read() + html_content = re.sub(r'\\n', '
    ', content) + return html_content + + +def create_tab_button(sample_id): + return f'''\n''' + + +def create_tab_content(sample_id, txt_file): + html_content = txt_to_html(txt_file) + return f'''
    +\t

    {sample_id}

    +\t
    {html_content}
    +
    +''' + + +app = typer.Typer() + +@app.command() +def main( + input: List[Path] = typer.Option( + ..., + "--input", + exists=True, + file_okay=True, + dir_okay=False, + help="Path to input .txt file (can be multiple)" + ), + sample: List[str] = typer.Option( + ..., + "--sample", + help="Sample ID(s) corresponding to the input .txt file(s)" + ), + output: Path = typer.Option( + ..., + "--output", + help="Path to output .html file" + ) +): + if len(input) != len(sample): + raise typer.BadParameter( + "--input and --sample must have the same number of values" + ) + input, sample = sort_inputs(input, sample) + tab_buttons = ''.join(create_tab_button(sid) for sid in sample) + tab_contents = ''.join(create_tab_content(sid, inp) for inp, sid in zip(input, sample)) + + html = f""" + + + + +
    +{tab_buttons} +
    +{tab_contents} + + +""" + + with open(output, 'w') as f: + f.write(html) + +if __name__ == "__main__": + app() diff --git a/bin/sanity_check_vcfanno_databases.py b/bin/sanity_check_vcfanno_databases.py new file mode 100755 index 000000000..7da092ab9 --- /dev/null +++ b/bin/sanity_check_vcfanno_databases.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +# Written by Ramprasad Neethiraj and released under the MIT license. +# See git repository (https://github.com/nf-core/raredisease) for full license text. + +import argparse +import gzip +import re +import sys +from pathlib import Path + + +INDEX_SUFFIXES = {".tbi", ".csi", ".bai"} + + +def has_records(path: Path) -> bool: + if path.suffix in INDEX_SUFFIXES: + return True + open_fn = gzip.open if path.suffix in {".gz", ".bgz"} else open + with open_fn(path, "rt") as fh: + for line in fh: + if not line.startswith("#") and line.strip(): + return True + return False + + +def split_toml(content: str): + """Return (header, blocks) where blocks is a list of [[annotation]] block strings.""" + parts = re.split(r"(?=\[\[annotation\]\])", content) + return parts[0], parts[1:] + + +def block_filename(block: str) -> str | None: + match = re.search(r'^file\s*=\s*["\']([^"\']+)["\']', block, re.MULTILINE) + if match: + return Path(match.group(1)).name + return None + + +def main(): + parser = argparse.ArgumentParser( + description="Check vcfanno database files and remove zero-record entries from the TOML" + ) + parser.add_argument("--toml", required=True, help="Path to vcfanno TOML config file") + parser.add_argument( + "--databases", + nargs="+", + required=True, + help="Paths to vcfanno database files", + ) + args = parser.parse_args() + + empty_basenames = set() + for db in args.databases: + path = Path(db) + if not has_records(path): + print(f"WARNING: {path.name} has zero records — removing from TOML", file=sys.stderr) + empty_basenames.add(path.name) + else: + print(f"{path.name}: has records") + + toml_path = Path(args.toml) + content = toml_path.read_text() + header, blocks = split_toml(content) + + filtered_blocks = [b for b in blocks if block_filename(b) not in empty_basenames] + removed = len(blocks) - len(filtered_blocks) + if removed: + print(f"Removed {removed} annotation block(s) from TOML.", file=sys.stderr) + + output_path = Path(toml_path.stem + "_filtered.toml") + output_path.write_text(header + "".join(filtered_blocks)) + print(f"Filtered TOML written to {output_path}") + + +if __name__ == "__main__": + main() diff --git a/conf/base.config b/conf/base.config index 9494718ff..b5f88ba6f 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' @@ -59,6 +59,7 @@ process { } withLabel: process_gpu { ext.use_gpu = { workflow.profile.contains('gpu') } + accelerator = { workflow.profile.contains('gpu') ? 1 : null } } withName: 'NFCORE_RAREDISEASE:RAREDISEASE:.*' { publishDir = [ diff --git a/conf/containers_conda_lock_files_amd64.config b/conf/containers_conda_lock_files_amd64.config new file mode 100644 index 000000000..d3ee1b4ee --- /dev/null +++ b/conf/containers_conda_lock_files_amd64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt' } } +process { withName: 'MULTIQC' { container = 'modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt' } } diff --git a/conf/containers_conda_lock_files_arm64.config b/conf/containers_conda_lock_files_arm64.config new file mode 100644 index 000000000..2b90ac4fc --- /dev/null +++ b/conf/containers_conda_lock_files_arm64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt' } } +process { withName: 'MULTIQC' { container = 'modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt' } } diff --git a/conf/containers_docker_amd64.config b/conf/containers_docker_amd64.config new file mode 100644 index 000000000..65f1814a0 --- /dev/null +++ b/conf/containers_docker_amd64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'community.wave.seqera.io/library/fastqc:0.12.1--5cb1a2fa2f18c7c2' } } +process { withName: 'MULTIQC' { container = 'community.wave.seqera.io/library/multiqc:1.34--db7c73dae76bc9e6' } } diff --git a/conf/containers_docker_arm64.config b/conf/containers_docker_arm64.config new file mode 100644 index 000000000..6c845ba4b --- /dev/null +++ b/conf/containers_docker_arm64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'community.wave.seqera.io/library/fastqc:0.12.1--e455e32f745abe68' } } +process { withName: 'MULTIQC' { container = 'community.wave.seqera.io/library/multiqc:1.34--d167b8012595a136' } } diff --git a/conf/containers_singularity_https_amd64.config b/conf/containers_singularity_https_amd64.config new file mode 100644 index 000000000..838f2484f --- /dev/null +++ b/conf/containers_singularity_https_amd64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f2/f20b021476d1d87658820f971ebecc1e8cdbde0f338eb0d9cea2b0a8fc54a54b/data' } } +process { withName: 'MULTIQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/1b/1bef8af6be88c5733461959c46ac8ef73d18f65277f62a1695d0e1633054f9c2/data' } } diff --git a/conf/containers_singularity_https_arm64.config b/conf/containers_singularity_https_arm64.config new file mode 100644 index 000000000..090173be1 --- /dev/null +++ b/conf/containers_singularity_https_arm64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/46/46daf2dad0169afd2ae047c3e50ed3776259f664bf07e5e06b045dc23449e994/data' } } +process { withName: 'MULTIQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9a/9a1fec9662a152683e6fcae440d0ce20920b3b89dc62d1e3a52e73f92eba0969/data' } } diff --git a/conf/containers_singularity_oras_amd64.config b/conf/containers_singularity_oras_amd64.config new file mode 100644 index 000000000..773f3698b --- /dev/null +++ b/conf/containers_singularity_oras_amd64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'oras://community.wave.seqera.io/library/fastqc:0.12.1--5c4bd442468d75dd' } } +process { withName: 'MULTIQC' { container = 'oras://community.wave.seqera.io/library/multiqc:1.34--4fc8657c816047c0' } } diff --git a/conf/containers_singularity_oras_arm64.config b/conf/containers_singularity_oras_arm64.config new file mode 100644 index 000000000..798cc638d --- /dev/null +++ b/conf/containers_singularity_oras_arm64.config @@ -0,0 +1,2 @@ +process { withName: 'FASTQC' { container = 'oras://community.wave.seqera.io/library/fastqc:0.12.1--127a87fc06499035' } } +process { withName: 'MULTIQC' { container = 'oras://community.wave.seqera.io/library/multiqc:1.34--7fbd82d945c06726' } } diff --git a/conf/modules/align.config b/conf/modules/align.config index c605a1586..cf3dcac18 100644 --- a/conf/modules/align.config +++ b/conf/modules/align.config @@ -19,20 +19,25 @@ process{ '--correction', '--overrepresentation_analysis' ].join(' ').trim() } - publishDir = [ - path: { "${params.outdir}/trimming" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } - withName: '.*ALIGN:SAMTOOLS_VIEW' { - ext.args = { '--output-fmt cram --write-index' } - ext.prefix = { "${meta.id}_sort_md" } - publishDir = [ - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] + withName: '.*ALIGN:CONVERTTOCRAM_ALTFILTERED' { + ext.args = { '--output-fmt cram' } + ext.prefix = { "${meta.id}_sorted_md_primary_contigs" } + } + + withName: '.*ALIGN:CONVERTTOCRAM_UNFILTERED' { + ext.args = { '--output-fmt cram' } + ext.prefix = { "${meta.id}_sorted_md" } + } + + withName: '.*ALIGN:SAMTOOLS_VIEW_EXCLUDE_ALT' { + ext.args = { '--fetch-pairs' } + ext.args2 = { + params.genome == 'GRCh38' + ? ((1..22).collect { n -> "chr${n}" } + ['chrX', 'chrY', 'chrM']).join(' ') + : ((1..22).collect { n -> "${n}" } + ['X', 'Y', 'MT' ]).join(' ') + } + ext.prefix = { "${meta.id}_sorted_md_primary_contigs" } } } diff --git a/conf/modules/align_bwa_bwamem2_bwameme.config b/conf/modules/align_bwa_bwamem2_bwameme.config index ce28d4380..c2711965e 100644 --- a/conf/modules/align_bwa_bwamem2_bwameme.config +++ b/conf/modules/align_bwa_bwamem2_bwameme.config @@ -17,6 +17,13 @@ process { + withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:BWAFASTALIGN_MEM' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-m ${params.mbuffer_mem}M" } + ext.args3 = { "-T ./samtools_sort_tmp -@ ${params.samtools_sort_threads} -m ${(params.mbuffer_mem / params.samtools_sort_threads).intValue()}M" } + ext.prefix = { "${meta.id}_sorted" } + } + withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:BWAMEM2_MEM' { ext.args = { "-M -K 100000000 -R ${meta.read_group}" } ext.args2 = { "-T ./samtools_sort_tmp" } @@ -30,10 +37,10 @@ process { } withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:BWAMEME_MEM' { - ext.args = { "-7 -M -K 100000000 -R ${meta.read_group}" } - ext.args2 = { "-T ./samtools_sort_tmp" } + ext.args = { "-7 -M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-m ${params.mbuffer_mem}M" } + ext.args3 = { "-T ./samtools_sort_tmp -@ ${params.samtools_sort_threads} -m ${(params.mbuffer_mem / params.samtools_sort_threads).intValue()}M" } ext.prefix = { "${meta.id}_sorted" } - ext.when = { params.aligner.equals("bwameme") } } withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:BWA' { @@ -58,20 +65,5 @@ process { withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:MARKDUPLICATES' { ext.args = "--TMP_DIR ." ext.prefix = { "${meta.id}_sorted_md" } - publishDir = [ - enabled: !params.save_mapped_as_cram, - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*ALIGN:ALIGN_BWA_BWAMEM2_BWAMEME:SAMTOOLS_INDEX_MARKDUP' { - publishDir = [ - enabled: !params.save_mapped_as_cram, - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/align_sentieon.config b/conf/modules/align_sentieon.config index 9a92b6057..13c051221 100644 --- a/conf/modules/align_sentieon.config +++ b/conf/modules/align_sentieon.config @@ -38,11 +38,5 @@ process { withName: '.*ALIGN:ALIGN_SENTIEON:SENTIEON_DEDUP' { ext.args4 = { params.rmdup ? "--rmdup" : '' } ext.prefix = { "${meta.id}_dedup.bam" } - publishDir = [ - enabled: !params.save_mapped_as_cram, - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/annotate_cadd.config b/conf/modules/annotate_cadd.config index 9034887fc..7cce27e23 100644 --- a/conf/modules/annotate_cadd.config +++ b/conf/modules/annotate_cadd.config @@ -21,7 +21,7 @@ process { } withName: '.*:ANNOTATE_CADD:BCFTOOLS_VIEW' { - ext.args = { "--output-type z --types indels,other" } + ext.args = { "--output-type z --write-index=tbi --types indels,other" } ext.prefix = { "${vcf.simpleName}_indels" } } @@ -35,7 +35,23 @@ process { } withName: '.*:ANNOTATE_CADD:BCFTOOLS_ANNOTATE' { - ext.args = { "--columns Chrom,Pos,Ref,Alt,-,CADD --output-type z" } + ext.args = { "--columns Chrom,Pos,Ref,Alt,-,CADD --output-type z --write-index=tbi" } ext.prefix = { "${input.simpleName}_ann" } } + + withName: '.*:ANNOTATE_CADD:CADD_TO_REFERENCE_CHRNAMES' { + ext.args2 = '\'{original=$1; sub("chr","",$1); print $1, original}\'' + ext.prefix = "cadd_to_reference" + ext.suffix = "txt" + } + + withName: '.*:ANNOTATE_CADD:REFERENCE_TO_CADD_CHRNAMES' { + ext.args2 = '\'{original=$1; sub("chr","",$1); print original, $1}\'' + ext.prefix = "reference_to_cadd" + ext.suffix = "txt" + } + + withName: '.*:ANNOTATE_CADD:RENAME_CHRNAMES' { + ext.args = { "--output-type z" } + } } diff --git a/conf/modules/annotate_consequence_pli.config b/conf/modules/annotate_consequence_pli.config index 21e2e8358..42b988256 100644 --- a/conf/modules/annotate_consequence_pli.config +++ b/conf/modules/annotate_consequence_pli.config @@ -14,65 +14,47 @@ process { - withName: '.*ANN_CSQ_PLI_SV:ADD_MOST_SEVERE_CSQ' { + withName: '.*ANN_CSQ_PLI_SV:CUSTOM_ADDMOSTSEVERECONSEQUENCE' { ext.prefix = { "${meta.id}_sv_csq_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_SV:ADD_MOST_SEVERE_PLI' { + withName: '.*ANN_CSQ_PLI_SV:CUSTOM_ADDMOSTSEVEREPLI' { ext.prefix = { "${meta.id}_sv_csq_pli_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_SV:TABIX_BGZIPTABIX' { - ext.prefix = { "${meta.id}_sv_csq_pli_${meta.set}" } - } } process { - withName: '.*ANN_CSQ_PLI_SNV:ADD_MOST_SEVERE_CSQ' { + withName: '.*ANN_CSQ_PLI_SNV:CUSTOM_ADDMOSTSEVERECONSEQUENCE' { ext.prefix = { "${meta.id}_snv_csq_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_SNV:ADD_MOST_SEVERE_PLI' { + withName: '.*ANN_CSQ_PLI_SNV:CUSTOM_ADDMOSTSEVEREPLI' { ext.prefix = { "${meta.id}_snv_csq_pli_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_SNV:TABIX_BGZIPTABIX' { - ext.prefix = { "${meta.id}_snv_csq_pli_${meta.set}" } - } } process { - withName: '.*ANN_CSQ_PLI_MT:ADD_MOST_SEVERE_CSQ' { + withName: '.*ANN_CSQ_PLI_MT:CUSTOM_ADDMOSTSEVERECONSEQUENCE' { ext.prefix = { "${meta.id}_mt_csq_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_MT:ADD_MOST_SEVERE_PLI' { + withName: '.*ANN_CSQ_PLI_MT:CUSTOM_ADDMOSTSEVEREPLI' { ext.prefix = { "${meta.id}_mt_csq_pli_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_MT:TABIX_BGZIPTABIX' { - ext.prefix = { "${meta.id}_mt_csq_pli_${meta.set}" } - } } process { - withName: '.*ANN_CSQ_PLI_ME:ADD_MOST_SEVERE_CSQ' { + withName: '.*ANN_CSQ_PLI_ME:CUSTOM_ADDMOSTSEVERECONSEQUENCE' { ext.prefix = { "${meta.id}_me_csq_${meta.set}" } } - withName: '.*ANN_CSQ_PLI_ME:ADD_MOST_SEVERE_PLI' { + withName: '.*ANN_CSQ_PLI_ME:CUSTOM_ADDMOSTSEVEREPLI' { ext.prefix = { "${meta.id}_me_pli_${meta.set}" } } - - withName: '.*ANN_CSQ_PLI_ME:TABIX_BGZIPTABIX' { - ext.prefix = { "${meta.id}_me_annotated_${meta.set}" } - publishDir = [ - path: { "${params.outdir}/annotate_mobile_elements" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } } diff --git a/conf/modules/annotate_genome_snvs.config b/conf/modules/annotate_genome_snvs.config index de3b4210b..6a1a3736b 100644 --- a/conf/modules/annotate_genome_snvs.config +++ b/conf/modules/annotate_genome_snvs.config @@ -18,7 +18,6 @@ process { withName: '.*ANNOTATE_GENOME_SNVS:BCFTOOLS_ROH' { - ext.when = { meta.probands.size()>0 } ext.args = { "--samples ${meta.probands.unique().first()} --skip-indels " } ext.prefix = { "${meta.id}_roh" } } @@ -55,11 +54,6 @@ process { ext.prefix = { "${meta7.upd_child}_chromograph_sites" } ext.args = { "--euploid" } tag = {"${meta7.upd_child}"} - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*ANNOTATE_GENOME_SNVS:CHROMOGRAPH_REGIONS' { @@ -67,11 +61,6 @@ process { ext.args = { '--euploid' } ext.when = { !(workflow.profile.tokenize(',').intersect(['test', 'test_singleton', 'test_sentieon', 'test_full']).size() >= 1) || workflow.stubRun } tag = {"${meta6.upd_child}"} - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*ANNOTATE_GENOME_SNVS:ZIP_TABIX_VCFANNO' { @@ -80,7 +69,7 @@ process { withName: '.*ANNOTATE_GENOME_SNVS:BCFTOOLS_VIEW' { ext.prefix = { "${meta.prefix}_filter_${meta.scatterid}" } - ext.args = { '--output-type z --exclude "INFO/GNOMADAF > 0.70 | INFO/GNOMADAF_popmax > 0.70" ' } + ext.args = { '--output-type z --write-index=tbi --exclude "INFO/GNOMADAF > 0.70 | INFO/GNOMADAF_popmax > 0.70" ' } } withName: '.*ANNOTATE_GENOME_SNVS:ENSEMBLVEP_SNV' { @@ -102,19 +91,7 @@ process { } withName: '.*ANNOTATE_GENOME_SNVS:BCFTOOLS_CONCAT' { + ext.args = { "--output-type z --write-index=tbi" } ext.prefix = { "${meta.prefix}_vep" } - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*ANNOTATE_GENOME_SNVS:TABIX_BCFTOOLS_CONCAT' { - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/annotate_mt_snvs.config b/conf/modules/annotate_mt_snvs.config index cda985d99..adddea74b 100644 --- a/conf/modules/annotate_mt_snvs.config +++ b/conf/modules/annotate_mt_snvs.config @@ -37,21 +37,6 @@ process { '--uniprot' ].join(' ') } ext.prefix = { "${meta.prefix}" } - publishDir = [ - path: { "${params.outdir}/annotate_snv/mitochondria" }, - mode: params.publish_dir_mode, - pattern: "*{vcf.gz,vcf.gz.tbi}", - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*ANNOTATE_MT_SNVS:TABIX_TABIX_VEP_MT' { - publishDir = [ - path: { "${params.outdir}/annotate_snv/mitochondria" }, - mode: params.publish_dir_mode, - pattern: "*{vcf.gz,vcf.gz.tbi}", - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*ANNOTATE_MT_SNVS:VCFANNO_MT' { @@ -62,13 +47,9 @@ process { ext.prefix = { "${meta.prefix}" } } - withName: '.*ANNOTATE_MT_SNVS:HAPLOGREP3_CLASSIFY_MT' { - ext.args = '--tree phylotree-rsrs@17.1' - ext.prefix = { "${meta.prefix}_haplogrep" } - publishDir = [ - path: { "${params.outdir}/annotate_snv/mitochondria" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] + withName: '.*:ANNOTATE_MT_SNVS:BCFTOOLS_PLUGINSETGT' { + ext.prefix = { "${meta.prefix}_mt_modifiedgt" } + ext.args = "--output-type z --write-index=tbi" + ext.args2 = { "-i 'FMT/AF>=${params.homoplasmy_af_threshold} && FMT/DP>=100'" } } } diff --git a/conf/modules/annotate_rhocallviz.config b/conf/modules/annotate_rhocallviz.config index 82cc1f7bb..28296e484 100644 --- a/conf/modules/annotate_rhocallviz.config +++ b/conf/modules/annotate_rhocallviz.config @@ -19,7 +19,7 @@ process { withName: '.*ANNOTATE_GENOME_SNVS:ANNOTATE_RHOCALLVIZ:BCFTOOLS_VIEW_RHOCALL' { ext.prefix = { "${meta.sample}" } - ext.args = { "--output-type z --min-ac 1 --samples ${meta.sample}" } + ext.args = { "--output-type z --write-index=tbi --min-ac 1 --samples ${meta.sample}" } } withName: '.*ANNOTATE_GENOME_SNVS:ANNOTATE_RHOCALLVIZ:BCFTOOLS_ROH' { @@ -35,31 +35,16 @@ process { withName: '.*ANNOTATE_GENOME_SNVS:ANNOTATE_RHOCALLVIZ:RHOCALL_VIZ' { ext.prefix = { "${meta.sample}_rhocallviz" } ext.args = { "--aftag GNOMADAF --wig" } - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*ANNOTATE_GENOME_SNVS:ANNOTATE_RHOCALLVIZ:CHROMOGRAPH_AUTOZYG' { ext.prefix = { "${autozyg.simpleName}_autozyg_chromograph" } ext.args = { "--euploid" } ext.when = { !(workflow.profile.tokenize(',').intersect(['test', 'test_singleton', 'test_sentieon', 'test_full']).size() >= 1) || workflow.stubRun } - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome/" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*ANNOTATE_GENOME_SNVS:ANNOTATE_RHOCALLVIZ:UCSC_WIGTOBIGWIG' { ext.prefix = { "${meta.sample}_rhocallviz" } ext.args = { "-clip" } - publishDir = [ - path: { "${params.outdir}/annotate_snv/genome/${meta.sample}_rhocallviz" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/annotate_structural_variants.config b/conf/modules/annotate_structural_variants.config index b8af1e888..b9c98b920 100644 --- a/conf/modules/annotate_structural_variants.config +++ b/conf/modules/annotate_structural_variants.config @@ -18,12 +18,10 @@ process { withName: '.*ANNOTATE_STRUCTURAL_VARIANTS:SVDB_QUERY_BEDPE' { - ext.when = {!params.svdb_query_bedpedbs.equals(null)} ext.prefix = { "${meta.id}_bedpedb" } } withName: '.*ANNOTATE_STRUCTURAL_VARIANTS:SVDB_QUERY_DB' { - ext.when = {!params.svdb_query_dbs.equals(null)} ext.prefix = { "${meta.id}_vcfdb" } } @@ -49,18 +47,5 @@ process { '--symbol --tsl --uniprot --vcf' ].join(' ') } ext.prefix = { "${meta.id}_svdbquery_vep" } - publishDir = [ - path: { "${params.outdir}/annotate_sv" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*ANNOTATE_STRUCTURAL_VARIANTS:TABIX_VEP' { - publishDir = [ - path: { "${params.outdir}/annotate_sv" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/call_mobile_elements.config b/conf/modules/call_mobile_elements.config index fd6bf61c2..dfa59f3fb 100644 --- a/conf/modules/call_mobile_elements.config +++ b/conf/modules/call_mobile_elements.config @@ -27,7 +27,7 @@ process { } withName: '.*CALL_MOBILE_ELEMENTS:RETROSEQ_CALL' { - ext.args = { '--soft' } + ext.args = { "--soft --region ${meta.interval}" } ext.prefix = { "${meta.id}_${meta.interval}_retroseq_call" } } @@ -44,24 +44,11 @@ process { withName: '.*CALL_MOBILE_ELEMENTS:BCFTOOLS_CONCAT_ME' { ext.args = { '--output-type z --allow-overlaps' } - ext.prefix = { "${meta.id}_mobile_elements" } + ext.prefix = { "${meta.id}_mobile_elements_concat" } } withName: '.*CALL_MOBILE_ELEMENTS:SVDB_MERGE_ME' { ext.args = { '--bnd_distance 150 --overlap 0.5' } ext.prefix = { "${meta.id}_mobile_elements" } - publishDir = [ - path: { "${params.outdir}/call_mobile_elements" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*CALL_MOBILE_ELEMENTS:TABIX_ME' { - publishDir = [ - path: { "${params.outdir}/call_mobile_elements" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/call_repeat_expansions.config b/conf/modules/call_repeat_expansions.config index fd6738ae9..88b4320f2 100644 --- a/conf/modules/call_repeat_expansions.config +++ b/conf/modules/call_repeat_expansions.config @@ -23,30 +23,12 @@ process { withName: '.*CALL_REPEAT_EXPANSIONS:SAMTOOLS_SORT' { ext.prefix = { "${meta.id}_exphunter_sorted" } - publishDir = [ - path: { "${params.outdir}/repeat_expansions" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] - } - - withName: '.*CALL_REPEAT_EXPANSIONS:SAMTOOLS_INDEX' { - publishDir = [ - path: { "${params.outdir}/repeat_expansions" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } withName: '.*CALL_REPEAT_EXPANSIONS:BCFTOOLS_REHEADER_EXP' { ext.args = "--temp-prefix ." - ext.args2 = "-O v" + ext.args2 = "--output-type v" ext.prefix = { "${meta.id}_repeat_expansion" } - publishDir = [ - path: { "${params.outdir}/repeat_expansions" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } withName: '.*CALL_REPEAT_EXPANSIONS:SPLIT_MULTIALLELICS_EXP' { diff --git a/conf/modules/call_snv.config b/conf/modules/call_snv.config index 58ad7b337..f5184c021 100644 --- a/conf/modules/call_snv.config +++ b/conf/modules/call_snv.config @@ -16,21 +16,10 @@ process { withName: '.*CALL_SNV:GATK4_SELECTVARIANTS' { ext.args = { "--exclude-intervals ${params.mito_name}" } ext.prefix = { "${meta.id}_snv" } - publishDir = [ - path: { "${params.outdir}/call_snv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*CALL_SNV:BCFTOOLS_CONCAT' { - ext.args = { "--write-index=tbi" } + ext.args = { "--write-index=tbi --output-type z" } ext.prefix = { "${meta.id}_mt_and_nuclear_snvs" } - publishDir = [ - enabled: params.concatenate_snv_calls, - path: { "${params.outdir}/call_snv/concatenated_calls" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/call_snv_MT.config b/conf/modules/call_snv_MT.config index f77d2f6b1..72442a992 100644 --- a/conf/modules/call_snv_MT.config +++ b/conf/modules/call_snv_MT.config @@ -26,14 +26,6 @@ process { ext.prefix = { "${meta.id}_filtered" } } - withName: '.*CALL_SNV:CALL_SNV_MT:HAPLOCHECK_MT' { - publishDir = [ - path: { "${params.outdir}/haplocheck" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.endsWith(".txt") ? filename : null } - ] - } - } // @@ -51,8 +43,4 @@ process { ext.prefix = { "${meta.id}_filtered_shifted" } } - withName: '.*CALL_SNV_MT_SHIFT:HAPLOCHECK_MT' { - ext.when = false - } - } diff --git a/conf/modules/call_snv_deepvariant.config b/conf/modules/call_snv_deepvariant.config index 3bbf26061..b97ff6d74 100644 --- a/conf/modules/call_snv_deepvariant.config +++ b/conf/modules/call_snv_deepvariant.config @@ -17,12 +17,9 @@ process { - withName: '.*CALL_SNV_DEEPVARIANT:.*' { - ext.when = params.variant_caller.equals("deepvariant") - } - withName: '.*CALL_SNV_DEEPVARIANT:DEEPVARIANT' { ext.args = { [ + "--vcf_stats_report=true", "--model_type=${params.analysis_type.toUpperCase()}", meta.sex == 1 ? params.genome == 'GRCh37' ? '--haploid_contigs="X,Y"' : '--haploid_contigs="chrX,chrY"' : '' ].join(' ') } @@ -38,7 +35,7 @@ process { } withName: '.*CALL_SNV_DEEPVARIANT:REMOVE_DUPLICATES_GL' { - ext.args = '--output-type z --rm-dup none' + ext.args = '--write-index=tbi --output-type z --rm-dup none' ext.prefix = { "${meta.id}_split_rmdup" } } @@ -47,7 +44,7 @@ process { } withName: '.*CALL_SNV_DEEPVARIANT:BCFTOOLS_ANNOTATE' { - ext.args = "-c CHROM,FROM,TO,FOUND_IN --output-type z" + ext.args = "-c CHROM,FROM,TO,FOUND_IN --output-type z --write-index=tbi " ext.prefix = { "${meta.id}_split_rmdup_info" } } } diff --git a/conf/modules/call_snv_sentieon.config b/conf/modules/call_snv_sentieon.config index d5f86fb24..39085f55d 100644 --- a/conf/modules/call_snv_sentieon.config +++ b/conf/modules/call_snv_sentieon.config @@ -29,12 +29,12 @@ process { } withName: '.*CALL_SNV:CALL_SNV_SENTIEON:BCF_FILTER_ONE' { - ext.args = "-s 'ML_FAIL' -i 'INFO/ML_PROB <= 0.95' -m x -Oz --write-index=tbi" + ext.args = "-s 'ML_FAIL' -i 'INFO/ML_PROB <= 0.95' -m x --output-type z --write-index=tbi" ext.prefix = { "${meta.id}_mlfiltered_0.95" } } withName: '.*CALL_SNV:CALL_SNV_SENTIEON:BCF_FILTER_TWO' { - ext.args = "-i FILTER='\"PASS\"' -m x -Oz --write-index=tbi" + ext.args = "-i FILTER='\"PASS\"' -m x --output-type z --write-index=tbi" ext.prefix = { "${meta.id}_passed" } } @@ -44,7 +44,7 @@ process { } withName: '.*CALL_SNV:CALL_SNV_SENTIEON:REMOVE_DUPLICATES_SEN' { - ext.args = '--output-type z --rm-dup none' + ext.args = '--output-type z --rm-dup none --write-index=tbi' ext.prefix = { "${meta.id}_split_rmdup" } } @@ -53,7 +53,7 @@ process { } withName: '.*CALL_SNV:CALL_SNV_SENTIEON:BCFTOOLS_ANNOTATE' { - ext.args = "-c CHROM,FROM,TO,FOUND_IN --output-type z" + ext.args = "-c CHROM,FROM,TO,FOUND_IN --output-type z --write-index=tbi" ext.prefix = { "${meta.id}_split_rmdup_info" } } } diff --git a/conf/modules/call_structural_variants.config b/conf/modules/call_structural_variants.config index 23e9325b6..a9fcd660d 100644 --- a/conf/modules/call_structural_variants.config +++ b/conf/modules/call_structural_variants.config @@ -20,18 +20,5 @@ process { withName: '.*CALL_STRUCTURAL_VARIANTS:SVDB_MERGE' { ext.prefix = {"${meta.id}_sv"} ext.args = '--pass_only --same_order' - publishDir = [ - path: { "${params.outdir}/call_sv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*CALL_STRUCTURAL_VARIANTS:TABIX_TABIX' { - publishDir = [ - path: { "${params.outdir}/call_sv/genome" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/call_sv_MT.config b/conf/modules/call_sv_MT.config index a220615f4..2f72115f6 100644 --- a/conf/modules/call_sv_MT.config +++ b/conf/modules/call_sv_MT.config @@ -20,19 +20,33 @@ process { withName: '.*CALL_SV_MT:MT_DELETION' { ext.args = '-s --insert-size 16000' ext.prefix = { "${meta.id}_mitochondria_deletions" } - publishDir = [ - path: { "${params.outdir}/call_sv/mitochondria" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } - withName: '.*CALL_SV_MT:EKLIPSE' { - ext.args = "-tmp ." - publishDir = [ - path: { "${params.outdir}/call_sv/mitochondria" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] + withName: '.*CALL_SV_MT:SALTSHAKER_CALL' { + ext.args = '--blacklist' } + + withName: '.*CALL_SV_MT:SALTSHAKER_CLASSIFY' { + ext.args = { [ + "--blacklist --vcf", + "--dominant-fraction ${params.saltshaker_dominant_fraction}", + "--radius ${params.saltshaker_group_radius}", + "--high-het ${params.saltshaker_high_heteroplasmy}", + "--multiple-threshold ${params.saltshaker_multiple_threshold}", + "--noise ${params.saltshaker_noise_threshold}" + ].join(' ') } + } + + withName: '.*CALL_SV_MT:SALTSHAKER_TO_HTML' { + ext.prefix = { "${meta.id}.saltshaker_classify" } + } + + withName: '.*CALL_SV_MT:SALTSHAKER_PLOT' { + ext.args = '--blacklist --genes' + } + + withName: '.*CALL_SV_MT:SVDB_MERGE' { + ext.prefix = { "${meta.id}_saltshaker" } + } + } diff --git a/conf/modules/call_sv_cnvnator.config b/conf/modules/call_sv_cnvnator.config index fcd9e88ff..8ba66dac8 100644 --- a/conf/modules/call_sv_cnvnator.config +++ b/conf/modules/call_sv_cnvnator.config @@ -16,30 +16,29 @@ // process { - withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:CNVNATOR_HIST" { tag = { "$meta2.id" } - ext.args = { "-his ${params.cnvnator_binsize}" } + ext.args = { "-genome ${params.genome} -his ${params.cnvnator_binsize}" } } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:CNVNATOR_STAT" { tag = { "$meta2.id" } - ext.args = { "-stat ${params.cnvnator_binsize}" } + ext.args = { "-genome ${params.genome} -stat ${params.cnvnator_binsize}" } } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:CNVNATOR_PARTITION" { tag = { "$meta2.id" } - ext.args = { "-partition ${params.cnvnator_binsize}" } + ext.args = { "-genome ${params.genome} -partition ${params.cnvnator_binsize}" } } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:CNVNATOR_CALL" { tag = { "$meta2.id" } - ext.args = { "-call ${params.cnvnator_binsize}" } + ext.args = { "-genome ${params.genome} -call ${params.cnvnator_binsize}" } } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:CNVNATOR_CONVERT2VCF" { ext.prefix = { "${meta.id}_cnvnator" } - ext.args = { "-call ${params.cnvnator_binsize}" } + ext.args = { "-reference ${params.genome}" } } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_CNVNATOR:BCFTOOLS_VIEW_CNVNATOR" { diff --git a/conf/modules/call_sv_tiddit.config b/conf/modules/call_sv_tiddit.config index ab2cd646e..99cd42c9b 100644 --- a/conf/modules/call_sv_tiddit.config +++ b/conf/modules/call_sv_tiddit.config @@ -21,7 +21,7 @@ process { } withName: ".*CALL_STRUCTURAL_VARIANTS:CALL_SV_TIDDIT:BCFTOOLS_VIEW_TIDDIT" { - ext.prefix = { "${meta.id}_tiddit" } + ext.prefix = { "${meta.id}_tiddit_bcftools" } ext.args = { '--apply-filters .,PASS --output-type z' } } diff --git a/conf/modules/contamination_check.config b/conf/modules/contamination_check.config new file mode 100644 index 000000000..f761c2322 --- /dev/null +++ b/conf/modules/contamination_check.config @@ -0,0 +1,31 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for GATK contamination checking modules +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +process { + + // + // GATK GetPileupSummaries + // + withName: '.*:CONTAMINATION_CHECK:GATK4_GETPILEUPSUMMARIES' { + ext.args = '' + ext.prefix = { "${meta.id}_pileups" } + } + + // + // GATK CalculateContamination + // + withName: '.*:CONTAMINATION_CHECK:GATK4_CALCULATECONTAMINATION' { + ext.args = '' + ext.prefix = { "${meta.id}_contamination" } + } + + // + // Parse contamination results for MultiQC + // + withName: '.*:RAREDISEASE:PARSE_CONTAMINATION' { + ext.prefix = { "${meta.id}_contamination" } + } +} diff --git a/conf/modules/generate_cytosure_files.config b/conf/modules/generate_cytosure_files.config index 86e1fd01e..969d726cf 100644 --- a/conf/modules/generate_cytosure_files.config +++ b/conf/modules/generate_cytosure_files.config @@ -42,13 +42,9 @@ process { ext.args = { [ meta.sex == 1 ? '--sex male' : '--sex female', '--size 5000', - '--maxbnd 5000' + '--maxbnd 5000', + params.genome.equals("GRCh38") ? "--genome 38" : "" ].join(' ') } ext.prefix = { "${meta.custid}" ? "${meta.custid}" : "${meta.id}" } - publishDir = [ - path: { "${params.outdir}/vcf2cytosure" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } } diff --git a/conf/modules/gens.config b/conf/modules/gens.config index 691cacd74..683565ba8 100644 --- a/conf/modules/gens.config +++ b/conf/modules/gens.config @@ -26,10 +26,5 @@ process { withName: '.*GENS:GENS_GENERATE' { ext.prefix = { "${meta.id}_gens" } - publishDir = [ - path: { "${params.outdir}/gens" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/postprocess_MT_calls.config b/conf/modules/postprocess_MT_calls.config index 61a14131a..4bd28abf3 100644 --- a/conf/modules/postprocess_MT_calls.config +++ b/conf/modules/postprocess_MT_calls.config @@ -35,8 +35,13 @@ process { ext.prefix = { "${meta.id}_split_rmdup" } } + withName: '.*POSTPROCESS_MT_CALLS:SPLIT_MULTIALLELICS_POSTMERGE_MT' { + ext.args = '--output-type z --multiallelics -both' + ext.prefix = { "${meta.id}_split_rmdup_merged_split" } + } + withName: '.*POSTPROCESS_MT_CALLS:BCFTOOLS_MERGE_MT' { - ext.args = '--output-type z' + ext.args = '--output-type z --write-index=tbi' ext.prefix = { "${meta.id}_split_rmdup_merged" } } @@ -47,19 +52,6 @@ process { withName: '.*POSTPROCESS_MT_CALLS:BCFTOOLS_ANNOTATE' { ext.args = "-c CHROM,FROM,TO,FOUND_IN --output-type z --include FILTER='\"PASS\"'" ext.prefix = { "${meta.id}_mitochondria" } - publishDir = [ - path: { "${params.outdir}/call_snv/mitochondria" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*POSTPROCESS_MT_CALLS:TABIX_ANNOTATE' { - publishDir = [ - path: { "${params.outdir}/call_snv/mitochondria" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/prepare_references.config b/conf/modules/prepare_references.config index 50e441017..846f03d2e 100644 --- a/conf/modules/prepare_references.config +++ b/conf/modules/prepare_references.config @@ -16,96 +16,27 @@ // process { - withName: '.*PREPARE_REFERENCES:.*' { - publishDir = [ - path: { "${params.outdir}/references" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - enabled: params.save_reference, - ] - } - - withName: '.*PREPARE_REFERENCES:BWAMEM2_INDEX_GENOME' { - ext.when = {!params.bwamem2 && (params.aligner == "bwamem2" || params.mt_aligner == "bwamem2")} - } - withName: '.*PREPARE_REFERENCES:BWAMEME_INDEX_GENOME' { ext.args = '-a meme' - ext.when = {!params.bwameme && params.aligner == "bwameme"} - } - - withName: '.*PREPARE_REFERENCES:BWA_INDEX_GENOME' { - ext.when = {!params.bwa && (!(params.aligner == "sentieon") || params.mt_aligner == "bwa")} - } - - withName: '.*PREPARE_REFERENCES:SENTIEON_BWAINDEX_GENOME' { - ext.when = {!params.bwa && (params.aligner == "sentieon" || params.mt_aligner == "sentieon")} - } - - withName: '.*PREPARE_REFERENCES:BWAMEM2_INDEX_MT.*' { - ext.when = { (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) && params.mt_aligner == "bwamem2"} - } - - withName: '.*PREPARE_REFERENCES:SENTIEON_BWAINDEX_MT.*' { - ext.when = { (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) && params.mt_aligner == "sentieon"} - } - - withName: '.*PREPARE_REFERENCES:BWA_INDEX_MT.*' { - ext.when = { (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) && params.mt_aligner == "bwa"} - } - - withName: '.*PREPARE_REFERENCES:SAMTOOLS_FAIDX_GENOME' { - ext.when = {!params.fai} - } - - withName: '.*PREPARE_REFERENCES:RTGTOOLS_FORMAT' { - ext.when = { !params.sdf && params.run_rtgvcfeval } } withName: '.*PREPARE_REFERENCES:SAMTOOLS_EXTRACT_MT' { ext.args = { " ${params.mito_name} -o ${meta.id}_mt.fa" } - ext.when = {!params.mt_fasta} - } - - withName: '.*PREPARE_REFERENCES:SAMTOOLS_FAIDX_MT' { - ext.when = { (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) } - } - - withName: '.*PREPARE_REFERENCES:GATK_SD' { - ext.when = {!params.sequence_dictionary} } withName: '.*PREPARE_REFERENCES:GATK_SHIFTFASTA' { ext.args = { "--interval-file-name ${meta.id}_mt" } } - withName: '.*PREPARE_REFERENCES:GATK_SD_MT' { - ext.when = { (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes)} - } - - withName: '.*PREPARE_REFERENCES:TABIX_DBSNP' { - ext.when = {params.known_dbsnp && !params.known_dbsnp_tbi} - } - withName: '.*PREPARE_REFERENCES:TABIX_GNOMAD_AF' { - ext.when = {params.gnomad_af && !params.gnomad_af_idx} ext.args = '-s 1 -b 2 -e 2' } - withName: '.*PREPARE_REFERENCES:TABIX_PT' { - ext.when = { !params.target_bed.equals(null) && params.target_bed.endsWith(".gz") } - } - - withName: '.*PREPARE_REFERENCES:TABIX_PBT' { - ext.when = { !params.target_bed.equals(null) && !params.target_bed.endsWith(".gz") } - } - withName: '.*PREPARE_REFERENCES:TABIX_BGZIPINDEX_VCFANNOEXTRA' { ext.args2 = '--csi' } withName: '.*PREPARE_REFERENCES:BEDTOOLS_PAD_TARGET_BED' { - ext.when = { params.target_bed && params.bait_padding > 0 } ext.prefix = { "${meta.id}_pad${params.bait_padding}" } ext.args = { "-b ${params.bait_padding}" } } @@ -115,22 +46,15 @@ process { } withName: '.*PREPARE_REFERENCES:GATK_BILT' { - ext.when = { !params.target_bed.equals(null) } ext.prefix = { "${meta.id}_target" } } withName: '.*PREPARE_REFERENCES:GATK_ILT' { - ext.when = { !params.target_bed.equals(null) } ext.args = { "--PADDING ${params.bait_padding} -SUBDIVISION_MODE INTERVAL_SUBDIVISION --SCATTER_COUNT 2" } } withName: '.*PREPARE_REFERENCES:CAT_CAT_BAIT' { - ext.when = { !params.target_bed.equals(null) } ext.prefix = { "${meta.id}" } } - withName: '.*PREPARE_REFERENCES:UNTAR_VEP_CACHE' { - ext.when = { (params.vep_cache && params.vep_cache.endsWith("tar.gz")) } - } - } diff --git a/conf/modules/qc_bam.config b/conf/modules/qc_bam.config index ef8603419..52444ff73 100644 --- a/conf/modules/qc_bam.config +++ b/conf/modules/qc_bam.config @@ -16,14 +16,6 @@ // process { - withName: '.*QC_BAM:.*' { - publishDir = [ - path: { "${params.outdir}/qc_bam" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] - } - withName: '.*QC_BAM:PICARD_COLLECTMULTIPLEMETRICS' { ext.args = "--TMP_DIR ." ext.prefix = { "${meta.id}_multiplemetrics" } @@ -31,14 +23,9 @@ process { withName: '.*QC_BAM:PICARD_COLLECTHSMETRICS' { ext.args = "--TMP_DIR ." - ext.when = { !params.target_bed.equals(null) } ext.prefix = { "${meta.id}_hsmetrics" } } - withName: '.*QC_BAM:QUALIMAP_BAMQC' { - ext.prefix = { "${meta.id}_qualimap" } - } - withName: '.*QC_BAM:TIDDIT_COV' { ext.args = '-z 500 -w' ext.prefix = { "${meta.id}_tidditcov" } @@ -62,32 +49,38 @@ process { // NGSBITS_SAMPLEGENDER needs a chrX and chrY in order to run so we skip it for the two test profiles ext.when = { !(workflow.profile.tokenize(',').intersect(['test', 'test_singleton', 'test_sentieon', 'test_full']).size() >= 1) || workflow.stubRun } ext.prefix = { "${meta.id}_ngsbits_sex" } - publishDir = [ - path: { "${params.outdir}/ngsbits_samplegender" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } withName: '.*QC_BAM:PICARD_COLLECTWGSMETRICS_WG' { ext.args = "--TMP_DIR ." - ext.when = { !params.aligner.equals("sentieon") } ext.prefix = { "${meta.id}_wgsmetrics" } } withName: '.*QC_BAM:PICARD_COLLECTWGSMETRICS_Y' { ext.args = "--TMP_DIR ." - ext.when = { !params.aligner.equals("sentieon") } ext.prefix = { "${meta.id}_wgsmetrics_y" } } + withName: '.*:QC_BAM:SAMBAMBA_DEPTH' { + ext.prefix = { "${meta.id}_sambamba_depth" } + ext.args = { + [ + "--cov-threshold 10", + "--cov-threshold 15", + "--cov-threshold 20", + "--cov-threshold 50", + "--cov-threshold 100", + "--min-base-quality 10", + "--filter 'mapping_quality >= 10 and not duplicate and not failed_quality_control'", + ].join(' ') + } + } + withName: '.*QC_BAM:SENTIEON_WGSMETRICS_WG' { - ext.when = { params.aligner.equals("sentieon") } ext.prefix = { "${meta.id}_wgsmetrics" } } withName: '.*QC_BAM:SENTIEON_WGSMETRICS_Y' { - ext.when = { params.aligner.equals("sentieon") } ext.prefix = { "${meta.id}_wgsmetrics_y" } } } diff --git a/conf/modules/rank_variants.config b/conf/modules/rank_variants.config index cd5ab7c98..0c31a1cd8 100644 --- a/conf/modules/rank_variants.config +++ b/conf/modules/rank_variants.config @@ -42,26 +42,10 @@ process { } withName: '.*RANK_VARIANTS_SV:BCFTOOLS_SORT' { - ext.args = "--output-type z" + ext.args = "--output-type z --write-index=tbi" ext.prefix = { "${meta.id}_sv_ranked_${meta.set}" } - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } - withName: '.*RANK_VARIANTS_SV:TABIX_BGZIP' { - ext.when = false - } - - withName: '.*RANK_VARIANTS_SV:TABIX_TABIX' { - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } } // @@ -94,26 +78,11 @@ process { ext.args = "--temp_dir ./" } - withName: '.*RANK_VARIANTS_SNV:BCFTOOLS_SORT' { - ext.when = false - } - - withName: '.*RANK_VARIANTS_SNV:TABIX_BGZIP' { + withName: '.*RANK_VARIANTS_SNV:TABIX_BGZIPTABIX' { + ext.args2 = '-p vcf' ext.prefix = { "${meta.id}_snv_ranked_${meta.set}" } - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } - withName: '.*RANK_VARIANTS_SNV:TABIX_TABIX' { - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } } // @@ -146,24 +115,9 @@ process { ext.args = "--temp_dir ./" } - withName: '.*RANK_VARIANTS_MT:BCFTOOLS_SORT' { - ext.when = false - } - - withName: '.*RANK_VARIANTS_MT:TABIX_BGZIP' { + withName: '.*RANK_VARIANTS_MT:TABIX_BGZIPTABIX' { + ext.args2 = '-p vcf' ext.prefix = { "${meta.id}_mt_ranked_${meta.set}" } - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } - withName: '.*RANK_VARIANTS_MT:TABIX_TABIX' { - publishDir = [ - path: { "${params.outdir}/rank_and_filter" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } } diff --git a/conf/modules/raredisease.config b/conf/modules/raredisease.config index 0b01c4488..5ef1734b4 100644 --- a/conf/modules/raredisease.config +++ b/conf/modules/raredisease.config @@ -18,9 +18,6 @@ process { withName: '.*RAREDISEASE:SPRING_DECOMPRESS_.*' { ext.prefix = { "${spring.simpleName}" } - publishDir = [ - enabled: false - ] } } @@ -32,11 +29,6 @@ process { withName: '.*RAREDISEASE:FASTQC' { ext.args = '--quiet --dir ./' - publishDir = [ - path: { "${params.outdir}/fastqc/${meta.id}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } } @@ -50,11 +42,6 @@ process { (params.genome == 'GRCh37') ? '--genome 37' : '--genome 38' } ext.prefix = { "${meta.id}_smncopynumbercaller" } - publishDir = [ - path: { "${params.outdir}/smncopynumbercaller" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } } @@ -65,11 +52,6 @@ process { process { withName: '.*STRANGER' { ext.prefix = { "${meta.id}_repeat_expansion_stranger" } - publishDir = [ - path: { "${params.outdir}/repeat_expansions" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } } @@ -78,27 +60,8 @@ process { // process { - withName: '.*:PEDDY' { - publishDir = [ - path: { "${params.outdir}/peddy" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } -} - -// -// Generate Pedigree File -// - -process { - - withName: '.*RAREDISEASE:CREATE_PEDIGREE_FILE' { - publishDir = [ - path: { "${params.outdir}/pedigree" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] + withName: 'PEDDY' { + ext.args = { params.genome.equals("GRCh38") ? "--sites hg38" : "" } } } @@ -109,10 +72,5 @@ process { process { withName: '.*RAREDISEASE:MULTIQC' { ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } - publishDir = [ - path: { "${params.outdir}/multiqc" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/scatter_genome.config b/conf/modules/scatter_genome.config index b5efa9bff..e36924f17 100644 --- a/conf/modules/scatter_genome.config +++ b/conf/modules/scatter_genome.config @@ -17,14 +17,13 @@ process { + withName: '.*SCATTER_GENOME:GENOME_FAI_TO_BED' { + ext.args2 = { '\'BEGIN {SEP="\t"}; {print \$1 SEP "0" SEP \$2}\'' } + ext.suffix = "bed" + } + withName: '.*SCATTER_GENOME:GATK4_SPLITINTERVALS' { ext.args = { "--scatter-count ${params.scatter_count}" } ext.prefix = { "${meta.id}_genome_intervals" } - publishDir = [ - enabled: params.save_reference, - path: { "${params.outdir}/processed_references" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/subsample_mt.config b/conf/modules/subsample_mt_frac.config similarity index 64% rename from conf/modules/subsample_mt.config rename to conf/modules/subsample_mt_frac.config index 7ce80bed1..32ba66748 100644 --- a/conf/modules/subsample_mt.config +++ b/conf/modules/subsample_mt_frac.config @@ -16,27 +16,14 @@ // process { - withName: '.*SUBSAMPLE_MT:BEDTOOLS_GENOMECOV' { + withName: '.*SUBSAMPLE_MT_FRAC:BEDTOOLS_GENOMECOV' { ext.args = { "-dz" } ext.prefix = { "${meta.id}" } } - withName: '.*SUBSAMPLE_MT:SAMTOOLS_VIEW' { + withName: '.*SUBSAMPLE_MT_FRAC:SAMTOOLS_VIEW' { ext.args = { "--output-fmt BAM -h -F 4 -s ${meta.seedfrac}" } ext.prefix = { "${meta.id}_mt_subsample" } - publishDir = [ - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*SUBSAMPLE_MT:SAMTOOLS_INDEX' { - publishDir = [ - path: { "${params.outdir}/alignment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/subsample_mt_reads.config b/conf/modules/subsample_mt_reads.config new file mode 100644 index 000000000..5c009ba61 --- /dev/null +++ b/conf/modules/subsample_mt_reads.config @@ -0,0 +1,46 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for defining DSL2 per module options and publishing paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Available keys to override module options: + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. + ext.when = Conditional clause +---------------------------------------------------------------------------------------- +*/ + +// +// Subsample MT +// + +process { + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_VIEW' { + ext.args = { "--output-fmt bam -F 0x400" } + ext.prefix = { "${meta.id}_mt_nodups" } + } + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_COLLATE' { + ext.args = { "--output-fmt sam" } + ext.prefix = { "${meta.id}_mt_nodups_collate" } + } + + // subsample a collated SAM down to approximately mt_subsample_reads reads, while making sure that read pairs are never split + withName: '.*SUBSAMPLE_MT_READS:GAWK' { + ext.args2 = { "'/^@/ { print; next } count < ${params.mt_subsample_reads} || last == \$1 { print; last = \$1; count++ }'" } + ext.prefix = { "${meta.id}_mt_nodups_collate_awk" } + ext.suffix = "sam" + } + + withName: '.*SUBSAMPLE_MT_READS:SAM_TO_BAM' { + ext.args = { "--output-fmt bam" } + ext.prefix = { "${meta.id}_mt_nodups_collate_awk" } + } + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_SORT' { + ext.prefix = { "${meta.id}_mt_subsample" } + } + +} diff --git a/conf/modules/variant_evaluation.config b/conf/modules/variant_evaluation.config index 4059b3a72..f140922a9 100644 --- a/conf/modules/variant_evaluation.config +++ b/conf/modules/variant_evaluation.config @@ -16,27 +16,17 @@ // process { - withName: '.*VARIANT_EVALUATION.*' { - ext.when = { params.run_rtgvcfeval } - } withName: '.*VARIANT_EVALUATION:BCFTOOLS_REHEADER' { beforeScript = { "echo ${meta.samplename} > ${meta.samplename}.txt" } ext.args = { "--samples ${meta.samplename}.txt" } ext.args2 = "--output-type z" - ext.when = { params.run_rtgvcfeval } ext.prefix = { "${meta.samplename}_truthvcf" } } withName: '.*VARIANT_EVALUATION:RTGTOOLS_VCFEVAL' { ext.args = { "--sample ${meta.samplename} --output-mode=split" } - ext.when = { params.run_rtgvcfeval } ext.prefix = { "${meta.samplename}_vcfeval" } - publishDir = [ - path: { "${params.outdir}/rtgvcfeval" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/generate_clinical_set.config b/conf/modules/vcf_filter_bcftools_filtervep.config similarity index 63% rename from conf/modules/generate_clinical_set.config rename to conf/modules/vcf_filter_bcftools_filtervep.config index 143e0a6d8..6a4a927af 100644 --- a/conf/modules/generate_clinical_set.config +++ b/conf/modules/vcf_filter_bcftools_filtervep.config @@ -18,12 +18,12 @@ // SNVs process { - withName: '.*:GENERATE_CLINICAL_SET_SNV:ENSEMBLVEP_FILTERVEP' { + withName: '.*:GENERATE_CLINICAL_SET_SNV:FILTERVEP' { ext.prefix = { "${meta.id}_snv_${meta.set}" } ext.args = { "--filter \"HGNC_ID in ${feature_file}\"" } } - withName: '.*:GENERATE_CLINICAL_SET_SNV:TABIX_BGZIP' { + withName: '.*:GENERATE_CLINICAL_SET_SNV:TABIX_BGZIPTABIX' { ext.prefix = { "${meta.id}_snv_${meta.set}" } } } @@ -31,12 +31,12 @@ process { // SVs process { - withName: '.*:GENERATE_CLINICAL_SET_SV:ENSEMBLVEP_FILTERVEP' { - ext.prefix = { "${input.simpleName}_sv_${meta.set}" } + withName: '.*:GENERATE_CLINICAL_SET_SV:FILTERVEP' { + ext.prefix = { "${meta.id}_sv_${meta.set}" } ext.args = { "--filter \"HGNC_ID in ${feature_file}\"" } } - withName: '.*:GENERATE_CLINICAL_SET_SV:TABIX_BGZIP' { + withName: '.*:GENERATE_CLINICAL_SET_SV:TABIX_BGZIPTABIX' { ext.prefix = { "${meta.id}_sv_${meta.set}" } } } @@ -44,29 +44,20 @@ process { // MT variants process { - withName: '.*:GENERATE_CLINICAL_SET_MT:ENSEMBLVEP_FILTERVEP' { - ext.prefix = { "${meta.id}_mt_filtervep_${meta.set}" } - ext.args = { "--filter \"HGNC_ID in ${feature_file}\"" } - } - - withName: '.*:GENERATE_CLINICAL_SET_MT:BCFTOOLS_FILTER' { - ext.prefix = { "${meta.id}_mt_${meta.set}" } - ext.args = { "-Oz -i 'AF>0.05'" } - } - - withName: '.*:GENERATE_CLINICAL_SET_MT:TABIX_BGZIP' { + withName: '.*:GENERATE_CLINICAL_SET_MT:BCFTOOLS_VIEW' { ext.prefix = { "${meta.id}_mt_${meta.set}" } + ext.args = { "-Oz -i 'AF>0.05' --write-index=tbi" } } } // ME variants -process{ - withName: '.*:GENERATE_CLINICAL_SET_ME:ENSEMBLVEP_FILTERVEP' { +process { + withName: '.*:GENERATE_CLINICAL_SET_ME:FILTERVEP' { ext.prefix = { "${meta.id}_me_${meta.set}" } ext.args = { "--filter \"HGNC_ID in ${feature_file}\"" } } - withName: '.*:GENERATE_CLINICAL_SET_ME:TABIX_BGZIP' { + withName: '.*:GENERATE_CLINICAL_SET_ME:TABIX_BGZIPTABIX' { ext.prefix = { "${meta.id}_me_${meta.set}" } } } diff --git a/conf/test.config b/conf/test.config index 7958cf363..6c1cf3049 100644 --- a/conf/test.config +++ b/conf/test.config @@ -1,7 +1,7 @@ /* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nextflow config file for running minimal tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: @@ -14,14 +14,8 @@ process { resourceLimits = [ cpus: 4, memory: '15.GB', - time: '1.h' + time: '2.h' ] - - withName: 'ENSEMBLVEP.*' { - container = { workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' } - } } env { @@ -36,8 +30,7 @@ params { mito_name = 'MT' pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease' - skip_tools = 'fastp,gens,haplogrep3,peddy,germlinecnvcaller,qualimap,eklipse,ngsbits' - skip_subworkflows = "mt_annotation,mt_subsample,me_calling,me_annotation,sv_annotation" + skip_tools = 'fastp,gens,peddy,germlinecnvcaller,ngsbits' input = params.pipelines_testdata_base_path + '/testdata/samplesheet_fq_spring.csv' fasta = params.pipelines_testdata_base_path + '/reference/reference.fasta' @@ -65,5 +58,4 @@ params { vep_filters = params.pipelines_testdata_base_path + '/reference/hgnc.txt' vep_cache_version = 107 vep_plugin_files = params.pipelines_testdata_base_path + '/reference/vep_files.csv' - } diff --git a/conf/test_bam.config b/conf/test_bam.config index 3e164ab46..46d398682 100644 --- a/conf/test_bam.config +++ b/conf/test_bam.config @@ -16,12 +16,6 @@ process { memory: '15.GB', time: '1.h' ] - - withName: 'ENSEMBLVEP.*' { - container = { workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' } - } } env { @@ -36,8 +30,7 @@ params { mito_name = 'MT' pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' - skip_tools = 'fastp,gens,haplogrep3,peddy,germlinecnvcaller,qualimap,eklipse' - skip_subworkflows = "mt_annotation,mt_subsample,me_calling,me_annotation,sv_annotation" + skip_tools = "fastp,gens,peddy,germlinecnvcaller,eklipse,ngsbits" input = params.pipelines_testdata_base_path + 'testdata/samplesheet_bam.csv' diff --git a/conf/test_full.config b/conf/test_full.config index cca2a2463..ff2c306c8 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -16,12 +16,6 @@ process { memory: '15.GB', time: '1.h' ] - - withName: 'ENSEMBLVEP.*' { - container = { workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' } - } } env { diff --git a/conf/test_sentieon.config b/conf/test_sentieon.config index 5349641d6..9b56b62ef 100644 --- a/conf/test_sentieon.config +++ b/conf/test_sentieon.config @@ -16,12 +16,6 @@ process { memory: '15.GB', time: '1.h' ] - - withName: 'ENSEMBLVEP.*' { - container = { workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' } - } } env { @@ -35,7 +29,7 @@ params { igenomes_ignore = true mito_name = 'MT' - skip_tools = 'gens,haplogrep3,peddy,germlinecnvcaller' + skip_tools = "fastp,gens,peddy,germlinecnvcaller,eklipse,ngsbits" // Input data pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' diff --git a/conf/test_singleton.config b/conf/test_singleton.config index 615f16a68..3810dbf06 100644 --- a/conf/test_singleton.config +++ b/conf/test_singleton.config @@ -16,12 +16,6 @@ process { memory: '15.GB', time: '1.h' ] - - withName: 'ENSEMBLVEP.*' { - container = { workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' } - } } env { @@ -36,8 +30,7 @@ params { mito_name = 'MT' pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' - skip_tools = 'fastp,gens,haplogrep3,peddy,germlinecnvcaller,qualimap,eklipse,ngsbits' - skip_subworkflows = "mt_annotation,mt_subsample,me_calling,me_annotation,sv_annotation" + skip_tools = "fastp,gens,peddy,germlinecnvcaller,eklipse,ngsbits" input = params.pipelines_testdata_base_path + 'testdata/samplesheet_single.csv' fasta = params.pipelines_testdata_base_path + 'reference/reference.fasta' diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 000000000..9c3133abd --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,190 @@ +--- +title: Contributing +markdownPlugin: checklist +--- + +# `nf-core/raredisease`: Contributing guidelines + +Hi there! +Thanks for taking an interest in improving nf-core/raredisease. + +This page describes the recommended nf-core way to contribute to both nf-core/raredisease 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/raredisease. + +> [!NOTE] +> If you need help using or modifying nf-core/raredisease, ask on the nf-core Slack [#raredisease](https://nfcore.slack.com/channels/raredisease) 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/raredisease/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/raredisease repository](https://github.com/nf-core/raredisease) 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. + +#### Forks and CI/CD Tests + +When creating a pull request from a forked repository, it's likely that some tests will fail that are related to nf-core/raredisease private license files (Sentieon etc) +as they are not available in the forked repository. If this is the case, push the branch into raredisease instead and open a PR from the new branch. + +## 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/raredisease documentation](https://nf-co.re/raredisease/usage) or ask on the nf-core [#raredisease](https://nfcore.slack.com/channels/raredisease) Slack channel ([join our Slack here](https://nf-co.re/join/slack)). + +### GitHub Codespaces + +You can contribute to nf-core/raredisease 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/raredisease/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 +``` + +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. + +### 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/raredisease 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. +- [ ] Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name cleanup, and module plots are in the appropriate order. +- [ ] If applicable, create a [MultiQC](https://seqera.io/multiqc/) module. +- [ ] Add a description of the output files and, if relevant, images from the MultiQC report to `docs/output.md`. + +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 + + diff --git a/docs/images/raredisease_metromap_dark.pdf b/docs/images/raredisease_metromap_dark.pdf index 65eecd9d7..2b5d24892 100644 Binary files a/docs/images/raredisease_metromap_dark.pdf and b/docs/images/raredisease_metromap_dark.pdf differ diff --git a/docs/images/raredisease_metromap_dark.png b/docs/images/raredisease_metromap_dark.png index e3fe3f334..ed42cb72b 100644 Binary files a/docs/images/raredisease_metromap_dark.png and b/docs/images/raredisease_metromap_dark.png differ diff --git a/docs/images/raredisease_metromap_dark.svg b/docs/images/raredisease_metromap_dark.svg index e041d0f05..b072ea598 100644 --- a/docs/images/raredisease_metromap_dark.svg +++ b/docs/images/raredisease_metromap_dark.svg @@ -8,7 +8,7 @@ version="1.1" id="svg1" xml:space="preserve" - inkscape:version="1.3.2 (091e20e, 2023-11-25)" + inkscape:version="1.4.3 (0d15f75, 2025-12-25)" sodipodi:docname="raredisease_metromap_dark.svg" inkscape:export-filename="raredisease_metromap_dark.pdf" inkscape:export-xdpi="96" @@ -28,14 +28,14 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" showgrid="true" - inkscape:zoom="0.31720749" - inkscape:cx="1473.7987" - inkscape:cy="941.02444" - inkscape:window-width="1712" - inkscape:window-height="1040" - inkscape:window-x="0" - inkscape:window-y="39" - inkscape:window-maximized="1" + inkscape:zoom="0.32610378" + inkscape:cx="1361.5297" + inkscape:cy="1004.2815" + inkscape:window-width="1470" + inkscape:window-height="816" + inkscape:window-x="237" + inkscape:window-y="1238" + inkscape:window-maximized="0" inkscape:current-layer="layer1" showguides="true" inkscape:export-bgcolor="#272829ff">manta - + -tiddit - + -cnvnatorvepsvdb-querygermlinecnvcallergenmod vcfeklipsemantamantamanta + + +tiddit + + +cnvnatorvepsvdb-querygermlinecnvcallergenmod vcfmitosaltsaltshaker diff --git a/docs/images/raredisease_metromap_light.pdf b/docs/images/raredisease_metromap_light.pdf index cc41a1368..c2adb5e7e 100644 Binary files a/docs/images/raredisease_metromap_light.pdf and b/docs/images/raredisease_metromap_light.pdf differ diff --git a/docs/images/raredisease_metromap_light.png b/docs/images/raredisease_metromap_light.png index 39a391aa8..7a50605f6 100644 Binary files a/docs/images/raredisease_metromap_light.png and b/docs/images/raredisease_metromap_light.png differ diff --git a/docs/images/raredisease_metromap_light.svg b/docs/images/raredisease_metromap_light.svg index 77d7b608e..d3878cd07 100644 --- a/docs/images/raredisease_metromap_light.svg +++ b/docs/images/raredisease_metromap_light.svg @@ -8,7 +8,7 @@ version="1.1" id="svg1" xml:space="preserve" - inkscape:version="1.3.2 (091e20e, 2023-11-25)" + inkscape:version="1.4.3 (0d15f75, 2025-12-25)" sodipodi:docname="raredisease_metromap_light.svg" inkscape:export-filename="raredisease_metromap_light.pdf" inkscape:export-xdpi="96" @@ -28,13 +28,13 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" showgrid="true" - inkscape:zoom="0.31001843" - inkscape:cx="1533.7798" - inkscape:cy="864.46473" - inkscape:window-width="1712" - inkscape:window-height="1025" - inkscape:window-x="0" - inkscape:window-y="39" + inkscape:zoom="0.57178976" + inkscape:cx="2021.7221" + inkscape:cy="1102.678" + inkscape:window-width="1470" + inkscape:window-height="890" + inkscape:window-x="237" + inkscape:window-y="1238" inkscape:window-maximized="0" inkscape:current-layer="layer1" showguides="true" @@ -54,7 +54,24 @@ gridanglex="30" gridanglez="30" visible="true" />manta + id="tspan11">manta + + id="tspan12"> + tiddit + id="tspan13">tiddit + + id="tspan14"> + cnvnatorcnvnatorvepvepsvdb-querysvdb-querygermlinecnvcallergermlinecnvcallergenmodgenmod vcf vcfeklipsemantamanta + ry="2.6962883" />mitosaltsaltshaker diff --git a/docs/output.md b/docs/output.md index 519de7ef6..aa0870745 100644 --- a/docs/output.md +++ b/docs/output.md @@ -28,7 +28,6 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [FastQC](#fastqc) - [Mosdepth](#mosdepth) - [Picard tools](#picard-tools) - - [Qualimap](#qualimap) - [Chromograph coverage](#chromograph-coverage) - [Sention WgsMetricsAlgo](#sention-wgsmetricsalgo) - [TIDDIT's cov and UCSC WigToBigWig](#tiddits-cov-and-ucsc-wigtobigwig) @@ -59,15 +58,13 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [SVDB query](#svdb-query) - [VEP](#vep-1) - [Mitochondrial analysis](#mitochondrial-analysis) - - [Haplocheck](#haplocheck) - [Alignment and variant calling](#alignment-and-variant-calling) - [MT deletion script](#mt-deletion-script) - - [eKLIPse](#eklipse) + - [MitoSAlt](#mitosalt) + - [saltshaker](#saltshaker) - [Annotation](#annotation) - - [HaploGrep2](#haplogrep2) - [vcfanno](#vcfanno-1) - [CADD](#cadd-1) - - [Hmtnote](#hmtnote) - [VEP](#vep-2) - [Filtering and ranking](#filtering-and-ranking) - [Filter_vep](#filter_vep) @@ -77,6 +74,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [Annotating mobile elements](#annotating-mobile-elements) - [Variant evaluation](#variant-evaluation) - [Gens](#gens) + - [Peddy](#peddy) - [Pipeline information](#pipeline-information) ### Alignment @@ -103,26 +101,28 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d ##### Picard's MarkDuplicates -[Picard MarkDuplicates](https://broadinstitute.github.io/picard/command-line-overview.html#MarkDuplicates) is used for marking PCR duplicates that can occur during library amplification. This is essential as the presence of such duplicates results in false inflated coverages, which in turn can lead to overly-confident genotyping calls during variant calling. Only reads aligned by Bwa-mem2, bwameme and bwa are processed by this tool. By default, alignment files are published in bam format. If you would like to store cram files instead, set `--save_mapped_as_cram` to true. +[Picard MarkDuplicates](https://broadinstitute.github.io/picard/command-line-overview.html#MarkDuplicates) is used for marking PCR duplicates that can occur during library amplification. This is essential as the presence of such duplicates results in false inflated coverages, which in turn can lead to overly-confident genotyping calls during variant calling. Only reads aligned by Bwa-mem2, bwameme and bwa are processed by this tool. By default, alignment files are published in bam format. To publish cram files instead, use `--save_all_mapped_as_cram` for the full (unfiltered) alignment, or `--save_noalt_mapped_as_cram` for the alt-filtered alignment (requires `--exclude_alt`).
    Output files from Alignment - `{outputdir}/alignment/` - - `*.bam|*.cram`: Alignment file in bam/cram format. + - `*_sorted_md.bam|*_sorted_md.cram`: Full (unfiltered) alignment file. Published as bam by default, or as cram when `--save_all_mapped_as_cram` is set. + - `*_sorted_md_primary_contigs.cram`: Alt-filtered alignment file in cram format. Published when `--save_noalt_mapped_as_cram` is set (requires `--exclude_alt`). Contains only primary chromosomes (GRCh37: 1-22,X,Y,MT / GRCh38: chr1-chr22,chrX,chrY,chrM). - `*.bai|*.crai`: Index of the corresponding bam/cram file. - `*.txt`: Text file containing the dedup metrics.
    ##### Sentieon Dedup -[Sentieon Dedup](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/#remove-or-mark-duplicates) is the algorithm used by Sentieon's driver to remove duplicate reads. Only reads aligned by Sentieon's implementation of bwa are processed by this algorithm. By default, alignment files are published in bam format. If you would like to store cram files instead, set `--save_mapped_as_cram` to true. +[Sentieon Dedup](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/#remove-or-mark-duplicates) is the algorithm used by Sentieon's driver to remove duplicate reads. Only reads aligned by Sentieon's implementation of bwa are processed by this algorithm. By default, alignment files are published in bam format. To publish cram files instead, use `--save_all_mapped_as_cram` for the full (unfiltered) alignment, or `--save_noalt_mapped_as_cram` for the alt-filtered alignment (requires `--exclude_alt`).
    Output files from Alignment - `{outputdir}/alignment/` - - `*.bam|*.cram`: Alignment file in bam/cram format. + - `*_sorted_md.bam|*_sorted_md.cram`: Full (unfiltered) alignment file. Published as bam by default, or as cram when `--save_all_mapped_as_cram` is set. + - `*_sorted_md_primary_contigs.cram`: Alt-filtered alignment file in cram format. Published when `--save_noalt_mapped_as_cram` is set (requires `--exclude_alt`). Contains only primary chromosomes (GRCh37: 1-22,X,Y,MT / GRCh38: chr1-chr22,chrX,chrY,chrM). - `*.bai|*.crai`: Index of the corresponding bam/cram file. - `*.metrics`: Text file containing the dedup metrics.
    @@ -184,7 +184,7 @@ The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They m
    Output files -- `{outputdir}/qc_bam/_qualimap/` +- `{outputdir}/qc_bam/` - `_hsmetrics.CollectHsMetrics.coverage_metrics`: - `_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics`: - `_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics`: @@ -195,21 +195,6 @@ The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They m - `_wgsmetrics_y.CollectWgsMetrics.coverage_metrics`:
    -##### Qualimap - -[Qualimap](http://qualimap.conesalab.org/) also allows you to assess the alignment coverage. Qualimap results are used by MultiQC to generate the following plots. - -- Coverage histogram -- Cumulative genome coverage -- Insert size histogram -- GC content distribution - -
    -Output files - -- `{outputdir}/qc_bam/_qualimap/` this directory includes a qualimap report and associated raw statistic files. You can open the .html file in your internet browser to see the in-depth report. -
    - ##### Chromograph coverage [Chromograph](https://github.com/Clinical-Genomics/chromograph) is a python package to create PNG images from genetics data such as BED and WIG files. @@ -454,6 +439,7 @@ Based on VEP annotations, custom scripts used by the pipeline further annotate e - `annotate_sv/` - `_svdbquery_vep.vcf.gz`: file containing svdb query, and vep annotations. - `_svdbquery_vep.vcf.gz.tbi`: index of the file containing bcftools roh, vcfanno, and vep annotations. + - `_svdbquery_vep_summary.html`: vep summary. @@ -461,18 +447,6 @@ Based on VEP annotations, custom scripts used by the pipeline further annotate e Mitochondrial analysis is run by default. If you want to turn off annotations set `--skip_subworkflows mt_annotation`. -#### Haplocheck - -[Haplocheck](https://github.com/genepi/haplocheck/) analyses the mitochondrial content to detect contamination in samples. The results are displayed in MultiQC. - -
    -Output files - -- `{outputdir}/haplocheck/` - - `.raw.txt`: haplocheck raw output. Read more about the file content [here](https://mitoverse.readthedocs.io/haplocheck/haplocheck/#textual-report-file-raw). - -
    - #### Alignment and variant calling [Alignment and variant calling - GATK Mitochondrial short variant discovery pipeline](https://gatk.broadinstitute.org/hc/en-us/articles/4403870837275-Mitochondrial-short-variant-discovery-SNVs-Indels-) The mitochondrial genome poses several challenges to the identification and understanding of somatic variants. The circularity of the mitochondrial genome means that the breakpoint in the reference genome is at an arbitrary position in the non-coding control region, creating a challenge in analyzing variation. Additionally, insertions of mitochondrial DNA into the nuclear genome (NuMTs) complicate the mapping of the mitochondrial genome and the distinction between NuMTs and the mitochondrial contig of interest. Lastly, mitochondrial variants often have very low heteroplasmy. Such low allele fraction (AF) variants can thus be mistaken for inherent sequencer noise. @@ -487,32 +461,20 @@ The pipeline for mitochondrial variant discovery, using Mutect2, uses a high sen [MT deletion script](https://github.com/dnil/mitosign/blob/master/run_mt_del_check.sh) lists the fraction of mitochondrially aligning read pairs (per 1000) that appear discordant, as defined by an insert size of more than 1.2 kb (and less than 15 kb due to the circular nature of the genome) using samtools. -- `call_sv/mitochondria` +- `call_sv` - `_mitochondria_deletions.txt`: file containing deletions. -##### eKLIPse +##### Saltshaker -[eKLIPse](https://github.com/dooguypapua/eKLIPse) allows the detection and quantification of large mtDNA rearrangements. +[MitoSAlt](https://mitosalt.sourceforge.io/) allows the detection and quantification of mtDNA strucutral variants. +[Saltshaker](https://gitlab.com/genomedx/annotation/saltshaker) allows for downstream clustering and classification of mtDNA strucutral variants. Called variants are combined with structural variants called in the nuclear genome. -- `call_sv/mitochondria` - - `eKLIPse__deletions.csv`: file containing all predicted deletions. - - `eKLIPse__genes.csv`: file summarizing cumulated deletions per mtDNA gene. - - `eKLIPse_.png`: circos plot. +- `call_sv` + - `.saltshaker_classify.html`: report containing case-level classification of mitochondrial deletions. Only created when MitoSAlt finds at least one cluster. + - `.saltshaker.png`: circos plot. Only created when MitoSAlt finds at least one cluster. #### Annotation -##### HaploGrep2 - -[HaploGrep2](https://github.com/seppinho/haplogrep-cmd) allows detecting artificial recombinants and missing variants as well as annotating rare and phantom mutations in mitochondria. Haplogrep generates a text report, which is published by default. - -
    -Output files - -- `annotate_snv/mitochondria` - - `*haplogrep.txt`: file containing haplogroup information. - -
    - ##### vcfanno [vcfanno](https://github.com/brentp/vcfanno) allows you to quickly annotate your VCF with any number of INFO fields from any number of VCFs. It uses a simple conf file to allow the user to specify the source annotation files and fields and how they will be added to the info of the query VCF. Values are pulled by name from the INFO field with special-cases of ID and FILTER to pull from those VCF columns. The output files are not published in the output folder, and is passed to vep for further annotation. @@ -523,10 +485,6 @@ We recommend using vcfanno to annotate SNVs with precomputed CADD scores (files [CADD](https://cadd.gs.washington.edu/) is a tool for scoring the deleteriousness of single nucleotide variants as well as insertion/deletions variants in the human genome. In nf-core/raredisease, SNVs can be annotated with precomputed CADD scores using vcfanno. However, for small indels they will be calculated on the fly by CADD. The output files are not published in the output folder, and is passed to VEP for further annotation. -##### Hmtnote - -[HmtNote](https://github.com/robertopreste/HmtNote) annotates vcf containing human mitochondrial variants with HmtVar. It will run offline by default with a database within the container. - ##### VEP [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html) determines the effect of your variants on genes, transcripts, and protein sequence, as well as regulatory regions. @@ -535,8 +493,8 @@ We recommend using vcfanno to annotate SNVs with precomputed CADD scores (files Output files - `annotate_snv/mitochondria` - - `_mitochondria_hmtnote_vcfanno_.vcf.gz`: file containing mitochondrial annotations. - - `_mitochondria_hmtnote_vcfanno_.vcf.gz.tbi`: index of the file containing mitochondrial annotations. + - `_mitochondria_vcfanno_.vcf.gz`: file containing mitochondrial annotations. + - `_mitochondria_vcfanno_.vcf.gz.tbi`: index of the file containing mitochondrial annotations. @@ -607,7 +565,6 @@ Provided a truth set, SNVs can be evaluated using RTG Tools' vcfeval engine. Out Output files - `rtgvcfeval/` - - `_vcfeval.fn.vcf.gz`: contains variants from the baseline VCF which were not correctly called. - `_vcfeval.fn.vcf.gz.tbi`: index of the \*fn.vcf file - `_vcfeval.fp.vcf.gz`: contains variants from the calls VCF which do not agree with baseline variants. @@ -635,7 +592,6 @@ The sequencing data can be prepared for visualization of CNVs in [Gens](https:// Output files - `gens/` - - `_gens.baf.bed.gz`: contains sample b-allele frequencies in bed format. - `_gens.baf.bed.gz.tbi`: index of the \*baf.bed.gz file. - `_gens.cov.bed.gz`: contains sample coverage in bed format. @@ -643,6 +599,25 @@ The sequencing data can be prepared for visualization of CNVs in [Gens](https:// +### Peddy + +[Peddy](https://github.com/brentp/peddy) compares familial-relationships and sexes as reported in a PED file with those inferred from a VCF. + +
    +Output files + +- `peddy/` + - `*.het_check.csv`: CSV file containing heterozygosity check results — rate of het calls, allele-balance at het calls, mean and median depth, and a PCA projection onto 1000 Genomes. + - `*.het_check.png`: PNG plot of heterozygosity check results — rate of het calls, allele-balance at het calls, mean and median depth, and a PCA projection onto 1000 Genomes. + - `*.html`: interactive HTML report with plots for sex check (HET rate on chrX), depth and heterozygosity, and pedigree relatedness, plus an interactive pedigree table. + - `*.ped_check.csv`: CSV file containing pedigree check results — pairwise relatedness statistics comparing reported vs. inferred relationships. + - `*.ped_check.png`: PNG plot of pedigree check results — comparison between reported and inferred relatedness. + - `*.ped_check.rel-difference.csv`: CSV file with the comparison between inferred and reported relatedness for sample pairs where they differ. + - `*.peddy.ped`: extended PED file augmented with key columns from the het-check and sex-check results. + - `*.sex_check.csv`: CSV file with sex check results — comparison between the sex reported in the PED file and that inferred from genotypes on the non-PAR regions of the X chromosome. + - `*.sex_check.png`: PNG plot of sex check results — comparison between reported and inferred sex. + - `*.vs.html`: interactive scatter plot of observed vs. expected (pedigree-reported) relatedness for all sample pairs. + ### Pipeline information [Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. diff --git a/docs/usage.md b/docs/usage.md index 449572684..58ba6ccd8 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -50,7 +50,7 @@ nf-core/raredisease is a bioinformatics best-practice analysis pipeline to call, ## Prerequisites -1. Install Nextflow (>=24.04.2) using the instructions [here.](https://nextflow.io/docs/latest/getstarted.html#installation) +1. Install Nextflow (>=25.10.4) using the instructions [here.](https://nextflow.io/docs/latest/getstarted.html#installation) 2. Install one of the following technologies for full pipeline reproducibility: Docker, Singularity, Podman, Shifter or Charliecloud. > Almost all nf-core pipelines give you the option to use conda as well. However, some tools used in the raredisease pipeline do not have a conda package so we do not support conda at the moment. @@ -100,7 +100,7 @@ Running the pipeline involves three steps: A samplesheet is used to provide information about the sample(s) to the pipeline in CSV format, including the path to the FASTQ files and other metadata such as sex and phenotype. -The nf-core/raredisease pipeline accepts FASTQ files, SPRING files, or BAM files as input. Currently, the pipeline does not support single-end data from Illumina. The pedigree information in the samplesheet (sex and phenotype) should be provided in the same format as a [PED file](https://gatk.broadinstitute.org/hc/en-us/articles/360035531972-PED-Pedigree-format), with sex indicated as 1 for male, 2 for female, and other for unknown. +The nf-core/raredisease pipeline accepts FASTQ files, SPRING files, or BAM files as input. Currently, the pipeline does not support single-end data from Illumina, and mitochondrial SV calling with MitoSAlt and saltshaker does not run with BAM file input. The pedigree information in the samplesheet (sex and phenotype) should be provided in the same format as a [PED file](https://gatk.broadinstitute.org/hc/en-us/articles/360035531972-PED-Pedigree-format), with sex indicated as 1 for male, 2 for female, and other for unknown. | Fields | Description | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -133,16 +133,16 @@ If you would like to see more examples of what a typical samplesheet looks like The nf-core/raredisease pipeline can handle duplicate-marked BAM files as input. In such cases, samplesheet should contain the following columns: -| Fields | Description | -| ------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. | -| `bam` | Absolute path to FASTQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `bai` | Absolute path to FASTQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `sex` | Sex (1=male; 2=female; for unknown sex use 0 or 'other'). | -| `phenotype` | Affected status of patient (0 = missing; 1=unaffected; 2=affected). | -| `paternal_id` | Sample ID of the father, can be blank if the father isn't part of the analysis or for samples other than the proband. | -| `maternal_id` | Sample ID of the mother, can be blank if the mother isn't part of the analysis or for samples other than the proband. | -| `case_id` | Case ID, for the analysis used when generating a family VCF. | +| Fields | Description | +| ------------- | --------------------------------------------------------------------------------------------------------------------- | +| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. | +| `bam` | Absolute path to a duplicate-marked BAM file. | +| `bai` | Absolute path to the BAM index file (.bai). | +| `sex` | Sex (1=male; 2=female; for unknown sex use 0 or 'other'). | +| `phenotype` | Affected status of patient (0 = missing; 1=unaffected; 2=affected). | +| `paternal_id` | Sample ID of the father, can be blank if the father isn't part of the analysis or for samples other than the proband. | +| `maternal_id` | Sample ID of the mother, can be blank if the mother isn't part of the analysis or for samples other than the proband. | +| `case_id` | Case ID, for the analysis used when generating a family VCF. | If you would like to see an example of what a typical samplesheet looks like in this case, follow this [link.](https://github.com/nf-core/test-datasets/blob/raredisease/testdata/samplesheet_bam.csv) @@ -151,7 +151,7 @@ If you would like to see an example of what a typical samplesheet looks like in In nf-core/raredisease, references can be supplied using parameters listed [here](https://nf-co.re/raredisease/dev/parameters). > [!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: @@ -169,6 +169,16 @@ genome: "GRCh37" Note that the pipeline is modular in architecture. It offers you the flexibility to choose between different tools. For example, you can align with bwamem2 or bwa or Sentieon BWA mem and call SNVs with either DeepVariant or Sentieon DNAscope. You also have the option to turn off sections of the pipeline if you do not want to run the. For example, snv annotation can be turned off by adding `--skip_subworkflows snv_annotation` flag in the command line, or by setting it to true in a parameter file. This flexibility means that in any given analysis run, a combination of tools included in the pipeline will not be executed. So the pipeline is written in a way that can account for these differences while working with reference parameters. If a tool is not going to be executed during the course of a run, parameters used only by that tool need not be provided. For example, for SNV calling if you use DeepVariant as your variant caller, you need not provide the parameter `--ml_model`, which is only used by Sentieon DNAscope. +The pipeline is modular — individual tools and subworkflows can be skipped using `--skip_tools` and `--skip_subworkflows` (comma-separated). The valid values are: + +| `--skip_tools` | +| --------------------------------------------------------------------------------------------------------- | +| `fastp`, `fastqc`, `gens`, `germlinecnvcaller`, `ngsbits`, `peddy`, `smncopynumbercaller`, `vcf2cytosure` | + +| `--skip_subworkflows` | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `generate_clinical_set`, `me_annotation`, `me_calling`, `mt_annotation`, `mt_subsample`, `repeat_annotation`, `repeat_calling`, `snv_annotation`, `snv_calling`, `sv_annotation`, `sv_calling` | + nf-core/raredisease consists of several tools used for various purposes. For convenience, we have grouped those tools under the following categories: 1. Alignment (bwamem2/bwa/bwameme/Sentieon BWA mem) @@ -200,6 +210,7 @@ The mandatory and optional parameters for each category are tabulated below. | | min_trimmed_length6 | | | extract_alignments | | | restrict_to_contigs7 | +| | exclude_alt8 | 1Default value is bwamem2. Other alternatives are bwa, bwameme and sentieon (requires valid Sentieon license ).
    2Analysis set reference genome in fasta format, first 25 contigs need to be chromosome 1-22, X, Y and the mitochondria.
    @@ -208,6 +219,7 @@ The mandatory and optional parameters for each category are tabulated below. 5Used only by Sentieon.
    6Default value is 40. Used only by fastp.
    7Used to limit your analysis to specific contigs. Can be used to remove alignments to unplaced contigs to minimize potential errors. This parameter should be used in conjunction with the `extract_alignments` parameter.
    +8When set to true, alignments to alt/unplaced contigs are removed after alignment using samtools view, retaining only primary chromosomes (GRCh37: 1-22,X,Y,MT / GRCh38: chr1-chr22,chrX,chrY,chrM). Note that this will affect all downstream variant calling, as variants will only be called on these primary chromosomes.
    ##### 2. QC stats from the alignment files @@ -234,25 +246,31 @@ The mandatory and optional parameters for each category are tabulated below. ##### 4. Variant calling - SNV -| Mandatory | Optional | -| -------------------------- | --------------------------- | -| variant_caller1 | known_dbsnp2 | -| ml_model2 | known_dbsnp_tbi2 | -| analysis_type3 | call_interval2 | -| | known_dbsnp_tbi2 | -| | par_bed4 | +| Mandatory | Optional | +| -------------------------- | ------------------------------------ | +| variant_caller1 | known_dbsnp2 | +| ml_model2 | known_dbsnp_tbi2 | +| analysis_type3 | call_interval2 | +| | known_dbsnp_tbi2 | +| | par_bed4 | +| | skip_split_multiallelics5 | 1Default variant caller is DeepVariant, but you have the option to use Sentieon as well.
    2These parameters are only used by Sentieon.
    3Default is `WGS`, but you have the option to choose `WES` and `mito` as well.
    4This parameter is only used by Deepvariant.
    +5Skips `bcftools norm --multiallelics -both` in both DeepVariant and Sentieon SNV calling. Recommended for single-interval runs to avoid indel quality degradation. See [#813](https://github.com/nf-core/raredisease/issues/813) for details.
    ##### 5. Variant calling - Structural variants -| Mandatory | Optional | -| --------- | ---------- | -| | target_bed | -| | bwa | +| Mandatory | Optional | +| --------- | ---------------------------------- | +| | target_bed | +| | bwa | +| | manta_call_regions1 | +| | manta_call_regions_tbi1 | + +1 A bgzipped BED file (`.bed.gz`) and its tabix index (`.bed.gz.tbi`) restricting Manta's SV calling to specific regions. Both parameters must be supplied together. Only applied for WGS; for WES, Manta always uses `target_bed` and these parameters have no effect. Useful for reducing runtime on references with many short contigs such as GRCh38 by limiting analysis to primary chromosomes. ##### 6. Copy number variant calling @@ -275,7 +293,7 @@ The mandatory and optional parameters for each category are tabulated below. | vcfanno_resources2 | vcfanno_lua | | vcfanno_toml3 | vep_filters/vep_filters_scout_fmt10 | | vep_cache_version | cadd_resources11 | -| vep_cache4 | | +| vep_cache4 | run_vcfanno_db_sanity_check12 | | gnomad_af5 | | | score_config_snv6 | | | variant_consequences_snv7 | | @@ -288,13 +306,14 @@ The mandatory and optional parameters for each category are tabulated below. VEP plugins may be installed in the cache directory, and the plugin pLI is mandatory to install. To supply files required by VEP plugins, use `vep_plugin_files` parameter. See example cache [here](https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/vep_cache_and_plugins.tar.gz).
    5 GnomAD VCF files can be downloaded from [here](https://gnomad.broadinstitute.org/downloads). The option `gnomad_af` expects a tab-delimited file with -no header and the following columns: `CHROM POS REF_ALLELE ALT_ALLELE AF`. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/gnomad_reformated.tab.gz).
    +no header and the following columns: `CHROM POS REF_ALLELE,ALT_ALLELE AF`. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/gnomad_reformated.tab.gz).
    6Used by GENMOD for ranking the variants. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/rank_model_snv.ini).
    7File containing list of SO terms listed in the order of severity from most severe to lease severe for annotating genomic and mitochondrial SNVs. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/variant_consequences_v2.txt). You can learn more about these terms [here](https://grch37.ensembl.org/info/genome/variation/prediction/predicted_data.html). 8A CSV file that describes the files used by VEP's named and custom plugins. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/vep_files.csv).
    9Used by GENMOD while modeling the variants. Contains a list of loci that show [reduced penetrance](https://medlineplus.gov/genetics/understanding/inheritance/penetranceexpressivity/) in people. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/reduced_penetrance.tsv).
    -10 This file contains a list of candidate genes (with [HGNC](https://www.genenames.org/) IDs) that is used to split the variants into canditate variants and research variants. Research variants contain all the variants, while candidate variants are a subset of research variants and are associated with candidate genes. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/hgnc.txt). Not required if `--skip_subworkflows generate_clinical_set` is set.
    +10 This file contains a list of candidate genes (with [HGNC](https://www.genenames.org/) IDs) that is used to split the variants into candidate variants and research variants. Research variants contain all the variants, while candidate variants are a subset of research variants and are associated with candidate genes. Sample file [here](https://github.com/nf-core/test-datasets/blob/raredisease/reference/hgnc.txt). Not required if `--skip_subworkflows generate_clinical_set` is set.
    11Path to a folder containing cadd annotations. Equivalent of the data/annotations/ folder described [here](https://github.com/kircherlab/CADD-scripts/#manual-installation), and it is used to calculate CADD scores for small indels.
    +12When set to `true`, each vcfanno database file listed in `vcfanno_resources` is checked for records (non-header lines). Any database with zero records is removed from the vcfanno TOML config before annotation runs to prevent vcfanno from crashing on default resource files. Default: `false`.
    :::note We use CADD only to annotate small indels. To annotate SNVs with precomputed CADD scores, pass the file containing CADD scores as a resource to vcfanno instead. Files containing the precomputed CADD scores for SNVs can be downloaded from [here](https://cadd.gs.washington.edu/download) (download files listed under the description: "All possible SNVs of GRCh3<7/8>/hg3<7/8>") @@ -316,17 +335,21 @@ We use CADD only to annotate small indels. To annotate SNVs with precomputed CAD ##### 9. Mitochondrial annotation +Mitochondrial analysis runs automatically for `wgs` and `mito` analysis types. For WES runs, set `--run_mt_for_wes true` to enable it. + | Mandatory | Optional | | ------------------------ | --------------------------------- | -| genome | vep_filters/vep_filters_scout_fmt | -| mito_name | vep_plugin_files | -| vcfanno_resources | | +| genome | run_mt_for_wes1 | +| mito_name | vep_filters/vep_filters_scout_fmt | +| vcfanno_resources | vep_plugin_files | | vcfanno_toml | | | vep_cache_version | | | vep_cache | | | score_config_mt | | | variant_consequences_snv | | +1Set to `true` to enable mitochondrial analysis for WES runs. Default is `false`.
    + ##### 10. Mobile element calling | Mandatory | Optional | @@ -443,7 +466,6 @@ with: input: './samplesheet.csv' outdir: './results/' genome: 'GRCh37' -input: 'data' <...> ``` @@ -482,7 +504,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - `shifter` - A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/) - `charliecloud` - - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) + - A generic configuration profile to be used with [Charliecloud](https://charliecloud.io/) - `apptainer` - A generic configuration profile to be used with [Apptainer](https://apptainer.org/) - `wave` @@ -506,19 +528,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 d229b2d58..1de035f26 100644 --- a/main.nf +++ b/main.nf @@ -14,12 +14,18 @@ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -include { RAREDISEASE } from './workflows/raredisease' +include { samplesheetToList } from 'plugin/nf-schema' +include { CREATE_HGNCIDS_FILE } from './modules/local/create_hgncids_file' +include { CREATE_PEDIGREE_FILE } from './modules/local/create_pedigree_file' +include { channelFromPath } from './subworkflows/local/utils_nfcore_raredisease_pipeline' +include { channelFromPathWithMeta } from './subworkflows/local/utils_nfcore_raredisease_pipeline' +include { channelFromSamplesheet } from './subworkflows/local/utils_nfcore_raredisease_pipeline' +include { parseSkipList } from './subworkflows/local/utils_nfcore_raredisease_pipeline' include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_raredisease_pipeline' include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_raredisease_pipeline' - - +include { PREPARE_REFERENCES } from './subworkflows/local/prepare_references' +include { RAREDISEASE } from './workflows/raredisease' +include { SCATTER_GENOME } from './subworkflows/local/scatter_genome' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -33,24 +39,662 @@ include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_rare workflow NFCORE_RAREDISEASE { take: - fastq - alignment - samples - case_info + ch_alignments + ch_case_info + ch_reads + ch_samples + val_aligner + val_analysis_type + val_bwa + val_bwafastalign + val_bwamem2 + val_bwameme + val_cadd_prescored + val_cadd_resources + val_call_interval + val_concatenate_snv_calls + val_skip_split_multiallelics + val_exclude_alt + val_extract_alignments + val_fai + val_fasta + val_gcnvcaller_model + val_genome + val_gens_gnomad_pos + val_gens_interval_list + val_gens_pon_female + val_gens_pon_male + val_gnomad_af + val_gnomad_af_idx + val_heavy_strand_origin_end + val_heavy_strand_origin_start + val_homoplasmy_af_threshold + val_intervals_wgs + val_intervals_y + val_known_dbsnp + val_known_dbsnp_tbi + val_light_strand_origin_end + val_light_strand_origin_start + val_manta_call_regions + val_manta_call_regions_tbi + val_mito_length + val_mito_name + val_mitosalt_breakspan + val_mitosalt_breakthreshold + val_mitosalt_cluster_threshold + val_mitosalt_deletion_threshold_max + val_mitosalt_deletion_threshold_min + val_mitosalt_evalue_threshold + val_mitosalt_exclude + val_mitosalt_flank + val_mitosalt_heteroplasmy_limit + val_mitosalt_paired_distance + val_mitosalt_score_threshold + val_mitosalt_sizelimit + val_mitosalt_split_distance_threshold + val_mitosalt_split_length + val_ml_model + val_mobile_element_references + val_mobile_element_svdb_annotations + val_mt_aligner + val_mt_fasta + val_mt_subsample_approach + val_mt_subsample_rd + val_mt_subsample_seed + val_multiqc_config + val_multiqc_logo + val_multiqc_methods_description + val_multiqc_samples + val_ngsbits_samplegender_method + val_outdir + val_par_bed + val_platform + val_ploidy_model + val_readcount_intervals + val_reduced_penetrance + val_rtg_truthvcfs + val_run_mt_for_wes + val_run_rtgvcfeval + val_run_vcfanno_db_sanity_check + val_sambamba_regions + val_sample_id_map + val_save_all_mapped_as_cram + val_save_noalt_mapped_as_cram + val_save_reference + val_score_config_mt + val_score_config_snv + val_score_config_sv + val_sdf + val_sentieon_dnascope_pcr_indel_model + val_sequence_dictionary + val_skip_tools + val_skip_subworkflows + val_subdepth + val_svdb_query_bedpedbs + val_svdb_query_dbs + val_target_bed + val_variant_caller + val_variant_catalog + val_variant_consequences_snv + val_variant_consequences_sv + val_vcf2cytosure_blacklist + val_vcfanno_extra_resources + val_vcfanno_lua + val_vcfanno_resources + val_vcfanno_toml + val_vep_cache_version + val_vep_filters + val_vep_filters_scout_fmt + val_vep_plugin_files + val_verifybamid_svd_bed + val_verifybamid_svd_mu + val_verifybamid_svd_ud + val_vep_cache + val_contamination_sites + val_contamination_sites_tbi main: // // WORKFLOW: Run pipeline // + + ch_versions = channel.empty() + + PREPARE_REFERENCES ( + val_aligner, + val_analysis_type, + val_bwa, + val_bwafastalign, + val_bwamem2, + val_bwameme, + val_fai, + val_fasta, + val_gnomad_af, + val_gnomad_af_idx, + val_known_dbsnp, + val_known_dbsnp_tbi, + val_mt_aligner, + val_mt_fasta, + val_run_mt_for_wes, + val_run_rtgvcfeval, + val_sdf, + val_sequence_dictionary, + val_target_bed, + val_vcfanno_extra_resources, + val_vep_cache + ) + .set { ch_references } + + ch_bait_intervals = ch_references.bait_intervals + ch_dbsnp = ch_references.dbsnp + ch_dbsnp_tbi = ch_references.dbsnp_tbi + ch_genome_bwafastalignindex = ch_references.genome_bwafastalign_index + ch_genome_bwaindex = ch_references.genome_bwa_index + ch_genome_bwamem2index = ch_references.genome_bwamem2_index + ch_genome_bwamemeindex = ch_references.genome_bwameme_index + ch_genome_chrsizes = ch_references.genome_chrom_sizes + ch_genome_fai = ch_references.genome_fai + ch_genome_fasta = ch_references.genome_fasta + ch_genome_dictionary = ch_references.genome_dict + ch_genome_hisat2index = ch_references.genome_hisat2_index + ch_gnomad_af = ch_references.gnomad_af_idx + ch_mt_bwaindex = ch_references.mt_bwa_index + ch_mt_bwamem2index = ch_references.mt_bwamem2_index + ch_mt_dictionary = ch_references.mt_dict + ch_mt_fai = ch_references.mt_fai + ch_mt_fasta = ch_references.mt_fasta + ch_mt_intervals = ch_references.mt_intervals + ch_mt_lastdb = ch_references.mt_last_index + ch_mtshift_backchain = ch_references.mtshift_backchain + ch_mtshift_bwaindex = ch_references.mtshift_bwa_index + ch_mtshift_bwamem2index = ch_references.mtshift_bwamem2_index + ch_mtshift_dictionary = ch_references.mtshift_dict + ch_mtshift_fai = ch_references.mtshift_fai + ch_mtshift_fasta = ch_references.mtshift_fasta + ch_mtshift_intervals = ch_references.mtshift_intervals + ch_sdf = ch_references.sdf + ch_target_bed = ch_references.target_bed + ch_target_intervals = ch_references.target_intervals + ch_vcfanno_extra = ch_references.vcfanno_extra + ch_vep_cache = ch_references.vep_resources + + // Using channelFromPath helper (val_x ? channel.fromPath(val_x).collect() : channel.value([])) + ch_reduced_penetrance = channelFromPath(val_reduced_penetrance, true) + ch_rtg_truthvcfs = channelFromPath(val_rtg_truthvcfs, true) + ch_score_config_mt = channelFromPath(val_score_config_mt, true) + ch_score_config_snv = channelFromPath(val_score_config_snv, true) + ch_score_config_sv = channelFromPath(val_score_config_sv, true) + ch_vcf2cytosure_blacklist = channelFromPath(val_vcf2cytosure_blacklist, true) + ch_vcfanno_lua = channelFromPath(val_vcfanno_lua, true) + ch_vcfanno_toml = channelFromPath(val_vcfanno_toml, true) + + // Using channelFromPath helper (val_x ? channel.fromPath(val_x).collect() : channel.empty()) + ch_gens_gnomad_pos = channelFromPath(val_gens_gnomad_pos) + ch_gens_interval_list = channelFromPath(val_gens_interval_list) + ch_intervals_wgs = channelFromPath(val_intervals_wgs) + ch_intervals_y = channelFromPath(val_intervals_y) + ch_me_svdb_resources = channelFromPath(val_mobile_element_svdb_annotations) + ch_readcount_intervals = channelFromPath(val_readcount_intervals) + ch_svd_bed = channelFromPath(val_verifybamid_svd_bed) + ch_svd_mu = channelFromPath(val_verifybamid_svd_mu) + ch_svd_ud = channelFromPath(val_verifybamid_svd_ud) + + // Using channelFromPathWithMeta helper (with simpleName). If filepath is null, returns, [[:],[]] + ch_cadd_prescored = channelFromPathWithMeta(val_cadd_prescored, true) + ch_cadd_resources = channelFromPathWithMeta(val_cadd_resources, true) + ch_call_interval = channelFromPathWithMeta(val_call_interval, true) + ch_ml_model = channelFromPathWithMeta(val_ml_model, true) + ch_variant_catalog = channelFromPathWithMeta(val_variant_catalog, true) + ch_variant_consequences_snv = channelFromPathWithMeta(val_variant_consequences_snv, true) + ch_variant_consequences_sv = channelFromPathWithMeta(val_variant_consequences_sv, true) + + // Using channelFromPathWithMeta helper (with simpleName). If filepath is null, returns, empty channel + ch_gens_pon_female = channelFromPathWithMeta(val_gens_pon_female) + ch_gens_pon_male = channelFromPathWithMeta(val_gens_pon_male) + ch_ploidy_model = channelFromPathWithMeta(val_ploidy_model) + + // Using channelFromPathWithMeta helper. Returns either an empty channel or [[:],[]] or a channel with custom ID. + ch_par_bed = channelFromPathWithMeta(val_par_bed, true, "par_bed") + ch_sambamba_bed = channelFromPathWithMeta(val_sambamba_regions, false, 'sambamba') + ch_vep_filters_std_fmt = channelFromPathWithMeta(val_vep_filters, false, 'standard') + ch_vep_filters_scout_fmt = channelFromPathWithMeta(val_vep_filters_scout_fmt, false, 'scout') + + // Using channelFromSamplesheet helper. Returns either an empty channel or validated channel. + ch_me_references = channelFromSamplesheet(val_mobile_element_references, "${projectDir}/assets/mobile_element_references_schema.json", false) + ch_me_svdb_resources = channelFromSamplesheet(val_mobile_element_svdb_annotations, "${projectDir}/assets/svdb_query_vcf_schema.json", false) + ch_sample_id_map = channelFromSamplesheet(val_sample_id_map, "${projectDir}/assets/sample_id_map.json", false) + ch_svdb_bedpedbs = channelFromSamplesheet(val_svdb_query_bedpedbs, "${projectDir}/assets/svdb_query_bedpe_schema.json", false) + ch_svdb_dbs = channelFromSamplesheet(val_svdb_query_dbs, "${projectDir}/assets/svdb_query_vcf_schema.json", false) + + ch_cadd_header = channel.fromPath("$projectDir/assets/cadd_to_vcf_header_-1.0-.txt", checkIfExists: true).collect() + ch_foundin_header = channel.fromPath("$projectDir/assets/foundin.hdr", checkIfExists: true).collect() + ch_manta_regions = val_analysis_type.equals("wgs") + ? (val_manta_call_regions + ? channel.value([file(val_manta_call_regions), file(val_manta_call_regions_tbi)]) + : channel.value([[], []])) + : ch_target_bed.map { _meta, bed, tbi -> [bed, tbi] } + ch_ngsbits_method = channel.value(val_ngsbits_samplegender_method) + ch_sentieon_pcr_indel_model = channel.value(val_sentieon_dnascope_pcr_indel_model) + ch_subdepth = channel.value(val_subdepth) + ch_vcfanno_resources = val_vcfanno_resources ? channel.fromPath(val_vcfanno_resources).splitText().map{it -> it.trim()}.collect() + : channel.value([]) + ch_gcnvcaller_model = val_gcnvcaller_model ? channel.fromPath(val_gcnvcaller_model) + .splitCsv ( header:true ) + .map { row -> + return [[id:file(row.models).simpleName], row.models] + } + : channel.empty() + + // + // Read and store paths in the vep_plugin_files file + // + ch_vep_extra_files = channel.empty() + if (val_vep_plugin_files) { + channel.fromPath(val_vep_plugin_files) + .collect() + .splitCsv ( header:true ) + .map { row -> + def f = file(row.vep_files[0]) + if(f.isFile() || f.isDirectory()){ + return [f] + } else { + error("\nVep database file ${f} does not exist.") + } + } + .collect() + .set {ch_vep_extra_files} + } + + // + // Dump all HGNC ids in a file + // + ch_vep_filters_scout_fmt + .mix (ch_vep_filters_std_fmt) + .set {ch_vep_filters} + + CREATE_HGNCIDS_FILE(ch_vep_filters) + .txt + .set {ch_hgnc_ids} + + // + // Generate pedigree file + // + ch_pedfile = CREATE_PEDIGREE_FILE(ch_samples.toList()).ped + ch_pedfile_publish = CREATE_PEDIGREE_FILE.out.ped + .map { ped -> ['pedigree/', [ped]] } + + // Tools + skip_fastp = parseSkipList(val_skip_tools, 'fastp') + skip_fastqc = parseSkipList(val_skip_tools, 'fastqc') + skip_gens = parseSkipList(val_skip_tools, 'gens') + skip_germlinecnvcaller = parseSkipList(val_skip_tools, 'germlinecnvcaller') + skip_mitosalt = parseSkipList(val_skip_tools, 'mitosalt') + skip_ngsbits = parseSkipList(val_skip_tools, 'ngsbits') + skip_peddy = parseSkipList(val_skip_tools, 'peddy') + skip_smncopynumbercaller = parseSkipList(val_skip_tools, 'smncopynumbercaller') + skip_vcf2cytosure = parseSkipList(val_skip_tools, 'vcf2cytosure') + // GATK contamination check is also skipped when no contamination sites are supplied + skip_contamination = parseSkipList(val_skip_tools, 'gatkcontamination') || !val_contamination_sites + + // + // Build contamination check inputs (channel construction kept out of the named workflow) + // + ch_contamination_sites = channel.empty() + ch_intervals_contamination = channel.empty() + if (!skip_contamination) { + ch_contamination_sites = channel.of([ + file(val_contamination_sites, checkIfExists: true), + file(val_contamination_sites_tbi, checkIfExists: true) + ]).collect() + + // Use intervals for WES (target regions); WGS stays genome-wide. + // CRITICAL: keep channel.empty() for WGS, not channel.of([]), so downstream ifEmpty handling works. + if (val_analysis_type.equals("wes") && val_target_bed) { + ch_intervals_contamination = channel.fromPath(val_target_bed).collect() + } + } + + // Subworkflows + skip_me_annotation = parseSkipList(val_skip_subworkflows, 'me_annotation') + skip_me_calling = parseSkipList(val_skip_subworkflows, 'me_calling') + skip_mt_annotation = parseSkipList(val_skip_subworkflows, 'mt_annotation') + skip_mt_subsample = parseSkipList(val_skip_subworkflows, 'mt_subsample') + skip_repeat_annotation = parseSkipList(val_skip_subworkflows, 'repeat_annotation') + skip_repeat_calling = parseSkipList(val_skip_subworkflows, 'repeat_calling') + skip_snv_annotation = parseSkipList(val_skip_subworkflows, 'snv_annotation') + skip_snv_calling = parseSkipList(val_skip_subworkflows, 'snv_calling') + skip_sv_annotation = parseSkipList(val_skip_subworkflows, 'sv_annotation') + skip_sv_calling = parseSkipList(val_skip_subworkflows, 'sv_calling') + skip_generate_clinical_set = parseSkipList(val_skip_subworkflows, 'generate_clinical_set') + + // + // Validate parameter combinations + // + if (val_save_noalt_mapped_as_cram && !val_exclude_alt) { + error("save_noalt_mapped_as_cram requires exclude_alt to be set to true") + } + + // + // SV caller priority + // + if (skip_germlinecnvcaller) { + if (val_analysis_type.equals("wgs")) { + ch_svcaller_priority = channel.value(["tiddit", "manta", "cnvnator"]) + } else { + ch_svcaller_priority = channel.value([]) + } + } else { + if (val_analysis_type.equals("wgs")) { + ch_svcaller_priority = channel.value(["tiddit", "manta", "gcnvcaller", "cnvnator"]) + } else { + ch_svcaller_priority = channel.value(["manta", "gcnvcaller"]) + } + } + + // + // Create chromosome bed and intervals for splitting and gathering operations + // + ch_scatter_genome_split_intervals = channel.empty() + if (!skip_snv_annotation) { + SCATTER_GENOME ( + ch_genome_dictionary, + ch_genome_fai, + ch_genome_fasta + ) + ch_scatter_genome_split_intervals = SCATTER_GENOME.out.gatk4_splitintervals_split_intervals + } + RAREDISEASE ( - fastq, - alignment, - samples, - case_info + ch_alignments, + ch_bait_intervals, + ch_cadd_header, + ch_cadd_prescored, + ch_cadd_resources, + ch_call_interval, + ch_case_info, + ch_dbsnp, + ch_dbsnp_tbi, + ch_foundin_header, + ch_gcnvcaller_model, + ch_genome_bwafastalignindex, + ch_genome_bwaindex, + ch_genome_bwamem2index, + ch_genome_bwamemeindex, + ch_genome_chrsizes, + ch_genome_dictionary, + ch_genome_fai, + ch_genome_fasta, + ch_genome_hisat2index, + ch_gens_gnomad_pos, + ch_gens_interval_list, + ch_gens_pon_female, + ch_gens_pon_male, + ch_gnomad_af, + ch_hgnc_ids, + ch_intervals_wgs, + ch_intervals_y, + ch_manta_regions, + ch_me_references, + ch_me_svdb_resources, + ch_ml_model, + ch_mt_bwaindex, + ch_mt_bwamem2index, + ch_mt_dictionary, + ch_mt_fai, + ch_mt_fasta, + ch_mt_intervals, + ch_mt_lastdb, + ch_mtshift_backchain, + ch_mtshift_bwaindex, + ch_mtshift_bwamem2index, + ch_mtshift_dictionary, + ch_mtshift_fai, + ch_mtshift_fasta, + ch_mtshift_intervals, + ch_ngsbits_method, + ch_par_bed, + ch_pedfile, + ch_ploidy_model, + ch_readcount_intervals, + ch_reads, + ch_reduced_penetrance, + ch_rtg_truthvcfs, + ch_sambamba_bed, + ch_sample_id_map, + ch_samples, + ch_scatter_genome_split_intervals, + ch_score_config_mt, + ch_score_config_snv, + ch_score_config_sv, + ch_sdf, + ch_sentieon_pcr_indel_model, + ch_subdepth, + ch_svcaller_priority, + ch_svd_bed, + ch_svd_mu, + ch_svd_ud, + ch_svdb_bedpedbs, + ch_svdb_dbs, + ch_target_bed, + ch_target_intervals, + ch_variant_catalog, + ch_variant_consequences_snv, + ch_variant_consequences_sv, + ch_vcf2cytosure_blacklist, + ch_vcfanno_extra, + ch_vcfanno_lua, + ch_vcfanno_resources, + ch_vcfanno_toml, + ch_vep_cache, + ch_vep_extra_files, + ch_versions, + skip_me_calling, + skip_me_annotation, + skip_mt_annotation, + skip_mt_subsample, + skip_repeat_annotation, + skip_repeat_calling, + skip_snv_annotation, + skip_snv_calling, + skip_sv_annotation, + skip_sv_calling, + skip_generate_clinical_set, + skip_fastp, + skip_fastqc, + skip_gens, + skip_germlinecnvcaller, + skip_mitosalt, + skip_ngsbits, + skip_peddy, + skip_smncopynumbercaller, + skip_vcf2cytosure, + val_aligner, + val_analysis_type, + val_cadd_resources, + val_concatenate_snv_calls, + val_skip_split_multiallelics, + val_exclude_alt, + val_extract_alignments, + val_genome, + val_heavy_strand_origin_end, + val_heavy_strand_origin_start, + val_homoplasmy_af_threshold, + val_light_strand_origin_end, + val_light_strand_origin_start, + val_mito_length, + val_mito_name, + val_mitosalt_breakspan, + val_mitosalt_breakthreshold, + val_mitosalt_cluster_threshold, + val_mitosalt_deletion_threshold_max, + val_mitosalt_deletion_threshold_min, + val_mitosalt_evalue_threshold, + val_mitosalt_exclude, + val_mitosalt_flank, + val_mitosalt_heteroplasmy_limit, + val_mitosalt_paired_distance, + val_mitosalt_score_threshold, + val_mitosalt_sizelimit, + val_mitosalt_split_distance_threshold, + val_mitosalt_split_length, + val_mt_aligner, + val_mt_subsample_approach, + val_mt_subsample_rd, + val_mt_subsample_seed, + val_multiqc_config, + val_multiqc_logo, + val_multiqc_methods_description, + val_multiqc_samples, + val_outdir, + val_platform, + val_run_mt_for_wes, + val_run_rtgvcfeval, + val_run_vcfanno_db_sanity_check, + val_sample_id_map, + val_save_all_mapped_as_cram, + val_save_noalt_mapped_as_cram, + val_svdb_query_bedpedbs, + val_svdb_query_dbs, + val_target_bed, + val_variant_caller, + val_vep_cache_version, + skip_contamination, + ch_contamination_sites, + ch_intervals_contamination ) emit: - multiqc_report = RAREDISEASE.out.multiqc_report // channel: /path/to/multiqc_report.html + align_fastp_out = RAREDISEASE.out.align_fastp_out // channel: [ val(meta), path(json|html|log|reads|reads_fail|reads_merged) ] + align_genome_marked_bam = RAREDISEASE.out.align_genome_marked_bam // channel: [ val(meta), path(bam) ] + align_genome_marked_bai = RAREDISEASE.out.align_genome_marked_bai // channel: [ val(meta), path(bai) ] + align_genome_marked_cram = RAREDISEASE.out.align_genome_marked_cram // channel: [ val(meta), path(cram) ] + align_genome_marked_crai = RAREDISEASE.out.align_genome_marked_crai // channel: [ val(meta), path(crai) ] + align_markdup_metrics = RAREDISEASE.out.align_markdup_metrics // channel: [ val(meta), path(metrics) ] + multiqc_report = RAREDISEASE.out.multiqc_report // channel: /path/to/multiqc_report.html + scatter_genome_split_intervals = ch_scatter_genome_split_intervals // channel: [ val(meta), path(interval_list) ] + qc_bam_chromograph_cov_plots = RAREDISEASE.out.qc_bam_chromograph_cov_plots // channel: [ val(meta), path(png) ] + qc_bam_mosdepth_global_txt = RAREDISEASE.out.qc_bam_mosdepth_global_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_per_base_bed = RAREDISEASE.out.qc_bam_mosdepth_per_base_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_per_base_csi = RAREDISEASE.out.qc_bam_mosdepth_per_base_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_per_base_d4 = RAREDISEASE.out.qc_bam_mosdepth_per_base_d4 // channel: [ val(meta), path(d4) ] + qc_bam_mosdepth_quantized_bed = RAREDISEASE.out.qc_bam_mosdepth_quantized_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_quantized_csi = RAREDISEASE.out.qc_bam_mosdepth_quantized_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_regions_bed = RAREDISEASE.out.qc_bam_mosdepth_regions_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_regions_csi = RAREDISEASE.out.qc_bam_mosdepth_regions_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_regions_txt = RAREDISEASE.out.qc_bam_mosdepth_regions_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_summary_txt = RAREDISEASE.out.qc_bam_mosdepth_summary_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_thresholds_bed = RAREDISEASE.out.qc_bam_mosdepth_thresholds_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_thresholds_csi = RAREDISEASE.out.qc_bam_mosdepth_thresholds_csi // channel: [ val(meta), path(csi) ] + qc_bam_ngsbits_samplegender_tsv = RAREDISEASE.out.qc_bam_ngsbits_samplegender_tsv // channel: [ val(meta), path(tsv) ] + qc_bam_picard_collecthsmetrics_metrics = RAREDISEASE.out.qc_bam_picard_collecthsmetrics_metrics // channel: [ val(meta), path(metrics) ] + qc_bam_picard_collectmultiplemetrics_metrics = RAREDISEASE.out.qc_bam_picard_collectmultiplemetrics_metrics // channel: [ val(meta), path(metrics) ] + qc_bam_picard_collectmultiplemetrics_pdf = RAREDISEASE.out.qc_bam_picard_collectmultiplemetrics_pdf // channel: [ val(meta), path(pdf) ] + qc_bam_sambamba_depth_bed = RAREDISEASE.out.qc_bam_sambamba_depth_bed // channel: [ val(meta), path(bed) ] + qc_bam_tiddit_cov_cov = RAREDISEASE.out.qc_bam_tiddit_cov_cov // channel: [ val(meta), path(bed) ] + qc_bam_tiddit_cov_wig = RAREDISEASE.out.qc_bam_tiddit_cov_wig // channel: [ val(meta), path(wig) ] + qc_bam_ucsc_wigtobigwig_bw = RAREDISEASE.out.qc_bam_ucsc_wigtobigwig_bw // channel: [ val(meta), path(bw) ] + qc_bam_verifybamid_ancestry = RAREDISEASE.out.qc_bam_verifybamid_ancestry // channel: [ val(meta), path(ancestry) ] + qc_bam_verifybamid_bed = RAREDISEASE.out.qc_bam_verifybamid_bed // channel: [ val(meta), path(bed) ] + qc_bam_verifybamid_log = RAREDISEASE.out.qc_bam_verifybamid_log // channel: [ val(meta), path(log) ] + qc_bam_verifybamid_mu = RAREDISEASE.out.qc_bam_verifybamid_mu // channel: [ val(meta), path(mu) ] + qc_bam_verifybamid_self_sm = RAREDISEASE.out.qc_bam_verifybamid_self_sm // channel: [ val(meta), path(selfSM) ] + qc_bam_verifybamid_ud = RAREDISEASE.out.qc_bam_verifybamid_ud // channel: [ val(meta), path(ud) ] + qc_bam_wgsmetrics_wg = RAREDISEASE.out.qc_bam_wgsmetrics_wg // channel: [ val(meta), path(metrics) ] + qc_bam_wgsmetrics_y = RAREDISEASE.out.qc_bam_wgsmetrics_y // channel: [ val(meta), path(metrics) ] + call_sv_vcf = RAREDISEASE.out.call_sv_vcf // channel: [ val(meta), path(vcf) ] + call_sv_tbi = RAREDISEASE.out.call_sv_tbi // channel: [ val(meta), path(tbi) ] + saltshaker_html = RAREDISEASE.out.saltshaker_html // channel: [ val(meta), path(html) ] + saltshaker_plot = RAREDISEASE.out.saltshaker_plot // channel: [ val(meta), path(png) ] + generate_cytosure_files_cgh = RAREDISEASE.out.generate_cytosure_files_cgh // channel: [ val(meta), path(cgh) ] + mt_del_result = RAREDISEASE.out.mt_del_result // channel: [ val(meta), path(txt) ] + call_repeat_expansions_expansionhunter_bai = RAREDISEASE.out.call_repeat_expansions_expansionhunter_bai // channel: [ val(meta), path(bai) ] + call_repeat_expansions_expansionhunter_bam = RAREDISEASE.out.call_repeat_expansions_expansionhunter_bam // channel: [ val(meta), path(bam) ] + call_repeat_expansions_expansionhunter_vcf = RAREDISEASE.out.call_repeat_expansions_expansionhunter_vcf // channel: [ val(meta), path(vcf) ] + call_repeat_expansions_stranger_tbi = RAREDISEASE.out.call_repeat_expansions_stranger_tbi // channel: [ val(meta), path(tbi) ] + call_repeat_expansions_stranger_vcf = RAREDISEASE.out.call_repeat_expansions_stranger_vcf // channel: [ val(meta), path(vcf) ] + call_mobile_elements_tbi = RAREDISEASE.out.call_mobile_elements_tbi // channel: [ val(meta), path(tbi) ] + call_mobile_elements_vcf = RAREDISEASE.out.call_mobile_elements_vcf // channel: [ val(meta), path(vcf) ] + ann_csq_pli_me_tbi = RAREDISEASE.out.ann_csq_pli_me_tbi // channel: [ val(meta), path(tbi) ] + ann_csq_pli_me_vcf_ann = RAREDISEASE.out.ann_csq_pli_me_vcf_ann // channel: [ val(meta), path(vcf) ] + call_snv_bcftools_concat_csi = RAREDISEASE.out.call_snv_bcftools_concat_csi // channel: [ val(meta), path(csi) ] + call_snv_bcftools_concat_tbi = RAREDISEASE.out.call_snv_bcftools_concat_tbi // channel: [ val(meta), path(tbi) ] + call_snv_bcftools_concat_vcf = RAREDISEASE.out.call_snv_bcftools_concat_vcf // channel: [ val(meta), path(vcf) ] + call_snv_deepvariant_report = RAREDISEASE.out.call_snv_deepvariant_report // channel: [ val(meta), path(html) ] + call_snv_genome_tabix = RAREDISEASE.out.call_snv_genome_tabix // channel: [ val(meta), path(tbi) ] + call_snv_genome_vcf = RAREDISEASE.out.call_snv_genome_vcf // channel: [ val(meta), path(vcf) ] + call_snv_mt_tabix = RAREDISEASE.out.call_snv_mt_tabix // channel: [ val(meta), path(tbi) ] + call_snv_mt_vcf = RAREDISEASE.out.call_snv_mt_vcf // channel: [ val(meta), path(vcf) ] + gens_baf_bed_gz = RAREDISEASE.out.gens_baf_bed_gz // channel: [ val(meta), path(bed.gz) ] + gens_baf_bed_tbi = RAREDISEASE.out.gens_baf_bed_tbi // channel: [ val(meta), path(tbi) ] + gens_cov_bed_gz = RAREDISEASE.out.gens_cov_bed_gz // channel: [ val(meta), path(bed.gz) ] + gens_cov_bed_tbi = RAREDISEASE.out.gens_cov_bed_tbi // channel: [ val(meta), path(tbi) ] + annotate_genome_snvs_bcftools_concat_tbi = RAREDISEASE.out.annotate_genome_snvs_bcftools_concat_tbi // channel: [ val(meta), path(tbi) ] + annotate_genome_snvs_bcftools_concat_vcf = RAREDISEASE.out.annotate_genome_snvs_bcftools_concat_vcf // channel: [ val(meta), path(vcf) ] + annotate_genome_snvs_chromograph_autozyg_plots = RAREDISEASE.out.annotate_genome_snvs_chromograph_autozyg_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_chromograph_regions_plots = RAREDISEASE.out.annotate_genome_snvs_chromograph_regions_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_chromograph_sites_plots = RAREDISEASE.out.annotate_genome_snvs_chromograph_sites_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_rhocall_viz_bed = RAREDISEASE.out.annotate_genome_snvs_rhocall_viz_bed // channel: [ val(meta), path(bed) ] + annotate_genome_snvs_rhocall_viz_wig = RAREDISEASE.out.annotate_genome_snvs_rhocall_viz_wig // channel: [ val(meta), path(wig) ] + annotate_genome_snvs_ucsc_wigtobigwig_bw = RAREDISEASE.out.annotate_genome_snvs_ucsc_wigtobigwig_bw // channel: [ val(meta), path(bw) ] + annotate_mt_snvs_ensemblvep_mt_tbi = RAREDISEASE.out.annotate_mt_snvs_ensemblvep_mt_tbi // channel: [ val(meta), path(tbi) ] + annotate_mt_snvs_ensemblvep_mt_vcf = RAREDISEASE.out.annotate_mt_snvs_ensemblvep_mt_vcf // channel: [ val(meta), path(vcf) ] + rank_snv_tbi = RAREDISEASE.out.rank_snv_tbi // channel: [ val(meta), path(tbi) ] + rank_snv_vcf = RAREDISEASE.out.rank_snv_vcf // channel: [ val(meta), path(vcf) ] + rank_mt_tbi = RAREDISEASE.out.rank_mt_tbi // channel: [ val(meta), path(tbi) ] + rank_mt_vcf = RAREDISEASE.out.rank_mt_vcf // channel: [ val(meta), path(vcf) ] + rank_sv_tbi = RAREDISEASE.out.rank_sv_tbi // channel: [ val(meta), path(tbi) ] + rank_sv_vcf = RAREDISEASE.out.rank_sv_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_baseline_tbi = RAREDISEASE.out.variant_evaluation_baseline_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_baseline_vcf = RAREDISEASE.out.variant_evaluation_baseline_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_false_negatives_tbi = RAREDISEASE.out.variant_evaluation_false_negatives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_false_negatives_vcf = RAREDISEASE.out.variant_evaluation_false_negatives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_false_positives_tbi = RAREDISEASE.out.variant_evaluation_false_positives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_false_positives_vcf = RAREDISEASE.out.variant_evaluation_false_positives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_non_snp_roc = RAREDISEASE.out.variant_evaluation_non_snp_roc // channel: [ val(meta), path(tsv) ] + variant_evaluation_phasing = RAREDISEASE.out.variant_evaluation_phasing // channel: [ val(meta), path(txt) ] + variant_evaluation_snp_roc = RAREDISEASE.out.variant_evaluation_snp_roc // channel: [ val(meta), path(tsv) ] + variant_evaluation_summary = RAREDISEASE.out.variant_evaluation_summary // channel: [ val(meta), path(txt) ] + variant_evaluation_true_positives_tbi = RAREDISEASE.out.variant_evaluation_true_positives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_true_positives_vcf = RAREDISEASE.out.variant_evaluation_true_positives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_weighted_roc = RAREDISEASE.out.variant_evaluation_weighted_roc // channel: [ val(meta), path(tsv) ] + prepare_references_bait_intervals = ch_bait_intervals + prepare_references_dbsnp = ch_dbsnp + prepare_references_dbsnp_tbi = ch_dbsnp_tbi + prepare_references_genome_bwafastalignindex = ch_genome_bwafastalignindex + prepare_references_genome_bwaindex = ch_genome_bwaindex + prepare_references_genome_bwamem2index = ch_genome_bwamem2index + prepare_references_genome_bwamemeindex = ch_genome_bwamemeindex + prepare_references_genome_chrsizes = ch_genome_chrsizes + prepare_references_genome_dictionary = ch_genome_dictionary + prepare_references_genome_fai = ch_genome_fai + prepare_references_genome_fasta = ch_genome_fasta + prepare_references_genome_hisat2index = ch_genome_hisat2index + prepare_references_gnomad_af = ch_gnomad_af + prepare_references_mt_bwaindex = ch_mt_bwaindex + prepare_references_mt_bwamem2index = ch_mt_bwamem2index + prepare_references_mt_dictionary = ch_mt_dictionary + prepare_references_mt_fai = ch_mt_fai + prepare_references_mt_fasta = ch_mt_fasta + prepare_references_mt_intervals = ch_mt_intervals + prepare_references_mt_lastdb = ch_mt_lastdb + prepare_references_mtshift_backchain = ch_mtshift_backchain + prepare_references_mtshift_bwaindex = ch_mtshift_bwaindex + prepare_references_mtshift_bwamem2index = ch_mtshift_bwamem2index + prepare_references_mtshift_dictionary = ch_mtshift_dictionary + prepare_references_mtshift_fai = ch_mtshift_fai + prepare_references_mtshift_fasta = ch_mtshift_fasta + prepare_references_mtshift_intervals = ch_mtshift_intervals + prepare_references_sdf = ch_sdf + prepare_references_target_bed = ch_target_bed + prepare_references_target_intervals = ch_target_intervals + prepare_references_vcfanno_extra = ch_vcfanno_extra + prepare_references_vep_cache = ch_vep_cache + subsample_mt_bai = RAREDISEASE.out.subsample_mt_bai // channel: [ val(meta), path(bai) ] + subsample_mt_bam = RAREDISEASE.out.subsample_mt_bam // channel: [ val(meta), path(bam) ] + contamination_table = RAREDISEASE.out.contamination_table // channel: [ val(meta), path(table) ] + contamination_pileup = RAREDISEASE.out.contamination_pileup // channel: [ val(meta), path(table) ] + publish = RAREDISEASE.out.publish + .mix(ch_pedfile_publish) // channel: [ val(destination), val(value) ] } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -67,20 +711,131 @@ workflow { PIPELINE_INITIALISATION ( params.version, params.validate_params, - params.monochrome_logs, args, params.outdir, - params.input + params.input, + params.help, + params.help_full, + params.monochrome_logs, + params.show_hidden ) - // // WORKFLOW: Run main workflow // NFCORE_RAREDISEASE ( - PIPELINE_INITIALISATION.out.reads, PIPELINE_INITIALISATION.out.align, + PIPELINE_INITIALISATION.out.case_info, + PIPELINE_INITIALISATION.out.reads, PIPELINE_INITIALISATION.out.samples, - PIPELINE_INITIALISATION.out.case_info + params.aligner, + params.analysis_type, + params.bwa, + params.bwafastalign, + params.bwamem2, + params.bwameme, + params.cadd_prescored, + params.cadd_resources, + params.call_interval, + params.concatenate_snv_calls, + params.skip_split_multiallelics, + params.exclude_alt, + params.extract_alignments, + params.fai, + params.fasta, + params.gcnvcaller_model, + params.genome, + params.gens_gnomad_pos, + params.gens_interval_list, + params.gens_pon_female, + params.gens_pon_male, + params.gnomad_af, + params.gnomad_af_idx, + params.heavy_strand_origin_end, + params.heavy_strand_origin_start, + params.homoplasmy_af_threshold, + params.intervals_wgs, + params.intervals_y, + params.known_dbsnp, + params.known_dbsnp_tbi, + params.light_strand_origin_end, + params.light_strand_origin_start, + params.manta_call_regions, + params.manta_call_regions_tbi, + params.mito_length, + params.mito_name, + params.mitosalt_breakspan, + params.mitosalt_breakthreshold, + params.mitosalt_cluster_threshold, + params.mitosalt_deletion_threshold_max, + params.mitosalt_deletion_threshold_min, + params.mitosalt_evalue_threshold, + params.mitosalt_exclude, + params.mitosalt_flank, + params.mitosalt_heteroplasmy_limit, + params.mitosalt_paired_distance, + params.mitosalt_score_threshold, + params.mitosalt_sizelimit, + params.mitosalt_split_distance_threshold, + params.mitosalt_split_length, + params.ml_model, + params.mobile_element_references, + params.mobile_element_svdb_annotations, + params.mt_aligner, + params.mt_fasta, + params.mt_subsample_approach, + params.mt_subsample_rd, + params.mt_subsample_seed, + params.multiqc_config, + params.multiqc_logo, + params.multiqc_methods_description, + params.multiqc_samples, + params.ngsbits_samplegender_method, + params.outdir, + params.par_bed, + params.platform, + params.ploidy_model, + params.readcount_intervals, + params.reduced_penetrance, + params.rtg_truthvcfs, + params.run_mt_for_wes, + params.run_rtgvcfeval, + params.run_vcfanno_db_sanity_check, + params.sambamba_regions, + params.sample_id_map, + params.save_all_mapped_as_cram, + params.save_noalt_mapped_as_cram, + params.save_reference, + params.score_config_mt, + params.score_config_snv, + params.score_config_sv, + params.sdf, + params.sentieon_dnascope_pcr_indel_model, + params.sequence_dictionary, + params.skip_tools, + params.skip_subworkflows, + params.mitosalt_depth, + params.svdb_query_bedpedbs, + params.svdb_query_dbs, + params.target_bed, + params.variant_caller, + params.variant_catalog, + params.variant_consequences_snv, + params.variant_consequences_sv, + params.vcf2cytosure_blacklist, + params.vcfanno_extra_resources, + params.vcfanno_lua, + params.vcfanno_resources, + params.vcfanno_toml, + params.vep_cache_version, + params.vep_filters, + params.vep_filters_scout_fmt, + params.vep_plugin_files, + params.verifybamid_svd_bed, + params.verifybamid_svd_mu, + params.verifybamid_svd_ud, + params.vep_cache, + params.contamination_sites, + params.contamination_sites_tbi ) // // SUBWORKFLOW: Run completion tasks @@ -91,9 +846,213 @@ workflow { params.plaintext_email, params.outdir, params.monochrome_logs, - params.hook_url, NFCORE_RAREDISEASE.out.multiqc_report ) + + publish: + alignment = NFCORE_RAREDISEASE.out.align_genome_marked_bam + .mix(NFCORE_RAREDISEASE.out.align_genome_marked_bai) + .mix(NFCORE_RAREDISEASE.out.align_genome_marked_cram) + .mix(NFCORE_RAREDISEASE.out.align_genome_marked_crai) + .mix(NFCORE_RAREDISEASE.out.align_markdup_metrics) + .mix(NFCORE_RAREDISEASE.out.subsample_mt_bam) + .mix(NFCORE_RAREDISEASE.out.subsample_mt_bai) + fastp = NFCORE_RAREDISEASE.out.align_fastp_out + ngsbits_samplegender = NFCORE_RAREDISEASE.out.qc_bam_ngsbits_samplegender_tsv + qc_bam = NFCORE_RAREDISEASE.out.qc_bam_chromograph_cov_plots.transpose() + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_global_txt) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_per_base_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_per_base_csi) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_per_base_d4) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_quantized_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_quantized_csi) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_regions_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_regions_csi) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_regions_txt) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_summary_txt) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_thresholds_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_mosdepth_thresholds_csi) + .mix(NFCORE_RAREDISEASE.out.qc_bam_picard_collecthsmetrics_metrics) + .mix(NFCORE_RAREDISEASE.out.qc_bam_picard_collectmultiplemetrics_metrics.transpose()) + .mix(NFCORE_RAREDISEASE.out.qc_bam_picard_collectmultiplemetrics_pdf.transpose()) + .mix(NFCORE_RAREDISEASE.out.qc_bam_sambamba_depth_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_tiddit_cov_cov) + .mix(NFCORE_RAREDISEASE.out.qc_bam_tiddit_cov_wig) + .mix(NFCORE_RAREDISEASE.out.qc_bam_ucsc_wigtobigwig_bw) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_ancestry) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_bed) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_log) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_mu) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_self_sm) + .mix(NFCORE_RAREDISEASE.out.qc_bam_verifybamid_ud) + .mix(NFCORE_RAREDISEASE.out.qc_bam_wgsmetrics_wg) + .mix(NFCORE_RAREDISEASE.out.qc_bam_wgsmetrics_y) + call_repeat_expansions = NFCORE_RAREDISEASE.out.call_repeat_expansions_expansionhunter_bam + .mix(NFCORE_RAREDISEASE.out.call_repeat_expansions_expansionhunter_bai) + .mix(NFCORE_RAREDISEASE.out.call_repeat_expansions_expansionhunter_vcf) + .mix(NFCORE_RAREDISEASE.out.call_repeat_expansions_stranger_vcf) + .mix(NFCORE_RAREDISEASE.out.call_repeat_expansions_stranger_tbi) + call_mobile_elements = NFCORE_RAREDISEASE.out.call_mobile_elements_vcf + .mix(NFCORE_RAREDISEASE.out.call_mobile_elements_tbi) + annotate_mobile_elements = NFCORE_RAREDISEASE.out.ann_csq_pli_me_vcf_ann + .mix(NFCORE_RAREDISEASE.out.ann_csq_pli_me_tbi) + call_sv = NFCORE_RAREDISEASE.out.call_sv_vcf + .mix(NFCORE_RAREDISEASE.out.call_sv_tbi) + .mix(NFCORE_RAREDISEASE.out.saltshaker_html) + .mix(NFCORE_RAREDISEASE.out.saltshaker_plot) + .mix(NFCORE_RAREDISEASE.out.mt_del_result) + generate_cytosure_files = NFCORE_RAREDISEASE.out.generate_cytosure_files_cgh + call_snv_genome = NFCORE_RAREDISEASE.out.call_snv_genome_vcf + .mix(NFCORE_RAREDISEASE.out.call_snv_genome_tabix) + .mix(NFCORE_RAREDISEASE.out.call_snv_deepvariant_report) + call_snv_mt = NFCORE_RAREDISEASE.out.call_snv_mt_vcf + .mix(NFCORE_RAREDISEASE.out.call_snv_mt_tabix) + call_snv_concatenated = NFCORE_RAREDISEASE.out.call_snv_bcftools_concat_vcf + .mix(NFCORE_RAREDISEASE.out.call_snv_bcftools_concat_tbi) + .mix(NFCORE_RAREDISEASE.out.call_snv_bcftools_concat_csi) + gens = NFCORE_RAREDISEASE.out.gens_baf_bed_gz + .mix(NFCORE_RAREDISEASE.out.gens_baf_bed_tbi) + .mix(NFCORE_RAREDISEASE.out.gens_cov_bed_gz) + .mix(NFCORE_RAREDISEASE.out.gens_cov_bed_tbi) + annotate_snv_genome = NFCORE_RAREDISEASE.out.annotate_genome_snvs_bcftools_concat_vcf + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_bcftools_concat_tbi) + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_chromograph_autozyg_plots) + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_chromograph_regions_plots) + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_chromograph_sites_plots) + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_rhocall_viz_bed) + .mix(NFCORE_RAREDISEASE.out.annotate_genome_snvs_rhocall_viz_wig) + annotate_snv_genome_rhocallviz_bw = NFCORE_RAREDISEASE.out.annotate_genome_snvs_ucsc_wigtobigwig_bw + annotate_snv_mt = NFCORE_RAREDISEASE.out.annotate_mt_snvs_ensemblvep_mt_vcf + .mix(NFCORE_RAREDISEASE.out.annotate_mt_snvs_ensemblvep_mt_tbi) + contamination = NFCORE_RAREDISEASE.out.contamination_table + contamination_pileups = NFCORE_RAREDISEASE.out.contamination_pileup + rank_variants = NFCORE_RAREDISEASE.out.rank_snv_vcf + .mix(NFCORE_RAREDISEASE.out.rank_snv_tbi) + .mix(NFCORE_RAREDISEASE.out.rank_mt_vcf) + .mix(NFCORE_RAREDISEASE.out.rank_mt_tbi) + .mix(NFCORE_RAREDISEASE.out.rank_sv_vcf) + .mix(NFCORE_RAREDISEASE.out.rank_sv_tbi) + variant_evaluation = NFCORE_RAREDISEASE.out.variant_evaluation_true_positives_vcf + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_true_positives_tbi) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_false_negatives_vcf) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_false_negatives_tbi) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_false_positives_vcf) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_false_positives_tbi) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_baseline_vcf) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_baseline_tbi) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_snp_roc) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_non_snp_roc) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_weighted_roc) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_summary) + .mix(NFCORE_RAREDISEASE.out.variant_evaluation_phasing) + references = NFCORE_RAREDISEASE.out.prepare_references_dbsnp + .mix(NFCORE_RAREDISEASE.out.prepare_references_dbsnp_tbi) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_bwaindex) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_bwafastalignindex) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_bwamem2index) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_bwamemeindex) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_fai) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_fasta) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_hisat2index) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_dictionary) + .mix(NFCORE_RAREDISEASE.out.prepare_references_genome_chrsizes) + .mix(NFCORE_RAREDISEASE.out.prepare_references_bait_intervals) + .mix(NFCORE_RAREDISEASE.out.prepare_references_gnomad_af) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_bwaindex) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_bwamem2index) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_dictionary) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_fai) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_fasta) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_intervals) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mt_lastdb) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_backchain) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_bwaindex) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_bwamem2index) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_dictionary) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_fai) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_fasta) + .mix(NFCORE_RAREDISEASE.out.prepare_references_mtshift_intervals) + .mix(NFCORE_RAREDISEASE.out.prepare_references_sdf) + .mix(NFCORE_RAREDISEASE.out.prepare_references_target_bed) + .mix(NFCORE_RAREDISEASE.out.prepare_references_target_intervals) + .mix(NFCORE_RAREDISEASE.out.prepare_references_vcfanno_extra) + .mix(NFCORE_RAREDISEASE.out.prepare_references_vep_cache) + processed_references = NFCORE_RAREDISEASE.out.scatter_genome_split_intervals + subworkflow_results = NFCORE_RAREDISEASE.out.publish +} + +output { + alignment { + path { _meta, _file -> "alignment/" } + } + fastp { + path { _meta, _file -> "trimming/" } + } + ngsbits_samplegender { + path { _meta, _file -> "ngsbits_samplegender/" } + } + qc_bam { + path { _meta, _file -> "qc_bam/" } + } + call_repeat_expansions { + path { _meta, _file -> "repeat_expansions/" } + } + call_mobile_elements { + path { _meta, _file -> "call_mobile_elements/" } + } + annotate_mobile_elements { + path { _meta, _file -> "annotate_mobile_elements/" } + } + call_sv { + path { _meta, _file -> "call_sv/" } + } + generate_cytosure_files { + path { _meta, _file -> "vcf2cytosure/" } + } + call_snv_genome { + path { _meta, _file -> "call_snv/genome/" } + } + call_snv_mt { + path { _meta, _file -> "call_snv/mitochondria/" } + } + call_snv_concatenated { + path { _meta, _file -> "call_snv/concatenated_calls/" } + } + gens { + path { _meta, _file -> "gens/" } + } + annotate_snv_genome { + path { _meta, _file -> "annotate_snv/genome/" } + } + annotate_snv_genome_rhocallviz_bw { + path { meta, _file -> "annotate_snv/genome/${meta.sample}_rhocallviz/" } + } + annotate_snv_mt { + path { _meta, _file -> "annotate_snv/mitochondria/" } + } + contamination { + path { _meta, _file -> "qc/contamination/" } + } + contamination_pileups { + path { _meta, _file -> "qc/contamination/pileups/" } + } + rank_variants { + path { _meta, _file -> "rank_and_filter/" } + } + variant_evaluation { + path { _meta, _file -> "rtgvcfeval/" } + } + references { + path { _meta, _file -> "references/" } + enabled params.save_reference + } + processed_references { + path { _meta, _file -> "processed_references/" } + enabled params.save_reference + } + subworkflow_results { + path { destination, _value -> destination } + } } /* diff --git a/modules.json b/modules.json index edb5cc6dc..9f9614582 100644 --- a/modules.json +++ b/modules.json @@ -7,525 +7,574 @@ "nf-core": { "bcftools/annotate": { "branch": "master", - "git_sha": "cb08035150685b11d890d90c9534d4f16869eaec", + "git_sha": "3d9c2f4beaa4f62b3f006928fd9095a496d1e5a8", "installed_by": ["modules"] }, "bcftools/concat": { "branch": "master", - "git_sha": "d1e0ec7670fa77905a378627232566ce54c3c26d", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/filter": { "branch": "master", - "git_sha": "f85dbddd7a335fc0f5ac331e8d22ca94123b654b", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/merge": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "3d9c2f4beaa4f62b3f006928fd9095a496d1e5a8", "installed_by": ["modules"] }, "bcftools/norm": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", + "installed_by": ["modules"] + }, + "bcftools/pluginsetgt": { + "branch": "master", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/reheader": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/roh": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/sort": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", "installed_by": ["modules"] }, "bcftools/view": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", - "installed_by": ["modules"] + "git_sha": "6383d8fe58f9498eecd5aa303e71a4a932d1e9f6", + "installed_by": ["modules", "vcf_filter_bcftools_ensemblvep"] }, "bedtools/genomecov": { "branch": "master", - "git_sha": "bfa8975eefb8df3e480a44ac9e594f23f52b2963", + "git_sha": "88d43dad73a675e66bff49ebb57fe657a5909018", "installed_by": ["modules"] }, "bedtools/slop": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "88d43dad73a675e66bff49ebb57fe657a5909018", "installed_by": ["modules"] }, "bwa/index": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "966ba9887e2b04d89d64db06c01508873bde13b1", "installed_by": ["modules"] }, "bwa/mem": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "707241c72951f24fd89982c4c80c5983a4c437ef", + "installed_by": ["modules"] + }, + "bwafastalign/index": { + "branch": "master", + "git_sha": "4ddd2d28518c7475bc76f0dd0e0451dd0e19df2a", + "installed_by": ["modules"] + }, + "bwafastalign/mem": { + "branch": "master", + "git_sha": "d6379deecb794ad5cc6234f3208085aaee27b327", "installed_by": ["modules"] }, "bwamem2/index": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "5dd46a36fca68d6ad1a6b22ec47adc8c6863717d", "installed_by": ["modules"] }, "bwamem2/mem": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "8325a8155a77a336a613a504b8e4d6cea7a2344a", "installed_by": ["modules"] }, "bwameme/index": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "7a41710e25fdcdf8e4d5b324f2eb74022ffc77ff", "installed_by": ["modules"] }, "bwameme/mem": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "ead2c49d7abda0172e1a0abf585b305b690fb8a8", "installed_by": ["modules"] }, "cadd": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "64ab14a6905e5c9d649f61e2757a1e600dbdb8e0", "installed_by": ["modules"] }, "cat/cat": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "7ed72ef972290b93d0bdd7c60ff00a693250f77a", "installed_by": ["modules"] }, - "chromograph": { + "cat/fastq": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "5d28ea7cfaebcfae6f74d1067ea766d8ff19dff3", "installed_by": ["modules"] }, - "cnvnator/cnvnator": { - "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", - "installed_by": ["modules"], - "patch": "modules/nf-core/cnvnator/cnvnator/cnvnator-cnvnator.diff" - }, - "cnvnator/convert2vcf": { + "chromograph": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309", "installed_by": ["modules"] }, - "deepvariant/rundeepvariant": { + "cnvnator/cnvnator": { "branch": "master", - "git_sha": "470ac76fb4fbba2a9284c8b65191119c8bfe5a69", + "git_sha": "dfe412ff862fdafd658b0d7beca1e084800ba5b2", "installed_by": ["modules"] }, - "eklipse": { + "cnvnator/convert2vcf": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "dfe412ff862fdafd658b0d7beca1e084800ba5b2", "installed_by": ["modules"] }, - "ensemblvep/filtervep": { + "deepvariant/rundeepvariant": { "branch": "master", - "git_sha": "6e3585d9ad20b41adc7d271009f8cb5e191ecab4", - "installed_by": ["modules"] + "git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309", + "installed_by": ["modules"], + "patch": "modules/nf-core/deepvariant/rundeepvariant/deepvariant-rundeepvariant.diff" }, "ensemblvep/vep": { "branch": "master", - "git_sha": "9f9e1fc31cb35876922070c0e601ae05abae5cae", + "git_sha": "34505e1fc5e9f4fd641210ca440acff6bd33b842", "installed_by": ["modules"], "patch": "modules/nf-core/ensemblvep/vep/ensemblvep-vep.diff" }, "expansionhunter": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "2ad28db4a5a82972c1210dfa7c85f035bb80c4de", "installed_by": ["modules"] }, "fastp": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "a331ecfd1aa48b2b2298aab23bb4516c800e410b", "installed_by": ["modules"] }, "fastqc": { "branch": "master", - "git_sha": "08108058ea36a63f141c25c4e75f9f872a5b2296", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["modules"] }, "gatk4/bedtointervallist": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "a89928b3f8b4fa91e4c783e769dbc10f91c89b32", "installed_by": ["modules"] }, "gatk4/collectreadcounts": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/createsequencedictionary": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/denoisereadcounts": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/determinegermlinecontigploidy": { "branch": "master", - "git_sha": "d6dd4ddea1663edbf15f40e089cc16db96e75f1d", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/filtermutectcalls": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/germlinecnvcaller": { "branch": "master", - "git_sha": "d6dd4ddea1663edbf15f40e089cc16db96e75f1d", + "git_sha": "86308d628760125908c5c77540517effe0f8880f", "installed_by": ["modules"] }, "gatk4/intervallisttools": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/mergebamalignment": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/mergevcfs": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6881702b1f6671b9471e69f4a75ea4e49a0d0349", "installed_by": ["modules"] }, "gatk4/mutect2": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/postprocessgermlinecnvcalls": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/printreads": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/revertsam": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/samtofastq": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/selectvariants": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/shiftfasta": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/splitintervals": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", "installed_by": ["modules"] }, "gatk4/variantfiltration": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "52b7843bd92ccf833cc12e71cd84aeccf2583852", + "installed_by": ["modules"] + }, + "gatk4/calculatecontamination": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "gatk4/getpileupsummaries": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "gawk": { + "branch": "master", + "git_sha": "c0da8f3a26835d663873001382a708f75766fec6", "installed_by": ["modules"] }, "genmod/annotate": { "branch": "master", - "git_sha": "91a84f951358143e93dc9e03470db4e6a4a7105c", + "git_sha": "7557033683e4016e7d474a23445f75deae2fb729", "installed_by": ["modules"] }, "genmod/compound": { "branch": "master", - "git_sha": "91a84f951358143e93dc9e03470db4e6a4a7105c", + "git_sha": "7557033683e4016e7d474a23445f75deae2fb729", "installed_by": ["modules"] }, "genmod/models": { "branch": "master", - "git_sha": "f888300c726e1f817a9f93a680866ff7e6c669f6", + "git_sha": "7557033683e4016e7d474a23445f75deae2fb729", "installed_by": ["modules"] }, "genmod/score": { "branch": "master", - "git_sha": "f888300c726e1f817a9f93a680866ff7e6c669f6", + "git_sha": "7557033683e4016e7d474a23445f75deae2fb729", "installed_by": ["modules"] }, - "glnexus": { + "gens/preparecovandbaf": { "branch": "master", - "git_sha": "bcf36bc95e3e5605e9859b8e9a49648841e04fe8", + "git_sha": "8220217c9ccad60dc5b395bd76de4d1ddfb7cd80", "installed_by": ["modules"] }, - "haplocheck": { + "glnexus": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "824f8012c9ede97642fd23371c8784fb71074c63", "installed_by": ["modules"] }, - "haplogrep3/classify": { + "hisat2/build": { "branch": "master", - "git_sha": "6af333190d76295671e4374df74513bdd7d1c596", + "git_sha": "66391ca86ea6a081d288afe6a93d242fefcd8c2c", "installed_by": ["modules"] }, - "hmtnote/annotate": { + "last/lastdb": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", - "installed_by": ["modules"], - "patch": "modules/nf-core/hmtnote/annotate/hmtnote-annotate.diff" + "git_sha": "a54953d05812af249d40ffaccb5b8ee371a75866", + "installed_by": ["modules"] }, "manta/germline": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "3485512d3930df1fcb66b5f92af639179bdfe4be", "installed_by": ["modules"] }, "mosdepth": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6832b69ef7f98c54876d6436360b6b945370c615", "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "f0719ae309075ae4a291533883847c3f7c441dad", + "git_sha": "008f9d3e61209bf995edac3ba531f54e269e1215", "installed_by": ["modules"] }, "ngsbits/samplegender": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "54c18191be1e99d78832cb62dc6fb9513ed97eae", "installed_by": ["modules"] }, "peddy": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "7773ae1c42342cacb0b99794aa3827af0d523678", "installed_by": ["modules"] }, "picard/addorreplacereadgroups": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/collecthsmetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/collectmultiplemetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/liftovervcf": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/markduplicates": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/renamesampleinvcf": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "picard/sortvcf": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", - "installed_by": ["modules"] - }, - "qualimap/bamqc": { - "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"] }, "rhocall/annotate": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "f6cba554dee5a4e180a40f5b1d5df651848d95b9", "installed_by": ["modules"] }, "rhocall/viz": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "f6cba554dee5a4e180a40f5b1d5df651848d95b9", "installed_by": ["modules"] }, "rtgtools/format": { "branch": "master", - "git_sha": "167a20a2e267261af397e9ea5bf58426e6345ce7", + "git_sha": "0f04646a9282049b16b3eb35b042e94dfb3340a0", "installed_by": ["modules"] }, "rtgtools/vcfeval": { "branch": "master", - "git_sha": "83e2df1e4ec594beb8a575b4db0b4197900f4ebd", + "git_sha": "0f04646a9282049b16b3eb35b042e94dfb3340a0", + "installed_by": ["modules"] + }, + "saltshaker/call": { + "branch": "master", + "git_sha": "a61c82ad6d255d555aa6c7f1c3c0e90c3735c830", + "installed_by": ["modules"] + }, + "saltshaker/classify": { + "branch": "master", + "git_sha": "a61c82ad6d255d555aa6c7f1c3c0e90c3735c830", + "installed_by": ["modules"] + }, + "saltshaker/plot": { + "branch": "master", + "git_sha": "a61c82ad6d255d555aa6c7f1c3c0e90c3735c830", + "installed_by": ["modules"] + }, + "sambamba/depth": { + "branch": "master", + "git_sha": "ca6da11b05740de461b1e2714037345c0f856201", + "installed_by": ["modules"] + }, + "samtools/collate": { + "branch": "master", + "git_sha": "18ef126d5c91f6f4ad94fe6b939647771d5bc7b0", "installed_by": ["modules"] }, "samtools/faidx": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "b2e78932ef01165fd85829513eaca29eff8e640a", "installed_by": ["modules"] }, "samtools/index": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", "installed_by": ["modules"] }, "samtools/merge": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "440edf75d8782913115a7b72a88392a227f72cc1", "installed_by": ["modules"] }, "samtools/sort": { "branch": "master", - "git_sha": "b7800db9b069ed505db3f9d91b8c72faea9be17b", + "git_sha": "5cb9a8694da0a0e550921636bb60bc8c56445fd7", "installed_by": ["modules"] }, "samtools/stats": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "fe93fde0845f907fc91ad7cc7d797930408824df", "installed_by": ["modules"] }, "samtools/view": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "b2e78932ef01165fd85829513eaca29eff8e640a", "installed_by": ["modules"] }, "sentieon/bwaindex": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "77fc71f9384035ef6259e0e0519d3406b0cda012", "installed_by": ["modules"] }, "sentieon/bwamem": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "77fc71f9384035ef6259e0e0519d3406b0cda012", "installed_by": ["modules"] }, "sentieon/datametrics": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "d9c84ed4564744313bb586928885ebf05f40ad98", "installed_by": ["modules"] }, "sentieon/dedup": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "77fc71f9384035ef6259e0e0519d3406b0cda012", "installed_by": ["modules"] }, "sentieon/dnamodelapply": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "d9c84ed4564744313bb586928885ebf05f40ad98", "installed_by": ["modules"] }, "sentieon/dnascope": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "d9c84ed4564744313bb586928885ebf05f40ad98", "installed_by": ["modules"] }, "sentieon/readwriter": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "d9c84ed4564744313bb586928885ebf05f40ad98", "installed_by": ["modules"] }, "sentieon/wgsmetrics": { "branch": "master", - "git_sha": "eb7b70119bfb1877334c996d13e520c61b21067d", + "git_sha": "77fc71f9384035ef6259e0e0519d3406b0cda012", + "installed_by": ["modules"] + }, + "seqtk/sample": { + "branch": "master", + "git_sha": "a46713779030a5f508117080cbf4b693dd4c6e33", "installed_by": ["modules"] }, "smncopynumbercaller": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "d0afa49c7c23c9e99a47af9bafb4cee449853560", "installed_by": ["modules"] }, "spring/decompress": { "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "git_sha": "d0afa49c7c23c9e99a47af9bafb4cee449853560", "installed_by": ["modules"] }, "stranger": { "branch": "master", - "git_sha": "ffe458cbd1208b82e33e607fa43fbe80df191047", + "git_sha": "f2b138ee1d91f67d31c187317d7e83e429bf0309", "installed_by": ["modules"] }, "svdb/merge": { "branch": "master", - "git_sha": "95185f269ec10a33cde61d294fcd4ba7c66bc6b8", + "git_sha": "7d09b5f86908bdd951e42aef9994ad5bb0f6c307", "installed_by": ["modules"] }, "svdb/query": { "branch": "master", - "git_sha": "eb2c3f7ee2c938ab1a49764bdb1319adaa35492c", + "git_sha": "7d09b5f86908bdd951e42aef9994ad5bb0f6c307", "installed_by": ["modules"] }, "tabix/bgzip": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "91a902fb32d6717da38a9694eb4ad3fade53a8db", "installed_by": ["modules"] }, "tabix/bgziptabix": { "branch": "master", - "git_sha": "f448e846bdadd80fc8be31fbbc78d9f5b5131a45", - "installed_by": ["modules"] + "git_sha": "91a902fb32d6717da38a9694eb4ad3fade53a8db", + "installed_by": ["modules", "vcf_filter_bcftools_ensemblvep"] }, "tabix/tabix": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "524a7d5ef99a0cbfb4feec8bf7062eb6a531931a", "installed_by": ["modules"] }, "tiddit/cov": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "c00e3ab203bdbce7a6ed6b9cd0a3f6406e2f3d8b", "installed_by": ["modules"] }, "tiddit/sv": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "c00e3ab203bdbce7a6ed6b9cd0a3f6406e2f3d8b", "installed_by": ["modules"] }, "ucsc/wigtobigwig": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "d0afa49c7c23c9e99a47af9bafb4cee449853560", "installed_by": ["modules"] }, "untar": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "447f7bc0fa41dfc2400c8cad4c0291880dc060cf", "installed_by": ["modules"] }, "upd": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "2ad28db4a5a82972c1210dfa7c85f035bb80c4de", "installed_by": ["modules"] }, "vcf2cytosure": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "2ad28db4a5a82972c1210dfa7c85f035bb80c4de", "installed_by": ["modules"] }, "vcfanno": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "2ad28db4a5a82972c1210dfa7c85f035bb80c4de", "installed_by": ["modules"] }, "verifybamid/verifybamid2": { "branch": "master", - "git_sha": "33278f733f3452dc77bde5c1a45db3a5f9278ac0", + "git_sha": "2ad28db4a5a82972c1210dfa7c85f035bb80c4de", "installed_by": ["modules"] } } @@ -534,17 +583,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "51ae5406a030d4da1e49e4dab49756844fdd6c7a", + "git_sha": "a3fb7351b1fdb2b1de282b765816bbea190e86a8", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "2fd2cd6d0e7b273747f32e465fdc6bcc3ae0814e", + "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57", "installed_by": ["subworkflows"] } } diff --git a/modules/local/add_most_severe_consequence/main.nf b/modules/local/add_most_severe_consequence/main.nf deleted file mode 100644 index dd9975219..000000000 --- a/modules/local/add_most_severe_consequence/main.nf +++ /dev/null @@ -1,44 +0,0 @@ -process ADD_MOST_SEVERE_CSQ { - tag "$meta.id" - label 'process_low' - - conda "conda-forge::python=3.8.3" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" - - input: - tuple val(meta), path(vcf) - path (variant_consequences) - - output: - tuple val(meta), path("*.vcf") , emit: vcf - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - add_most_severe_consequence.py --file_in ${vcf} --file_out ${prefix}.vcf --variant_csq ${variant_consequences} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - add_most_severe_consequence: v1.1 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}_csq.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - add_most_severe_consequence: v1.1 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ -} diff --git a/modules/local/add_most_severe_pli/main.nf b/modules/local/add_most_severe_pli/main.nf deleted file mode 100644 index e1bfe67db..000000000 --- a/modules/local/add_most_severe_pli/main.nf +++ /dev/null @@ -1,43 +0,0 @@ -process ADD_MOST_SEVERE_PLI { - tag "$meta.id" - label 'process_low' - - conda "conda-forge::python=3.8.3" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" - - input: - tuple val(meta), path(vcf) - - output: - tuple val(meta), path("*.vcf") , emit: vcf - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - add_most_severe_pli.py --file_in ${vcf} --file_out ${prefix}.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - add_most_severe_pli: v1.1 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}_pli.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - add_most_severe_pli: v1.1 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ -} diff --git a/modules/local/add_varcallername_to_bed/environment.yml b/modules/local/add_varcallername_to_bed/environment.yml new file mode 100644 index 000000000..c0ba63205 --- /dev/null +++ b/modules/local/add_varcallername_to_bed/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.21 diff --git a/modules/local/add_varcallername_to_bed/main.nf b/modules/local/add_varcallername_to_bed/main.nf index 11190c2ac..d584c1f14 100644 --- a/modules/local/add_varcallername_to_bed/main.nf +++ b/modules/local/add_varcallername_to_bed/main.nf @@ -4,15 +4,16 @@ process ADD_VARCALLER_TO_BED { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/tabix:1.11--hdfd78af_0' : - 'biocontainers/tabix:1.11--hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/92/92859404d861ae01afb87e2b789aebc71c0ab546397af890c7df74e4ee22c8dd/data' : + 'community.wave.seqera.io/library/htslib:1.21--ff8e28a189fbecaa' }" input: tuple val(meta), path(chromsizes) output: tuple val(meta), path("*.gz"), path("*.tbi"), emit: gz_tbi - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'") , topic: versions , emit: versions_tabix + tuple val("${task.process}"), val('bgzip'), eval("bgzip --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_bgzip when: task.ext.when == null || task.ext.when @@ -26,11 +27,6 @@ process ADD_VARCALLER_TO_BED { awk '{print \$1"\t0\t"\$2"\t$variant_caller\"}' $chromsizes > ${variant_caller}.bed bgzip --threads ${task.cpus} -c $args ${variant_caller}.bed > ${prefix}.bed.gz tabix $args2 ${prefix}.bed.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ stub: @@ -38,10 +34,5 @@ process ADD_VARCALLER_TO_BED { """ touch ${prefix}.bed.gz touch ${prefix}.bed.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/local/calculate_seed_fraction/environment.yml b/modules/local/calculate_seed_fraction/environment.yml new file mode 100644 index 000000000..c38e0465e --- /dev/null +++ b/modules/local/calculate_seed_fraction/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.23 + - conda-forge::python=3.14.3 diff --git a/modules/local/calculate_seed_fraction/main.nf b/modules/local/calculate_seed_fraction/main.nf index 1c367b38d..65fbac484 100644 --- a/modules/local/calculate_seed_fraction/main.nf +++ b/modules/local/calculate_seed_fraction/main.nf @@ -2,10 +2,10 @@ process CALCULATE_SEED_FRACTION { tag "$meta.id" label 'process_low' - conda "conda-forge::python=3.8.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/2f/2fdb3ffa4bac62e98ec062e991217df2ab96e67bbd45a502bd25ff2effecb96e/data': + 'community.wave.seqera.io/library/htslib_python:d1e4474cbf76f4e9' }" input: tuple val(meta), path(cov) @@ -14,34 +14,21 @@ process CALCULATE_SEED_FRACTION { output: tuple val(meta), path("seedfrac.csv"), emit: csv - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('calculate_seed_fraction'), val("1.0"), topic: versions, emit: versions_tabix + tuple val("${task.process}"), val('python'), eval("python -V | sed 's/Python //'"), topic: versions, emit: versions_python when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" """ export MT_COVERAGE=`awk '{cov += \$3}END{ if (NR > 0) print cov / NR }' $cov` python -c "import os;print('%0.6f' % ($seed+ $rd/float(os.environ['MT_COVERAGE'])))" >seedfrac.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - calculate_seed_fraction: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS """ stub: """ touch seedfrac.csv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - calculate_seed_fraction: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS """ } diff --git a/modules/local/create_bed_from_fai/main.nf b/modules/local/create_bed_from_fai/main.nf deleted file mode 100644 index 6b96b6aee..000000000 --- a/modules/local/create_bed_from_fai/main.nf +++ /dev/null @@ -1,39 +0,0 @@ -process BUILD_BED { - tag "$meta.id" - label 'process_single' - - conda "anaconda::gawk=5.1.0" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gawk:5.1.0' : - 'biocontainers/gawk:5.1.0' }" - - input: - tuple val(meta), path(fasta_fai) - - output: - tuple val(meta), path("*.bed") , emit: bed - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - """ - awk 'BEGIN {SEP="\t"}; {print \$1 SEP "0" SEP \$2}' ${fasta_fai} > ${fasta_fai.baseName}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gawk: \$(awk -Wversion | sed '1!d; s/.*Awk //; s/,.*//') - END_VERSIONS - """ - - stub: - """ - touch chr.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gawk: \$(awk -Wversion | sed '1!d; s/.*Awk //; s/,.*//') - END_VERSIONS - """ -} diff --git a/modules/local/create_hgncids_file/environment.yml b/modules/local/create_hgncids_file/environment.yml new file mode 100644 index 000000000..c38e0465e --- /dev/null +++ b/modules/local/create_hgncids_file/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.23 + - conda-forge::python=3.14.3 diff --git a/modules/local/create_hgncids_file/main.nf b/modules/local/create_hgncids_file/main.nf index a6e1abdb3..ecf73e495 100644 --- a/modules/local/create_hgncids_file/main.nf +++ b/modules/local/create_hgncids_file/main.nf @@ -2,60 +2,31 @@ process CREATE_HGNCIDS_FILE { tag "$meta.id" label 'process_single' - conda "conda-forge::python=3.8.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/2f/2fdb3ffa4bac62e98ec062e991217df2ab96e67bbd45a502bd25ff2effecb96e/data': + 'community.wave.seqera.io/library/htslib_python:d1e4474cbf76f4e9' }" input: tuple val(meta), path(input) output: - path("*_reformatted.txt"), emit: txt - path "versions.yml" , emit: versions + tuple val(meta), path("*_reformatted.txt"), emit: txt + tuple val("${task.process}"), val('create_hgncids_file'), val("1.0"), topic: versions, emit: versions_create_hgncids_file + tuple val("${task.process}"), val('python'), eval("python -V | sed 's/Python //'"), topic: versions, emit: versions_python when: task.ext.when == null || task.ext.when script: """ - python3 < versions.yml - "${task.process}": - create_hgncids_file: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS + create_hgncids_file.py --input ${input} --meta-id ${meta.id} + """ stub: """ - python3 < versions.yml - "${task.process}": - create_hgncids_file: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS + create_hgncids_file.py --input ${input} --meta-id ${meta.id} + """ } diff --git a/modules/local/create_pedigree_file/environment.yml b/modules/local/create_pedigree_file/environment.yml new file mode 100644 index 000000000..0c4cd9422 --- /dev/null +++ b/modules/local/create_pedigree_file/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=9.5 diff --git a/modules/local/create_pedigree_file/main.nf b/modules/local/create_pedigree_file/main.nf index 79f2aef0e..45f3b7101 100644 --- a/modules/local/create_pedigree_file/main.nf +++ b/modules/local/create_pedigree_file/main.nf @@ -2,17 +2,17 @@ process CREATE_PEDIGREE_FILE { tag "pedigree" label 'process_single' - conda "conda-forge::python=3.8.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c2/c262fc09eca59edb5a724080eeceb00fb06396f510aefb229c2d2c6897e63975/data' : + 'community.wave.seqera.io/library/coreutils:9.5--ae99c88a9b28c264' }" input: val(samples) output: path("*.ped"), emit: ped - path "versions.yml", emit: versions + tuple val("${task.process}"), val('coreutils'), val("9.5"), topic: versions, emit: versions_coreutils when: task.ext.when == null || task.ext.when @@ -30,23 +30,11 @@ process CREATE_PEDIGREE_FILE { } """ echo -e "$outfile_text" >${case_name}.ped - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - create_pedigree_file: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS """ stub: def case_name = samples[0].case_id """ touch ${case_name}.ped - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - create_pedigree_file: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS """ } diff --git a/modules/local/custom/addmostsevereconsequence/environment.yml b/modules/local/custom/addmostsevereconsequence/environment.yml new file mode 100644 index 000000000..315b7489e --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::htslib=1.21 + - conda-forge::python=3.13.2 diff --git a/modules/local/custom/addmostsevereconsequence/main.nf b/modules/local/custom/addmostsevereconsequence/main.nf new file mode 100644 index 000000000..c165cea0a --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/main.nf @@ -0,0 +1,45 @@ +process CUSTOM_ADDMOSTSEVERECONSEQUENCE { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/cb/cbeb20c898a76bec809629320ece9e1f84a3e355e96568bfbe14b9f411bdf3e7/data': + 'community.wave.seqera.io/library/htslib_python:9c6265e98ef06930' }" + + input: + tuple val(meta), path(vcf) + tuple val(meta2), path(variant_consequences) + + + output: + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val("${task.process}"), val('addmostsevereconsequence'), val("1.2.0"), topic: versions, emit: versions_addmostsevereconsequence + tuple val("${task.process}"), val('bgzip'), eval("bgzip --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_bgzip + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + add_most_severe_consequence.py \\ + $args \\ + --file_in $vcf \\ + --file_out ${prefix}.vcf \\ + --variant_csq $variant_consequences + + bgzip \\ + $args2 \\ + --threads ${task.cpus} \\ + ${prefix}.vcf + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo | gzip > ${prefix}.vcf.gz + """ +} diff --git a/modules/local/custom/addmostsevereconsequence/meta.yml b/modules/local/custom/addmostsevereconsequence/meta.yml new file mode 100644 index 000000000..496063ee8 --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/meta.yml @@ -0,0 +1,95 @@ +name: "custom_addmostsevereconsequence" +description: Annotate a VEP annotated VCF with the most severe consequence field +keywords: + - annotation + - vep + - consequence + - vcf +tools: + - "custom": + description: "Custom module to annotate a VEP annotated VCF with the most severe + consequence field" + tool_dev_url: "https://github.com/nf-core/modules/blob/master/modules/nf-core/custom/addmostsevereconsequence/main.nf" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - vcf: + type: file + description: VEP annotated VCF file + pattern: "*.{vcf,vcf.gz}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - variant_consequences: + type: file + description: File with VEP variant consequences, one per line. + pattern: "*" + ontologies: [] +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.vcf.gz": + type: file + description: Annotated VCF file + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + versions_addmostsevereconsequence: + - - ${task.process}: + type: string + description: The name of the process + - addmostsevereconsequence: + type: string + description: The name of the tool + - 1.2.0: + type: string + description: The expression to obtain the version of the tool + versions_bgzip: + - - ${task.process}: + type: string + description: The name of the process + - bgzip: + type: string + description: The name of the tool + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - addmostsevereconsequence: + type: string + description: The name of the tool + - 1.2.0: + type: string + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - bgzip: + type: string + description: The name of the tool + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@ramprasadn" + - "@fellen31" +maintainers: + - "@ramprasadn" + - "@fellen31" diff --git a/modules/local/custom/addmostsevereconsequence/tests/main.nf.test b/modules/local/custom/addmostsevereconsequence/tests/main.nf.test new file mode 100644 index 000000000..4664c198b --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/tests/main.nf.test @@ -0,0 +1,146 @@ +// nf-core modules test custom/addmostsevereconsequence +nextflow_process { + + name "Test Process CUSTOM_ADDMOSTSEVERECONSEQUENCE" + script "../main.nf" + process "CUSTOM_ADDMOSTSEVERECONSEQUENCE" + + tag "modules" + tag "modules_nfcore" + tag "custom" + tag "custom/addmostsevereconsequence" + config "./nextflow.config" + + test("vcf") { + + when { + process { + """ + input[0] = [ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ] + input[1] = Channel.of([ + "transcript_ablation", + "splice_acceptor_variant", + "splice_donor_variant", + "stop_gained", + "frameshift_variant", + "stop_lost", + "start_lost", + "transcript_amplification", + "feature_elongation", + "feature_truncation", + "inframe_insertion", + "inframe_deletion", + "missense_variant", + "protein_altering_variant", + "splice_donor_5th_base_variant", + "splice_region_variant", + "splice_donor_region_variant", + "splice_polypyrimidine_tract_variant", + "incomplete_terminal_codon_variant", + "start_retained_variant", + "stop_retained_variant", + "synonymous_variant", + "coding_sequence_variant", + "mature_miRNA_variant", + "5_prime_UTR_variant", + "3_prime_UTR_variant", + "non_coding_transcript_exon_variant", + "intron_variant", + "NMD_transcript_variant", + "non_coding_transcript_variant", + "coding_transcript_variant", + "upstream_gene_variant", + "downstream_gene_variant", + "TFBS_ablation", + "TFBS_amplification", + "TF_binding_site_variant", + "regulatory_region_ablation", + "regulatory_region_amplification", + "regulatory_region_variant", + "intergenic_variant", + "sequence_variant" + ]).collectFile(name: 'variant_consequences.txt', newLine:true).map { file -> [ [ id: file.simpleName ], file ] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcf - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ] + input[1] = Channel.of([ + "transcript_ablation", + "splice_acceptor_variant", + "splice_donor_variant", + "stop_gained", + "frameshift_variant", + "stop_lost", + "start_lost", + "transcript_amplification", + "feature_elongation", + "feature_truncation", + "inframe_insertion", + "inframe_deletion", + "missense_variant", + "protein_altering_variant", + "splice_donor_5th_base_variant", + "splice_region_variant", + "splice_donor_region_variant", + "splice_polypyrimidine_tract_variant", + "incomplete_terminal_codon_variant", + "start_retained_variant", + "stop_retained_variant", + "synonymous_variant", + "coding_sequence_variant", + "mature_miRNA_variant", + "5_prime_UTR_variant", + "3_prime_UTR_variant", + "non_coding_transcript_exon_variant", + "intron_variant", + "NMD_transcript_variant", + "non_coding_transcript_variant", + "coding_transcript_variant", + "upstream_gene_variant", + "downstream_gene_variant", + "TFBS_ablation", + "TFBS_amplification", + "TF_binding_site_variant", + "regulatory_region_ablation", + "regulatory_region_amplification", + "regulatory_region_variant", + "intergenic_variant", + "sequence_variant" + ]).collectFile(name: 'variant_consequences.txt', newLine:true).map { file -> [ [ id: file.simpleName ], file ] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/local/custom/addmostsevereconsequence/tests/main.nf.test.snap b/modules/local/custom/addmostsevereconsequence/tests/main.nf.test.snap new file mode 100644 index 000000000..9d5640c13 --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/tests/main.nf.test.snap @@ -0,0 +1,112 @@ +{ + "vcf": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,d82db60282f5c594c105c010b3a76639" + ] + ], + "1": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "addmostsevereconsequence", + "1.2.0" + ] + ], + "2": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "bgzip", + "1.21" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,d82db60282f5c594c105c010b3a76639" + ] + ], + "versions_addmostsevereconsequence": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "addmostsevereconsequence", + "1.2.0" + ] + ], + "versions_bgzip": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "bgzip", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-20T13:39:46.791679914" + }, + "vcf - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "addmostsevereconsequence", + "1.2.0" + ] + ], + "2": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "bgzip", + "1.21" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_addmostsevereconsequence": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "addmostsevereconsequence", + "1.2.0" + ] + ], + "versions_bgzip": [ + [ + "CUSTOM_ADDMOSTSEVERECONSEQUENCE", + "bgzip", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-20T13:39:51.821372334" + } +} \ No newline at end of file diff --git a/modules/local/custom/addmostsevereconsequence/tests/nextflow.config b/modules/local/custom/addmostsevereconsequence/tests/nextflow.config new file mode 100644 index 000000000..651f0b86a --- /dev/null +++ b/modules/local/custom/addmostsevereconsequence/tests/nextflow.config @@ -0,0 +1 @@ +nextflow.enable.moduleBinaries = true diff --git a/modules/local/custom/addmostseverepli/environment.yml b/modules/local/custom/addmostseverepli/environment.yml new file mode 100644 index 000000000..315b7489e --- /dev/null +++ b/modules/local/custom/addmostseverepli/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::htslib=1.21 + - conda-forge::python=3.13.2 diff --git a/modules/local/custom/addmostseverepli/main.nf b/modules/local/custom/addmostseverepli/main.nf new file mode 100644 index 000000000..078dd2cb7 --- /dev/null +++ b/modules/local/custom/addmostseverepli/main.nf @@ -0,0 +1,42 @@ +process CUSTOM_ADDMOSTSEVEREPLI { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/cb/cbeb20c898a76bec809629320ece9e1f84a3e355e96568bfbe14b9f411bdf3e7/data': + 'community.wave.seqera.io/library/htslib_python:9c6265e98ef06930' }" + + input: + tuple val(meta), path(vcf) + + output: + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val("${task.process}"), val('addmostseverepli'), val("1.2.0"), topic: versions, emit: versions_addmostseverepli + tuple val("${task.process}"), val('bgzip'), eval("bgzip --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_bgzip + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + add_most_severe_pli.py \\ + $args \\ + --file_in $vcf \\ + --file_out ${prefix}.vcf + + bgzip \\ + $args2 \\ + --threads ${task.cpus} \\ + ${prefix}.vcf + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo | gzip > ${prefix}.vcf.gz + """ +} diff --git a/modules/local/custom/addmostseverepli/meta.yml b/modules/local/custom/addmostseverepli/meta.yml new file mode 100644 index 000000000..1c02be4f5 --- /dev/null +++ b/modules/local/custom/addmostseverepli/meta.yml @@ -0,0 +1,85 @@ +name: "custom_addmostseverepli" +description: Annotate a VEP annotated VCF with the most severe pLi field +keywords: + - annotation + - vep + - pli + - vcf +tools: + - "custom": + description: "Custom module to annotate a VEP annotated VCF with the most severe + pLi field" + tool_dev_url: "https://github.com/nf-core/modules/blob/master/modules/nf-core/custom/addmostseverepli/main.nf" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - vcf: + type: file + description: VEP annotated VCF file + pattern: "*.{vcf,vcf.gz}" + ontologies: [] +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.vcf.gz": + type: file + description: Annotated VCF file + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + versions_addmostseverepli: + - - ${task.process}: + type: string + description: The name of the process + - addmostseverepli: + type: string + description: The name of the tool + - 1.2.0: + type: string + description: The expression to obtain the version of the tool + versions_bgzip: + - - ${task.process}: + type: string + description: The name of the process + - bgzip: + type: string + description: The name of the tool + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - addmostseverepli: + type: string + description: The name of the tool + - 1.2.0: + type: string + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - bgzip: + type: string + description: The name of the tool + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@ramprasadn" + - "@fellen31" +maintainers: + - "@ramprasadn" + - "@fellen31" diff --git a/modules/nf-core/haplogrep3/classify/tests/main.nf.test b/modules/local/custom/addmostseverepli/tests/main.nf.test similarity index 51% rename from modules/nf-core/haplogrep3/classify/tests/main.nf.test rename to modules/local/custom/addmostseverepli/tests/main.nf.test index 654124c52..5263f5c5c 100644 --- a/modules/nf-core/haplogrep3/classify/tests/main.nf.test +++ b/modules/local/custom/addmostseverepli/tests/main.nf.test @@ -1,26 +1,25 @@ - +// nf-core modules test custom/addmostseverepli nextflow_process { - name "Test Process HAPLOGREP3_CLASSIFY" + name "Test Process CUSTOM_ADDMOSTSEVEREPLI" script "../main.nf" - process "HAPLOGREP3_CLASSIFY" + process "CUSTOM_ADDMOSTSEVEREPLI" tag "modules" tag "modules_nfcore" - tag "haplogrep3" - tag "haplogrep3/classify" - - test("test-haplogrep3-classify") { + tag "custom" + tag "custom/addmostseverepli" + config "./nextflow.config" - config './nextflow.config' + test("vcf") { when { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_chrM.vcf.gz', checkIfExists: true) - ] + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ] """ } } @@ -31,19 +30,20 @@ nextflow_process { { assert snapshot(process.out).match() } ) } + } - test("test-haplogrep3-classify-stub") { + test("vcf - stub") { - options '-stub' + options "-stub" when { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_chrM.vcf.gz', checkIfExists: true) - ] + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ] """ } } @@ -54,6 +54,7 @@ nextflow_process { { assert snapshot(process.out).match() } ) } + } } diff --git a/modules/local/custom/addmostseverepli/tests/main.nf.test.snap b/modules/local/custom/addmostseverepli/tests/main.nf.test.snap new file mode 100644 index 000000000..6b3da9e0e --- /dev/null +++ b/modules/local/custom/addmostseverepli/tests/main.nf.test.snap @@ -0,0 +1,112 @@ +{ + "vcf": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,d29918951676cc028d980aaab161db21" + ] + ], + "1": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "addmostseverepli", + "1.2.0" + ] + ], + "2": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "bgzip", + "1.21" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,d29918951676cc028d980aaab161db21" + ] + ], + "versions_addmostseverepli": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "addmostseverepli", + "1.2.0" + ] + ], + "versions_bgzip": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "bgzip", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-20T13:39:23.157595356" + }, + "vcf - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "addmostseverepli", + "1.2.0" + ] + ], + "2": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "bgzip", + "1.21" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_addmostseverepli": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "addmostseverepli", + "1.2.0" + ] + ], + "versions_bgzip": [ + [ + "CUSTOM_ADDMOSTSEVEREPLI", + "bgzip", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-20T13:39:28.679239093" + } +} \ No newline at end of file diff --git a/modules/local/custom/addmostseverepli/tests/nextflow.config b/modules/local/custom/addmostseverepli/tests/nextflow.config new file mode 100644 index 000000000..651f0b86a --- /dev/null +++ b/modules/local/custom/addmostseverepli/tests/nextflow.config @@ -0,0 +1 @@ +nextflow.enable.moduleBinaries = true diff --git a/modules/nf-core/eklipse/environment.yml b/modules/local/filtervep/environment.yml similarity index 65% rename from modules/nf-core/eklipse/environment.yml rename to modules/local/filtervep/environment.yml index b638fba1d..0ffb35d7c 100644 --- a/modules/nf-core/eklipse/environment.yml +++ b/modules/local/filtervep/environment.yml @@ -2,4 +2,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::eklipse=1.8 + - bioconda::cyvcf2=0.32.1 diff --git a/modules/local/filtervep/main.nf b/modules/local/filtervep/main.nf new file mode 100644 index 000000000..6e05dace3 --- /dev/null +++ b/modules/local/filtervep/main.nf @@ -0,0 +1,40 @@ +process FILTERVEP { + tag "${meta.id}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/48/481e0a88c723eb6abe5a6c36e50bc2119b460f3c6f71aff2111a22e8b704c5d9/data' : + 'community.wave.seqera.io/library/cyvcf2:0.32.1--569b36b775b7f1e5' }" + + input: + tuple val(meta), path(input) + path feature_file + + output: + tuple val(meta), path("*.${extension}"), emit: output + tuple val("${task.process}"), val('filtervep'), val('1.0.0'), topic: versions, emit: versions_filtervep + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--format tab") ? "txt" : "vcf" + """ + filter_vep \\ + ${args} \\ + --input_file ${input} \\ + --output_file ${prefix}.${extension} \\ + --only_matched + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--format tab") ? "txt" : "vcf" + """ + touch ${prefix}.${extension} + """ +} diff --git a/modules/local/gens/main.nf b/modules/local/gens/main.nf deleted file mode 100644 index 75f20c2e8..000000000 --- a/modules/local/gens/main.nf +++ /dev/null @@ -1,53 +0,0 @@ -process GENS { - tag "$meta.id" - label 'process_medium' - - container 'docker.io/clinicalgenomics/gens_preproc:1.0.11' - - input: - tuple val(meta), path(read_counts) - tuple val(meta2), path(gvcf) - path gnomad_positions - - output: - tuple val(meta), path('*.cov.bed.gz') , emit: cov - tuple val(meta), path('*.cov.bed.gz.tbi'), emit: cov_index - tuple val(meta), path('*.baf.bed.gz') , emit: baf - tuple val(meta), path('*.baf.bed.gz.tbi'), emit: baf_index - path "versions.yml" , emit: versions - - script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "The gens pre-processing module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.0.11" // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. - """ - generate_gens_data.pl \\ - $read_counts \\ - $gvcf \\ - $prefix \\ - $gnomad_positions - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - generate_gens_data.pl: $VERSION - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.0.11" - """ - touch ${prefix}.baf.bed.gz - touch ${prefix}.baf.bed.gz.tbi - touch ${prefix}.cov.bed.gz - touch ${prefix}.cov.bed.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - generate_gens_data.pl: $VERSION - END_VERSIONS - """ -} diff --git a/modules/local/gens/meta.yml b/modules/local/gens/meta.yml deleted file mode 100644 index 44d0e7b75..000000000 --- a/modules/local/gens/meta.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: gens -description: -keywords: - - bed - - vcf -tools: - - gens: - description: | - Gens is a web-based interactive tool to visualize genomic copy number profiles from WGS data (although it could theoretically be used for any type of data). - It plots the normalized read depth and alternative allele frequency. - homepage: https://github.com/Clinical-Genomics-Lund/gens - documentation: https://github.com/Clinical-Genomics-Lund/gens -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test'] - - read_counts: - type: file - description: Input standardized read counts file - pattern: "*.tsv" - - vcf: - type: file - description: Input vcf file - pattern: "*.vcf" - - gnomad_positions: - type: file - description: SNV filter file - pattern: "*.txt" -output: - - cov: - type: file - description: Gens preprocessed coverage file - pattern: "*.bed.gz" - - baf: - type: file - description: Gens preprocessed base allele frequency file - pattern: "*.bed.gz" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@raysloks" diff --git a/modules/local/get_chrom_sizes/environment.yml b/modules/local/get_chrom_sizes/environment.yml new file mode 100644 index 000000000..0c4cd9422 --- /dev/null +++ b/modules/local/get_chrom_sizes/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=9.5 diff --git a/modules/local/get_chrom_sizes/main.nf b/modules/local/get_chrom_sizes/main.nf index 1234c9eff..3cad914b8 100644 --- a/modules/local/get_chrom_sizes/main.nf +++ b/modules/local/get_chrom_sizes/main.nf @@ -2,41 +2,29 @@ process GET_CHROM_SIZES { tag "$fai" label 'process_single' - conda "conda-forge::coreutils=8.31" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h36e9172_9' : - 'biocontainers/gnu-wget:1.18--h36e9172_9' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c2/c262fc09eca59edb5a724080eeceb00fb06396f510aefb229c2d2c6897e63975/data' : + 'community.wave.seqera.io/library/coreutils:9.5--ae99c88a9b28c264' }" input: tuple val(meta), path(fai) output: path '*.sizes' , emit: sizes - path "versions.yml", emit: versions + tuple val("${task.process}"), val('coreutils'), val("9.5"), topic: versions, emit: versions_coreutils when: task.ext.when == null || task.ext.when script: - def VERSION = "8.31" """ cut -f 1,2 $fai > ${fai}.sizes - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - coreutils: $VERSION - END_VERSIONS """ stub: - def VERSION = "8.31" """ touch ${fai}.sizes - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - coreutils: $VERSION - END_VERSIONS """ } diff --git a/modules/local/mitosalt/environment.yml b/modules/local/mitosalt/environment.yml new file mode 100644 index 000000000..3bb5bb046 --- /dev/null +++ b/modules/local/mitosalt/environment.yml @@ -0,0 +1,16 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bbmap=39.37 + - bioconda::bedtools=2.31.1 + - bioconda::bioconductor-biostrings=2.74.0 + - bioconda::bioconductor-pwalign=1.2.0 + - bioconda::hisat2=2.2.1 + - bioconda::last=1648 + - bioconda::sambamba=1.0.1 + - bioconda::samtools=1.22.1 + - bioconda::ucsc-bedgraphtobigwig=482 + - bioconda::ucsc-fasize=482 + - bioconda::ucsc-fasomerecords=482 + - conda-forge::r-rcolorbrewer=1.1_3 diff --git a/modules/local/mitosalt/main.nf b/modules/local/mitosalt/main.nf new file mode 100644 index 000000000..3eee65aa3 --- /dev/null +++ b/modules/local/mitosalt/main.nf @@ -0,0 +1,43 @@ +process MITOSALT { + tag "$meta.id" + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/13/130779a0dd5a8d86441f262a16a5fb1dfe562125edf93646b53c893d982b5519/data': + 'community.wave.seqera.io/library/bbmap_bedtools_bioconductor-biostrings_bioconductor-pwalign_pruned:856c05081cbd8239' }" + + input: + tuple val(meta), path(reads) + path msconfig + path chrsizes + tuple val(meta3), path(genomefai) + tuple val(meta2), path(hisat2index) + tuple val(meta5), path(mtfai) + tuple val(meta6), path(mtfasta) + tuple val(meta4), path(lastindex) + + output: + tuple val(meta), path("*breakpoint") , emit: breakpoint + tuple val(meta), path("*cluster") , emit: cluster + tuple val("${task.process}"), val('mitosalt'), val("1.1.1"), topic: versions, emit: versions_mitosalt + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $msconfig | sed "s/threads = 1/threads = ${task.cpus}/" > new-${msconfig} + mkdir -p log indel bam tab bw plot + MitoSAlt1.1.1.pl new-${msconfig} $reads $prefix + mv indel/*.breakpoint ${prefix}.breakpoint + mv indel/*.cluster ${prefix}.cluster + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $msconfig | sed "s/threads = 1/threads = ${task.cpus}/" > new-${msconfig} + touch ${prefix}.breakpoint + echo 'cluster' > ${prefix}.cluster + """ + +} diff --git a/modules/local/mt_deletion_script/environment.yml b/modules/local/mt_deletion_script/environment.yml new file mode 100644 index 000000000..53698527f --- /dev/null +++ b/modules/local/mt_deletion_script/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::samtools=1.23 diff --git a/modules/local/mt_deletion_script/main.nf b/modules/local/mt_deletion_script/main.nf index 9ccb56995..c117352e1 100644 --- a/modules/local/mt_deletion_script/main.nf +++ b/modules/local/mt_deletion_script/main.nf @@ -2,9 +2,10 @@ process MT_DELETION { tag "$meta.id" label 'process_single' + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.19.2--h50ea8bc_0' : - 'biocontainers/samtools:1.19.2--h50ea8bc_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b9/b946e2f0e77ec69853787dfc8b312bd7e9d5c65a11a613ce918469a9566992e3/data' : + 'community.wave.seqera.io/library/samtools:1.23--12d9384dd0649f36' }" input: tuple val(meta), path(input), path(input_index) @@ -12,7 +13,8 @@ process MT_DELETION { output: tuple val(meta), path('*.txt'), emit: mt_del_result - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools + tuple val("${task.process}"), val('mitodel'), val("1.0"), topic: versions, emit: versions_mitodel when: task.ext.when == null || task.ext.when @@ -21,28 +23,16 @@ process MT_DELETION { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--reference ${fasta}" : "" - """ samtools stats --threads ${task.cpus} $args ${reference} ${input} | \\ grep -E ^IS | \\ awk 'BEGIN {sum=0} (\$2>=1200 && \$2<=15000) {sum=sum+\$3} (\$2<1200 || \$2>15000) {sum_norm=sum_norm+\$3} END \\ {print "intermediate discordant ", sum, "normal ", sum_norm, "ratio ppk", sum*1000/(sum_norm+sum)}' 1> ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - mitodel: v1.0 - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/local/parse_contamination/environment.yml b/modules/local/parse_contamination/environment.yml new file mode 100644 index 000000000..b5260d32d --- /dev/null +++ b/modules/local/parse_contamination/environment.yml @@ -0,0 +1,7 @@ +name: parse_contamination +channels: + - conda-forge + - bioconda + - defaults +dependencies: + - python=3.11 diff --git a/modules/local/parse_contamination/main.nf b/modules/local/parse_contamination/main.nf new file mode 100644 index 000000000..894556142 --- /dev/null +++ b/modules/local/parse_contamination/main.nf @@ -0,0 +1,34 @@ +process PARSE_CONTAMINATION { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.11' : + 'biocontainers/python:3.11' }" + + input: + tuple val(meta), path(contamination_table) + + output: + tuple val(meta), path("*_contamination_mqc.tsv"), emit: mqc_table + tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + parse_contamination.py \\ + --input ${contamination_table} \\ + --sample_id ${meta.id} \\ + --prefix ${prefix} + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}_contamination_mqc.tsv + """ +} diff --git a/modules/local/parse_contamination/meta.yml b/modules/local/parse_contamination/meta.yml new file mode 100644 index 000000000..50803de8f --- /dev/null +++ b/modules/local/parse_contamination/meta.yml @@ -0,0 +1,62 @@ +name: "parse_contamination" +description: Parse GATK CalculateContamination output into a MultiQC custom-content table +keywords: + - contamination + - multiqc + - parsing +tools: + - "python": + description: "Python programming language" + homepage: "https://www.python.org/" + documentation: "https://docs.python.org/" + licence: + - "PSF" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - contamination_table: + type: file + description: GATK CalculateContamination output table + pattern: "*.contamination.table" + ontologies: [] +output: + mqc_table: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*_contamination_mqc.tsv": + type: file + description: MultiQC custom-content table + pattern: "*_contamination_mqc.tsv" + ontologies: [] + versions_python: + - - ${task.process}: + type: string + description: The name of the process + - python: + type: string + description: The name of the tool + - python3 --version | sed 's/Python //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - python: + type: string + description: The name of the tool + - python3 --version | sed 's/Python //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@dorotejavujinovic" +maintainers: + - "@dorotejavujinovic" diff --git a/modules/local/prep_mitosalt/main.nf b/modules/local/prep_mitosalt/main.nf new file mode 100644 index 000000000..fa749e0ca --- /dev/null +++ b/modules/local/prep_mitosalt/main.nf @@ -0,0 +1,85 @@ +process PREP_MITOSALT { + tag "$meta.id" + label "process_low" + + input: + path chrsizes + tuple val(meta), path(genomefai) + tuple val(meta2), path(hisat2index) + tuple val(breakspan), val(breakthreshold), val(cluster_threshold), + val(deletion_threshold_max), val(deletion_threshold_min), val(evalue_threshold), + val(exclude), val(paired_distance), val(score_threshold), + val(sizelimit), val(split_distance_threshold), val(split_length) + tuple val(meta3), path(mtfai) + tuple val(meta4), path(mtfasta) + tuple val(meta5), path(lastindex) + val flank + val heteroplasmy_limit + val mitochondria_name + + output: + path "mitosalt_config.txt", emit: msconfig + + script: + """ + hisat2path=`find -L ./ -name "*.1.ht2" | sed 's/.1.ht2//'` + lastpath=`find -L ./ -name "*.prj" | sed 's/.prj//'` + + echo "hisat2 = hisat2" > mitosalt_config.txt + echo "lastal = lastal" >> mitosalt_config.txt + echo "lastsp = last-split" >> mitosalt_config.txt + echo "mfcv = maf-convert" >> mitosalt_config.txt + echo "reformat = reformat.sh" >> mitosalt_config.txt + echo "samtools = samtools" >> mitosalt_config.txt + echo "sambamba = sambamba" >> mitosalt_config.txt + echo "b2fq = bamToFastq" >> mitosalt_config.txt + echo "gcov = genomeCoverageBed" >> mitosalt_config.txt + echo "intersectBed = intersectBed" >> mitosalt_config.txt + echo "sortBed = sortBed" >> mitosalt_config.txt + echo "clusterBed = clusterBed" >> mitosalt_config.txt + echo "randomBed = randomBed" >> mitosalt_config.txt + echo "groupBy = groupBy" >> mitosalt_config.txt + echo "bg2bw = bedGraphToBigWig" >> mitosalt_config.txt + echo "hsindex = \$hisat2path" >> mitosalt_config.txt + echo "faindex = ${genomefai}" >> mitosalt_config.txt + echo "lastindex = \$lastpath" >> mitosalt_config.txt + echo "mtfaindex = ${mtfai}" >> mitosalt_config.txt + echo "gsize = ${chrsizes}" >> mitosalt_config.txt + echo "MT_fasta = ${mtfasta}" >> mitosalt_config.txt + echo "threads = 1" >> mitosalt_config.txt + echo "refchr = ${mitochondria_name}" >> mitosalt_config.txt + echo "msize = 16569" >> mitosalt_config.txt + echo "exclude = ${exclude}" >> mitosalt_config.txt + echo "orihs = 16081" >> mitosalt_config.txt + echo "orihe = 407" >> mitosalt_config.txt + echo "orils = 5730" >> mitosalt_config.txt + echo "orile = 5763" >> mitosalt_config.txt + echo "score_threshold = ${score_threshold}" >> mitosalt_config.txt + echo "evalue_threshold = ${evalue_threshold}" >> mitosalt_config.txt + echo "split_length = ${split_length}" >> mitosalt_config.txt + echo "paired_distance = ${paired_distance}" >> mitosalt_config.txt + echo "deletion_threshold_min = ${deletion_threshold_min}" >> mitosalt_config.txt + echo "deletion_threshold_max = ${deletion_threshold_max}" >> mitosalt_config.txt + echo "breakthreshold = ${breakthreshold}" >> mitosalt_config.txt + echo "cluster_threshold = ${cluster_threshold}" >> mitosalt_config.txt + echo "breakspan = ${breakspan}" >> mitosalt_config.txt + echo "sizelimit = ${sizelimit}" >> mitosalt_config.txt + echo "hplimit = ${heteroplasmy_limit}" >> mitosalt_config.txt + echo "flank = ${flank}" >> mitosalt_config.txt + echo "split_distance_threshold = ${split_distance_threshold}" >> mitosalt_config.txt + echo "dna = yes" >> mitosalt_config.txt + echo "enriched = no" >> mitosalt_config.txt + echo "nu_mt = yes" >> mitosalt_config.txt + echo "rmtmp = no" >> mitosalt_config.txt + echo "o_mt = yes" >> mitosalt_config.txt + echo "i_del = yes" >> mitosalt_config.txt + echo "cn_mt = yes" >> mitosalt_config.txt + """ + + stub: + """ + echo "hisat2 = hisat2" > mitosalt_config.txt + echo "lastal = lastal" >> mitosalt_config.txt + """ + +} diff --git a/modules/local/rename_align_files/environment.yml b/modules/local/rename_align_files/environment.yml new file mode 100644 index 000000000..0c4cd9422 --- /dev/null +++ b/modules/local/rename_align_files/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=9.5 diff --git a/modules/local/rename_align_files/main.nf b/modules/local/rename_align_files/main.nf index b450902f0..4f5111c13 100644 --- a/modules/local/rename_align_files/main.nf +++ b/modules/local/rename_align_files/main.nf @@ -2,10 +2,10 @@ process RENAME_ALIGN_FILES { tag "$meta.id" label 'process_single' - conda "conda-forge::coreutils=8.31" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h36e9172_9' : - 'biocontainers/gnu-wget:1.18--h36e9172_9' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c2/c262fc09eca59edb5a724080eeceb00fb06396f510aefb229c2d2c6897e63975/data' : + 'community.wave.seqera.io/library/coreutils:9.5--ae99c88a9b28c264' }" input: tuple val(meta), path(input) @@ -13,30 +13,19 @@ process RENAME_ALIGN_FILES { output: tuple val(meta), path("*.{bam,bai}"), emit: output - path "versions.yml", emit: versions + tuple val("${task.process}"), val('coreutils'), val("9.5"), topic: versions, emit: versions_coreutils when: task.ext.when == null || task.ext.when script: - def VERSION = "8.31" """ ln -s $input ${meta.sample}.${extension} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - coreutils: $VERSION - END_VERSIONS """ stub: - def VERSION = "8.31" """ ln -s $input ${meta.sample}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - coreutils: $VERSION - END_VERSIONS """ } diff --git a/modules/local/replace_spaces_in_vcfinfo/environment.yml b/modules/local/replace_spaces_in_vcfinfo/environment.yml new file mode 100644 index 000000000..c38e0465e --- /dev/null +++ b/modules/local/replace_spaces_in_vcfinfo/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.23 + - conda-forge::python=3.14.3 diff --git a/modules/local/replace_spaces_in_vcfinfo/main.nf b/modules/local/replace_spaces_in_vcfinfo/main.nf index afd660292..37dd61141 100644 --- a/modules/local/replace_spaces_in_vcfinfo/main.nf +++ b/modules/local/replace_spaces_in_vcfinfo/main.nf @@ -2,58 +2,29 @@ process REPLACE_SPACES_IN_VCFINFO { tag "$meta.id" label 'process_single' - conda "conda-forge::python=3.8.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.8.3' : - 'biocontainers/python:3.8.3' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/2f/2fdb3ffa4bac62e98ec062e991217df2ab96e67bbd45a502bd25ff2effecb96e/data': + 'community.wave.seqera.io/library/htslib_python:d1e4474cbf76f4e9' }" input: tuple val(meta), path(input) output: tuple val(meta), path("*_reformatted.vcf"), emit: vcf - path "versions.yml", emit: versions + tuple val("${task.process}"), val('replace_spaces_in_vcfinfo'), val("1.0"), topic: versions, emit: versions_replace_spaces_in_vcfinfo + tuple val("${task.process}"), val('python'), eval("python -V | sed 's/Python //'"), topic: versions, emit: versions_python when: task.ext.when == null || task.ext.when script: """ - python3 < versions.yml - "${task.process}": - replace_spaces_in_vcfinfo: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS + replace_spaces_in_vcfinfo.py --input ${input} """ stub: """ - python3 < versions.yml - "${task.process}": - replace_spaces_in_vcfinfo: v1.0 - python: \$(python --version | sed 's/Python //g') - END_VERSIONS + replace_spaces_in_vcfinfo.py --input ${input} """ } diff --git a/modules/local/retroseq/call/main.nf b/modules/local/retroseq/call/main.nf index 5b13c6304..394744d4b 100644 --- a/modules/local/retroseq/call/main.nf +++ b/modules/local/retroseq/call/main.nf @@ -2,10 +2,7 @@ process RETROSEQ_CALL { tag "$meta.id" label 'process_low' - conda "bioconda::perl-retroseq=1.5=pl5321hdfd78af_1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' : 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' }" - + container 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' input: tuple val(meta), path(tab), path(bam), path(bai) @@ -14,7 +11,7 @@ process RETROSEQ_CALL { output: tuple val(meta), path("*.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('retroseq'), val("1.5"), topic: versions, emit: versions_retroseq when: task.ext.when == null || task.ext.when @@ -22,8 +19,6 @@ process RETROSEQ_CALL { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.5" - """ retroseq.pl \\ -call \\ @@ -32,23 +27,11 @@ process RETROSEQ_CALL { -input $tab \\ -ref $fasta \\ -output ${prefix}.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - retroseq_call: $VERSION - END_VERSIONS """ stub: - def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.5" """ touch ${prefix}.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - retroseq_call: $VERSION - END_VERSIONS """ } diff --git a/modules/local/retroseq/discover/main.nf b/modules/local/retroseq/discover/main.nf index 2ea513442..84ca21d0f 100644 --- a/modules/local/retroseq/discover/main.nf +++ b/modules/local/retroseq/discover/main.nf @@ -2,10 +2,7 @@ process RETROSEQ_DISCOVER { tag "$meta.id" label 'process_low' - conda "bioconda::perl-retroseq=1.5=pl5321hdfd78af_1" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' : 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' }" - + container 'docker.io/clinicalgenomics/retroseq:1.5_9d4f3b5-1' input: tuple val(meta), path(bam), path(bai) @@ -14,7 +11,7 @@ process RETROSEQ_DISCOVER { output: tuple val(meta), path("*.tab"), emit: tab - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('retroseq'), val("1.5"), topic: versions, emit: versions_retroseq when: task.ext.when == null || task.ext.when @@ -22,8 +19,6 @@ process RETROSEQ_DISCOVER { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.5" // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. - """ paste <(printf "%s\\n" $me_types | tr -d '[],') <(printf "%s\\n" $me_references) > me_reference_manifest.tsv retroseq.pl \\ @@ -33,23 +28,12 @@ process RETROSEQ_DISCOVER { -refTEs me_reference_manifest.tsv\\ -output ${prefix}.tab - cat <<-END_VERSIONS > versions.yml - "${task.process}": - retroseq_discover: $VERSION - END_VERSIONS """ stub: - def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.5" """ paste <(printf "%s\\n" $me_types | tr -d '[],') <(printf "%s\\n" $me_references) > me_reference_manifest.tsv touch ${prefix}.tab - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - retroseq_discover: $VERSION - END_VERSIONS """ } diff --git a/modules/nf-core/hmtnote/annotate/environment.yml b/modules/local/saltshaker_to_html/environment.yml similarity index 63% rename from modules/nf-core/hmtnote/annotate/environment.yml rename to modules/local/saltshaker_to_html/environment.yml index 1d9d20e3f..046b3426c 100644 --- a/modules/nf-core/hmtnote/annotate/environment.yml +++ b/modules/local/saltshaker_to_html/environment.yml @@ -2,4 +2,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::hmtnote=0.7.2 + - conda-forge::typer=0.25.1 diff --git a/modules/local/saltshaker_to_html/main.nf b/modules/local/saltshaker_to_html/main.nf new file mode 100644 index 000000000..3d56fdb6b --- /dev/null +++ b/modules/local/saltshaker_to_html/main.nf @@ -0,0 +1,34 @@ +process SALTSHAKER_TO_HTML { + tag "$meta.id" + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a2/a23c958d5a0439419f82069df6217c542f6ab13816f9808ed73307dff1efe227/data': + 'community.wave.seqera.io/library/typer:0.25.1--25ea8a9ce34456a3' }" + + input: + tuple val(meta), path(saltshaker_classify_reports), val(sample_ids) + + output: + tuple val(meta), path("*.html"), emit: classify_html + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + """ + saltshaker_to_html.py \ + $args \ + --input ${saltshaker_classify_reports.join(' --input ')} \ + --sample ${sample_ids.join(' --sample ')} \ + --output ${prefix}.html + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo $args + touch ${prefix}.html + """ +} diff --git a/modules/local/sanity_check_vcfanno_databases/environment.yml b/modules/local/sanity_check_vcfanno_databases/environment.yml new file mode 100644 index 000000000..c38e0465e --- /dev/null +++ b/modules/local/sanity_check_vcfanno_databases/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.23 + - conda-forge::python=3.14.3 diff --git a/modules/local/sanity_check_vcfanno_databases/main.nf b/modules/local/sanity_check_vcfanno_databases/main.nf new file mode 100644 index 000000000..9c53bce0a --- /dev/null +++ b/modules/local/sanity_check_vcfanno_databases/main.nf @@ -0,0 +1,34 @@ +process SANITY_CHECK_VCFANNO_DATABASES { + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/2f/2fdb3ffa4bac62e98ec062e991217df2ab96e67bbd45a502bd25ff2effecb96e/data': + 'community.wave.seqera.io/library/htslib_python:d1e4474cbf76f4e9' }" + + input: + path(toml) + path(databases) + + output: + path("*_filtered.toml") , emit: toml + tuple val("${task.process}"), val('sanity_check_vcfanno_databases'), val("1.0"), topic: versions , emit: versions_sanity_check_vcfanno_databases + tuple val("${task.process}"), val('python'), eval("python -V | sed 's/Python //'"), topic: versions , emit: versions_python + + when: + task.ext.when == null || task.ext.when + + script: + """ + sanity_check_vcfanno_databases.py \\ + --toml ${toml} \\ + --databases ${databases} + + """ + + stub: + """ + touch ${toml.baseName}_filtered.toml + + """ +} diff --git a/modules/local/split_chr/main.nf b/modules/local/split_chr/main.nf new file mode 100644 index 000000000..c41580530 --- /dev/null +++ b/modules/local/split_chr/main.nf @@ -0,0 +1,32 @@ +process SPLIT_CHR { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/bioawk:1.0--h5bf99c6_6': + 'biocontainers/bioawk:1.0--h5bf99c6_6' }" + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path("chr_split"), emit: output + tuple val("${task.process}"), val('bioawk'), val("1.0"), emit: versions_bioawk, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + """ + mkdir -p chr_split + bioawk -v outdir="chr_split" 'BEGIN{RS=">"; FS="\\n"} NR>1 {fnme=outdir "/" \$1 ".fa"; print ">" \$0 > fnme; close(fnme); if (NR==25) exit;}' ${input} + """ + + stub: + """ + mkdir -p chr_split + touch chr_split/test1.fa + touch chr_split/test2.fa + """ +} diff --git a/modules/nf-core/bcftools/annotate/environment.yml b/modules/nf-core/bcftools/annotate/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/annotate/environment.yml +++ b/modules/nf-core/bcftools/annotate/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/annotate/main.nf b/modules/nf-core/bcftools/annotate/main.nf index 9ffdfdf0a..18778cc2b 100644 --- a/modules/nf-core/bcftools/annotate/main.nf +++ b/modules/nf-core/bcftools/annotate/main.nf @@ -1,78 +1,81 @@ process BCFTOOLS_ANNOTATE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: - tuple val(meta), path(input), path(index), path(annotations), path(annotations_index) - path(header_lines) + tuple val(meta), path(input), path(index), path(annotations), path(annotations_index), path(columns), path(header_lines), path(rename_chrs) output: - tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi, optional: true - tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.${extension}"), emit: vcf + tuple val(meta), path("${prefix}.${extension}.tbi"), emit: tbi, optional: true + tuple val(meta), path("${prefix}.${extension}.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def header_file = header_lines ? "--header-lines ${header_lines}" : '' + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" def annotations_file = annotations ? "--annotations ${annotations}" : '' - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index_command = !index ? "bcftools index $input" : '' + def columns_file = columns ? "--columns-file ${columns}" : '' + def header_file = header_lines ? "--header-lines ${header_lines}" : '' + def rename_chrs_file = rename_chrs ? "--rename-chrs ${rename_chrs}" : '' + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : "vcf" + def index_command = !index ? "bcftools index ${input}" : '' - if ("$input" == "${prefix}.${extension}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + if ("${input}" == "${prefix}.${extension}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } """ - $index_command + ${index_command} bcftools \\ annotate \\ - $args \\ - $annotations_file \\ - $header_file \\ + ${args} \\ + ${annotations_file} \\ + ${columns_file} \\ + ${header_file} \\ + ${rename_chrs_file} \\ --output ${prefix}.${extension} \\ - --threads $task.cpus \\ - $input - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$( bcftools --version |& sed '1!d; s/^.*bcftools //' ) - END_VERSIONS + --threads ${task.cpus} \\ + ${input} """ stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index_extension = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : "vcf" + def index_extension = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") ? "csi" : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" def create_index = extension.endsWith(".gz") && index_extension.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index_extension}" : "" + if ("${input}" == "${prefix}.${extension}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$( bcftools --version |& sed '1!d; s/^.*bcftools //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/annotate/meta.yml b/modules/nf-core/bcftools/annotate/meta.yml index 5bfccd2bd..863316616 100644 --- a/modules/nf-core/bcftools/annotate/meta.yml +++ b/modules/nf-core/bcftools/annotate/meta.yml @@ -23,54 +23,87 @@ input: - input: type: file description: Query VCF or BCF file, can be either uncompressed or compressed + ontologies: [] - index: type: file description: Index of the query VCF or BCF file + ontologies: [] - annotations: type: file description: Bgzip-compressed file with annotations + ontologies: [] - annotations_index: type: file description: Index of the annotations file - - - header_lines: + ontologies: [] + - columns: + type: file + description: List of columns in the annotations file, one name per row + ontologies: [] + - header_lines: type: file description: Contains lines to append to the output VCF header + ontologies: [] + - rename_chrs: + type: file + description: Rename annotations according to this file containing "old_name new_name\n" + pairs separated by whitespaces, each on a separate line. + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.{vcf,vcf.gz,bcf,bcf.gz}": + - "${prefix}.${extension}": type: file description: Compressed annotated VCF file pattern: "*{vcf,vcf.gz,bcf,bcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.tbi": + - "${prefix}.${extension}.tbi": type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.csi": + - "${prefix}.${extension}.csi": type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@projectoriented" - "@ramprasadn" diff --git a/modules/nf-core/bcftools/annotate/tests/bcf.config b/modules/nf-core/bcftools/annotate/tests/bcf.config deleted file mode 100644 index 79d26779d..000000000 --- a/modules/nf-core/bcftools/annotate/tests/bcf.config +++ /dev/null @@ -1,4 +0,0 @@ -process { - ext.args = "-x ID,INFO/DP,FORMAT/DP --output-type u" - ext.prefix = { "${meta.id}_ann" } -} diff --git a/modules/nf-core/bcftools/annotate/tests/main.nf.test b/modules/nf-core/bcftools/annotate/tests/main.nf.test index 3a5c49331..3e1d25733 100644 --- a/modules/nf-core/bcftools/annotate/tests/main.nf.test +++ b/modules/nf-core/bcftools/annotate/tests/main.nf.test @@ -2,6 +2,7 @@ nextflow_process { name "Test Process BCFTOOLS_ANNOTATE" script "../main.nf" + config "./nextflow.config" process "BCFTOOLS_ANNOTATE" tag "modules" @@ -9,11 +10,12 @@ nextflow_process { tag "bcftools" tag "bcftools/annotate" - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_output") { - - config "./vcf.config" + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_output") { when { + params { + args_modules = "-x ID,INFO/DP,FORMAT/DP --output-type z" + } process { """ input[0] = [ @@ -21,30 +23,32 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, - process.out.versions + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name + ":variantsMD5," + path(it).vcf.variantsMD5 }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } - test("sarscov2 - [vcf, [], annotation, annotation_tbi], [] - vcf_output") { - - config "./vcf.config" + test("sarscov2 - [vcf, [], annotation, annotation_tbi], [], [], [] - vcf_output") { when { + params { + args_modules = "-x ID,INFO/DP,FORMAT/DP --output-type z" + } process { """ input[0] = [ @@ -52,29 +56,32 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), [], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, - process.out.versions + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name + ":variantsMD5," + path(it).vcf.variantsMD5 }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index") { - config "./vcf_gz_index.config" + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index") { when { + params { + args_modules = "--output-type z --write-index --no-version" + } process { """ input[0] = [ @@ -82,33 +89,32 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions - ).match() }, - { assert process.out.csi[0][1].endsWith(".csi") } + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name + ":variantsMD5," + path(it).vcf.variantsMD5 }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_csi") { - - config "./vcf_gz_index_csi.config" + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_csi") { when { + params { + args_modules = "--output-type z --write-index=csi --no-version" + } process { """ input[0] = [ @@ -116,33 +122,32 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions - ).match() }, - { assert process.out.csi[0][1].endsWith(".csi") } + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name + ":variantsMD5," + path(it).vcf.variantsMD5 }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_tbi") { - - config "./vcf_gz_index_tbi.config" + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_tbi") { when { + params { + args_modules = "--output-type z --write-index=tbi --no-version" + } process { """ input[0] = [ @@ -150,67 +155,146 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions - ).match() }, - { assert process.out.tbi[0][1].endsWith(".tbi") } + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name + ":variantsMD5," + path(it).vcf.variantsMD5 }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } + } + + test("sarscov2 - [vcf, [], annotation, annotation_tbi], [], header, [] - bcf_output") { + + when { + params { + args_modules = "-x ID,INFO/DP,FORMAT/DP --output-type u" + } + process { + """ + header = channel.of( + '##INFO=', + '##INFO=' + ).collectFile(name:"headers.vcf", newLine:true) + input[0] = channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + [], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [] + ]) + .combine(header) + .combine(channel.of([[]])) + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } } - test("sarscov2 - [vcf, [], annotation, annotation_tbi], header - bcf_output") { - config "./bcf.config" + test("sarscov2 - [vcf, [], annotation, annotation_tbi], columns, [], [] - bcf_output") { when { + params { + args_modules = "-x ID,INFO/DP,FORMAT/DP --output-type u" + } process { """ - input[0] = [ + columns = channel.of('INFO/ICB', 'INFO/HOB', 'INFO/DP4').collectFile(name:"columns.txt", newLine:true) + input[0] = channel.of([ [ id:'test', single_end:false ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), [], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) - ] - input[1] = Channel.of( + ]).combine(columns) + .combine(channel.of([[], []])) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sarscov2 - [vcf, [], annotation, annotation_tbi], [], header, rename_chrs - vcf_gz_index") { + + when { + params { + args_modules = "--output-type z --write-index --no-version" + } + process { + """ + headers = channel.of( '##INFO=', '##INFO=' ).collectFile(name:"headers.vcf", newLine:true) + rename = channel.of('MT192765.1 renamed').collectFile(name:"rename.txt", newLine:true) + input[0] = channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + [], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [] + ]).combine(headers) + .combine(rename) """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, - process.out.versions - ).match("bcf") } + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - stub") { + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - stub") { - config "./vcf.config" options "-stub" when { + params { + args_modules = "-x ID,INFO/DP,FORMAT/DP --output-type z" + } process { """ input[0] = [ @@ -218,28 +302,34 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index - stub") { + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index - stub") { - config "./vcf_gz_index.config" options "-stub" when { + params { + args_modules = "--output-type z --write-index --no-version" + } process { """ input[0] = [ @@ -247,29 +337,34 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match()}, - { assert process.out.csi[0][1].endsWith(".csi") } + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_csi - stub") { + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_csi - stub") { - config "./vcf_gz_index_csi.config" options "-stub" when { + params { + args_modules = "--output-type z --write-index=csi --no-version" + } process { """ input[0] = [ @@ -277,29 +372,34 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() }, - { assert process.out.csi[0][1].endsWith(".csi") } + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_tbi - stub") { + test("sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_tbi - stub") { - config "./vcf_gz_index_tbi.config" options "-stub" when { + params { + args_modules = "--output-type z --write-index=tbi --no-version" + } process { """ input[0] = [ @@ -307,21 +407,23 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), + [], [], [] ] - input[1] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() }, - { assert process.out.tbi[0][1].endsWith(".tbi") } + { assert snapshot( + process.out.vcf.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/annotate/tests/main.nf.test.snap b/modules/nf-core/bcftools/annotate/tests/main.nf.test.snap index bac2224a3..10af196a1 100644 --- a/modules/nf-core/bcftools/annotate/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/annotate/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "bcf": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index - stub": { "content": [ [ [ @@ -7,20 +7,38 @@ "id": "test", "single_end": false }, - "test_ann.bcf" + "test_ann.vcf.gz" ] ], [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.csi" + ] + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-06-12T16:39:33.331888" + "timestamp": "2026-02-27T15:29:19.618749659" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_tbi": { "content": [ [ [ @@ -28,91 +46,116 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz" + "test_ann.vcf.gz:variantsMD5,bc7bf3ee9e8430e064c539eb81e59bf9" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.tbi" ] ], [ ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-27T15:28:43.350060834" + }, + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_csi": { + "content": [ [ [ { "id": "test", "single_end": false }, - "test_vcf.vcf.gz.csi" + "test_ann.vcf.gz:variantsMD5,bc7bf3ee9e8430e064c539eb81e59bf9" ] ], [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.csi" + ] + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:07:59.658031137" + "timestamp": "2026-02-27T15:28:36.101003418" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_csi - stub": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_tbi - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.tbi" + ] + ], + [ + + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "1": [ - - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ], - "csi": [ + "versions_bcftools": [ [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" ] - ], - "tbi": [ - - ], - "vcf": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "versions": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:09:05.096883418" + "timestamp": "2026-02-27T15:29:34.19449127" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_csi": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index_csi - stub": { "content": [ [ [ @@ -120,7 +163,7 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz" + "test_ann.vcf.gz" ] ], [ @@ -132,67 +175,65 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz.csi" + "test_ann.vcf.gz.csi" ] ], - [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:08:10.581301219" + "timestamp": "2026-02-27T15:29:26.927815399" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - stub": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_gz_index": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz:variantsMD5,bc7bf3ee9e8430e064c539eb81e59bf9" + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.csi" + ] + ], { - "0": [ + "versions_bcftools": [ [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ], - "csi": [ - - ], - "tbi": [ - - ], - "vcf": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "versions": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:08:43.975017625" + "timestamp": "2026-02-27T15:28:28.891823681" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_tbi": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - stub": { "content": [ [ [ @@ -200,32 +241,65 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz" + "test_ann.vcf.gz" ] ], + [ + + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-27T15:29:12.400301681" + }, + "sarscov2 - [vcf, [], annotation, annotation_tbi], [], header, [] - bcf_output": { + "content": [ [ [ { "id": "test", "single_end": false }, - "test_vcf.vcf.gz.tbi" + "test_ann.bcf" ] ], [ ], [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:08:21.354059092" + "timestamp": "2026-02-27T15:28:50.375384421" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_output": { + "sarscov2 - [vcf, [], annotation, annotation_tbi], [], [], [] - vcf_output": { "content": [ [ [ @@ -233,20 +307,32 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz" + "test_ann.vcf.gz:variantsMD5,250b64289ab9d48f76359d01699fdf7d" ] ], [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:07:37.788393317" + "timestamp": "2026-02-27T15:28:21.320211288" }, - "sarscov2 - [vcf, [], annotation, annotation_tbi], [] - vcf_output": { + "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [], [], [] - vcf_output": { "content": [ [ [ @@ -254,135 +340,101 @@ "id": "test", "single_end": false }, - "test_vcf.vcf.gz" + "test_ann.vcf.gz:variantsMD5,250b64289ab9d48f76359d01699fdf7d" ] ], [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ] + + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:07:48.500746325" + "timestamp": "2026-02-27T15:28:13.274072987" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index_tbi - stub": { + "sarscov2 - [vcf, [], annotation, annotation_tbi], [], header, rename_chrs - vcf_gz_index": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz" + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.csi" + ] + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ], - "csi": [ - - ], - "tbi": [ + "versions_bcftools": [ [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" ] - ], - "vcf": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "versions": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:09:16.094918834" + "timestamp": "2026-02-27T15:29:05.094685409" }, - "sarscov2 - [vcf, tbi, annotation, annotation_tbi], [] - vcf_gz_index - stub": { + "sarscov2 - [vcf, [], annotation, annotation_tbi], columns, [], [] - bcf_output": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.bcf" + ] + ], + [ + + ], + [ + + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "1": [ - - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" - ], - "csi": [ - [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "tbi": [ - - ], - "vcf": [ + "versions_bcftools": [ [ - { - "id": "test", - "single_end": false - }, - "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "BCFTOOLS_ANNOTATE", + "bcftools", + "1.22" ] - ], - "versions": [ - "versions.yml:md5,ea53f98610d42597cf384ff1fa3eb204" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-15T10:08:54.366358502" + "timestamp": "2026-02-27T15:28:57.906382655" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/annotate/tests/nextflow.config b/modules/nf-core/bcftools/annotate/tests/nextflow.config new file mode 100644 index 000000000..102351009 --- /dev/null +++ b/modules/nf-core/bcftools/annotate/tests/nextflow.config @@ -0,0 +1,4 @@ +process { + ext.args = "${params.args_modules}" + ext.prefix = { "${meta.id}_ann" } +} diff --git a/modules/nf-core/bcftools/annotate/tests/tags.yml b/modules/nf-core/bcftools/annotate/tests/tags.yml deleted file mode 100644 index f97a1afc8..000000000 --- a/modules/nf-core/bcftools/annotate/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/annotate: - - "modules/nf-core/bcftools/annotate/**" diff --git a/modules/nf-core/bcftools/annotate/tests/vcf.config b/modules/nf-core/bcftools/annotate/tests/vcf.config deleted file mode 100644 index 611868d55..000000000 --- a/modules/nf-core/bcftools/annotate/tests/vcf.config +++ /dev/null @@ -1,4 +0,0 @@ -process { - ext.args = "-x ID,INFO/DP,FORMAT/DP --output-type z" - ext.prefix = { "${meta.id}_vcf" } -} diff --git a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index.config b/modules/nf-core/bcftools/annotate/tests/vcf_gz_index.config deleted file mode 100644 index 2fd9a225f..000000000 --- a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index.config +++ /dev/null @@ -1,4 +0,0 @@ -process { - ext.args = "--output-type z --write-index --no-version" - ext.prefix = { "${meta.id}_vcf" } -} diff --git a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_csi.config b/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_csi.config deleted file mode 100644 index 512c1dfb0..000000000 --- a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_csi.config +++ /dev/null @@ -1,4 +0,0 @@ -process { - ext.args = "--output-type z --write-index=csi --no-version" - ext.prefix = { "${meta.id}_vcf" } -} diff --git a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_tbi.config b/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_tbi.config deleted file mode 100644 index 7feb5ebbe..000000000 --- a/modules/nf-core/bcftools/annotate/tests/vcf_gz_index_tbi.config +++ /dev/null @@ -1,4 +0,0 @@ -process { - ext.args = "--output-type z --write-index=tbi --no-version" - ext.prefix = { "${meta.id}_vcf" } -} diff --git a/modules/nf-core/bcftools/concat/environment.yml b/modules/nf-core/bcftools/concat/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/concat/environment.yml +++ b/modules/nf-core/bcftools/concat/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/concat/main.nf b/modules/nf-core/bcftools/concat/main.nf index a94b28d86..269da8e0c 100644 --- a/modules/nf-core/bcftools/concat/main.nf +++ b/modules/nf-core/bcftools/concat/main.nf @@ -1,59 +1,73 @@ process BCFTOOLS_CONCAT { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcfs), path(tbi) output: - tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf - tuple val(meta), path("${prefix}.vcf.gz.tbi"), emit: tbi, optional: true - tuple val(meta), path("${prefix}.vcf.gz.csi"), emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.${extension}"), emit: vcf + tuple val(meta), path("${prefix}.${extension}.tbi"), emit: tbi, optional: true + tuple val(meta), path("${prefix}.${extension}.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" def tbi_names = tbi.findAll { file -> !(file instanceof List) }.collect { file -> file.name } - def create_input_index = vcfs.collect { vcf -> tbi_names.contains(vcf.name + ".tbi") ? "" : "tabix ${vcf}" }.join("\n ") + def create_input_index = vcfs.collect { vcf -> tbi_names.contains(vcf.name + ".tbi") || tbi_names.contains(vcf.name + ".csi") ? "" : "tabix ${vcf}" }.join("\n ") + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def input = vcfs.sort { vcf -> vcf.toString() }.join(" ") """ ${create_input_index} bcftools concat \\ - --output ${prefix}.vcf.gz \\ - $args \\ - --threads $task.cpus \\ - ${vcfs} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS + --output ${prefix}.${extension} \\ + ${args} \\ + --threads ${task.cpus} \\ + ${input} """ stub: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" - def create_index = index.matches("csi|tbi") ? "touch ${prefix}.vcf.gz.${index}" : "" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def index_extension = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" + def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" + def create_index = extension.endsWith(".gz") && index_extension.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index_extension}" : "" + """ - echo "" | gzip > ${prefix}.vcf.gz + ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/concat/meta.yml b/modules/nf-core/bcftools/concat/meta.yml index d2565b289..1734a8c34 100644 --- a/modules/nf-core/bcftools/concat/meta.yml +++ b/modules/nf-core/bcftools/concat/meta.yml @@ -31,50 +31,63 @@ input: List containing 2 or more index files (optional) e.g. [ 'file1.tbi', 'file2.tbi' ] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - pattern: "*.{vcf.gz}" - - ${prefix}.vcf.gz: + - ${prefix}.${extension}: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - pattern: "*.{vcf.gz}" - - tbi: - - meta: + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + tbi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - pattern: "*.tbi" - - ${prefix}.vcf.gz.tbi: + - ${prefix}.${extension}.tbi: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] pattern: "*.tbi" - - csi: - - meta: + csi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - pattern: "*.csi" - - ${prefix}.vcf.gz.csi: + - ${prefix}.${extension}.csi: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@abhi18av" - "@nvnieuwk" diff --git a/modules/nf-core/bcftools/concat/tests/main.nf.test b/modules/nf-core/bcftools/concat/tests/main.nf.test index cb4642b29..58e199918 100644 --- a/modules/nf-core/bcftools/concat/tests/main.nf.test +++ b/modules/nf-core/bcftools/concat/tests/main.nf.test @@ -9,7 +9,6 @@ nextflow_process { tag "bcftools" tag "bcftools/concat" - test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]]") { config "./nextflow.config" @@ -20,12 +19,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -38,7 +37,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index") { @@ -51,12 +49,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -70,12 +68,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_csi") { @@ -88,12 +85,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -107,12 +104,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi") { @@ -125,12 +121,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -144,12 +140,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } @@ -163,8 +158,8 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [] ] @@ -178,7 +173,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - stub") { @@ -192,12 +186,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -210,7 +204,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index - stub") { @@ -224,12 +217,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -243,7 +236,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_csi - stub") { @@ -257,12 +249,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -276,7 +268,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi - stub") { @@ -290,12 +281,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test_haplotcaller.cnn.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -309,8 +300,7 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/concat/tests/main.nf.test.snap b/modules/nf-core/bcftools/concat/tests/main.nf.test.snap index 09e87cd3e..5edf5beb6 100644 --- a/modules/nf-core/bcftools/concat/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/concat/tests/main.nf.test.snap @@ -1,5 +1,42 @@ { - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index - stub": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_csi": { + "content": [ + [ + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" + ] + ], + [ + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz.csi" + ] + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T11:59:52.705734505" + }, + "homo_sapiens - [[vcf1, vcf2], []]": { "content": [ { "0": [ @@ -7,30 +44,24 @@ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "1": [ ], "2": [ - [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" - ], - "csi": [ [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" ] + ], + "csi": [ + ], "tbi": [ @@ -40,21 +71,25 @@ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:04:11.178539482" + "timestamp": "2026-01-20T12:00:08.498123366" }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]]": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - stub": { "content": [ { "0": [ @@ -62,7 +97,7 @@ { "id": "test3" }, - "test3.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" + "test3.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ @@ -72,7 +107,11 @@ ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ], "csi": [ @@ -85,52 +124,25 @@ { "id": "test3" }, - "test3.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" + "test3.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:03:08.765639958" + "timestamp": "2026-01-20T12:00:15.986212097" }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index": { - "content": [ - [ - [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" - ] - ], - [ - [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz.csi" - ] - ], - [ - - ], - [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-26T11:03:21.607274757" - }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi - stub": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index - stub": { "content": [ { "0": [ @@ -142,29 +154,33 @@ ] ], "1": [ + + ], + "2": [ [ { "id": "test3" }, - "test3_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + "test3_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "2": [ - ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ], "csi": [ - - ], - "tbi": [ [ { "id": "test3" }, - "test3_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + "test3_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "tbi": [ + ], "vcf": [ [ @@ -174,49 +190,59 @@ "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:04:27.332133878" + "timestamp": "2026-01-20T12:00:24.007593166" }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_csi": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi": { "content": [ [ [ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] + ], + [ + ], [ [ { "id": "test3" }, - "test3_vcf.vcf.gz.csi" + "test3_vcf.vcf.gz.tbi" ] ], - [ - - ], - [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:03:36.575719606" + "timestamp": "2026-01-20T12:00:00.937832062" }, - "homo_sapiens - [[vcf1, vcf2], []]": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]]": { "content": [ { "0": [ @@ -224,7 +250,7 @@ { "id": "test3" }, - "test3.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "1": [ @@ -234,7 +260,11 @@ ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ], "csi": [ @@ -247,21 +277,62 @@ { "id": "test3" }, - "test3.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:03:54.069826178" + "timestamp": "2026-01-20T11:59:37.378838683" }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - stub": { + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index": { + "content": [ + [ + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" + ] + ], + [ + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz.csi" + ] + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T11:59:45.296771646" + }, + "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi - stub": { "content": [ { "0": [ @@ -269,73 +340,60 @@ { "id": "test3" }, - "test3.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ - + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "2": [ ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ], "csi": [ ], "tbi": [ - + [ + { + "id": "test3" + }, + "test3_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "vcf": [ [ { "id": "test3" }, - "test3.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:04:02.45346063" - }, - "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi": { - "content": [ - [ - [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz:md5,5f6796c3ae109a1a5b87353954693f5a" - ] - ], - [ - - ], - [ - [ - { - "id": "test3" - }, - "test3_vcf.vcf.gz.tbi" - ] - ], - [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-26T11:03:44.618596639" + "timestamp": "2026-01-20T12:00:39.792930532" }, "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_csi - stub": { "content": [ @@ -360,7 +418,11 @@ ] ], "3": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -381,15 +443,19 @@ "test3_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,c6e19f105510a46af1c5da9064e2e659" + "versions_bcftools": [ + [ + "BCFTOOLS_CONCAT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-26T11:04:19.745768656" + "timestamp": "2026-01-20T12:00:31.985353981" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/concat/tests/nextflow.config b/modules/nf-core/bcftools/concat/tests/nextflow.config index f3e1e98c6..1d5fee9eb 100644 --- a/modules/nf-core/bcftools/concat/tests/nextflow.config +++ b/modules/nf-core/bcftools/concat/tests/nextflow.config @@ -1,3 +1,3 @@ process { - ext.args = "--no-version" -} \ No newline at end of file + ext.args = "--no-version -a" +} diff --git a/modules/nf-core/bcftools/concat/tests/tags.yml b/modules/nf-core/bcftools/concat/tests/tags.yml deleted file mode 100644 index 21710d4eb..000000000 --- a/modules/nf-core/bcftools/concat/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/concat: - - "modules/nf-core/bcftools/concat/**" diff --git a/modules/nf-core/bcftools/concat/tests/vcf_gz_index.config b/modules/nf-core/bcftools/concat/tests/vcf_gz_index.config index 7dd696ee2..b6f9165cf 100644 --- a/modules/nf-core/bcftools/concat/tests/vcf_gz_index.config +++ b/modules/nf-core/bcftools/concat/tests/vcf_gz_index.config @@ -1,4 +1,4 @@ process { ext.prefix = { "${meta.id}_vcf" } - ext.args = "--output-type z --write-index --no-version" + ext.args = "--output-type z --write-index --no-version --allow-overlaps" } diff --git a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config index aebffb6fb..2455b1457 100644 --- a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config +++ b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config @@ -1,4 +1,4 @@ process { ext.prefix = { "${meta.id}_vcf" } - ext.args = "--output-type z --write-index=csi --no-version" + ext.args = "--output-type z --write-index=csi --no-version --allow-overlaps -a" } diff --git a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_tbi.config b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_tbi.config index b192ae7d1..1ca852310 100644 --- a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_tbi.config +++ b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_tbi.config @@ -1,4 +1,4 @@ process { ext.prefix = { "${meta.id}_vcf" } - ext.args = "--output-type z --write-index=tbi --no-version" + ext.args = "--output-type z --write-index=tbi --no-version --allow-overlaps" } diff --git a/modules/nf-core/bcftools/filter/environment.yml b/modules/nf-core/bcftools/filter/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/filter/environment.yml +++ b/modules/nf-core/bcftools/filter/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/filter/main.nf b/modules/nf-core/bcftools/filter/main.nf index 36cbf8c2b..4b558818a 100644 --- a/modules/nf-core/bcftools/filter/main.nf +++ b/modules/nf-core/bcftools/filter/main.nf @@ -1,20 +1,20 @@ process BCFTOOLS_FILTER { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf), path(tbi) output: tuple val(meta), path("*.${extension}"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi, optional: true - tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -23,51 +23,56 @@ process BCFTOOLS_FILTER { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" - if ("$vcf" == "${prefix}.${extension}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + if ("${vcf}" == "${prefix}.${extension}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } """ bcftools filter \\ --output ${prefix}.${extension} \\ --threads ${task.cpus} \\ - $args \\ - $vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS + ${args} \\ + ${vcf} """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" - if ("$vcf" == "${prefix}.${extension}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + if ("${vcf}" == "${prefix}.${extension}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/filter/meta.yml b/modules/nf-core/bcftools/filter/meta.yml index d72f27554..4ab447ff6 100644 --- a/modules/nf-core/bcftools/filter/meta.yml +++ b/modules/nf-core/bcftools/filter/meta.yml @@ -23,13 +23,15 @@ input: type: file description: VCF input file pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" + ontologies: [] - tbi: type: file description: VCF index file pattern: "*.tbi" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -38,8 +40,9 @@ output: type: file description: VCF filtered output file pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -48,8 +51,9 @@ output: type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -58,11 +62,28 @@ output: type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/bcftools/filter/tests/main.nf.test b/modules/nf-core/bcftools/filter/tests/main.nf.test index fadff0e30..42cb8ab97 100644 --- a/modules/nf-core/bcftools/filter/tests/main.nf.test +++ b/modules/nf-core/bcftools/filter/tests/main.nf.test @@ -31,7 +31,6 @@ nextflow_process { { assert snapshot(process.out).match("vcf") } ) } - } test("sarscov2 - vcf_gz_index") { @@ -57,12 +56,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_csi") { @@ -88,12 +86,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_tbi") { @@ -119,12 +116,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } test("sarscov2 - vcf - bcf output") { @@ -149,7 +145,6 @@ nextflow_process { { assert snapshot(process.out).match("bcf output") } ) } - } test("sarscov2 - vcf.gz, tbi - region filter") { @@ -174,7 +169,6 @@ nextflow_process { { assert snapshot(process.out).match("region filter") } ) } - } test("sarscov2 - vcf - stub") { @@ -200,7 +194,6 @@ nextflow_process { { assert snapshot(process.out).match("vcf - stub") } ) } - } test("sarscov2 - vcf_gz_index - stub") { @@ -227,7 +220,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_csi - stub") { @@ -254,7 +246,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_tbi - stub") { @@ -281,7 +272,5 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } - -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/filter/tests/main.nf.test.snap b/modules/nf-core/bcftools/filter/tests/main.nf.test.snap index 640907e42..798dade7f 100644 --- a/modules/nf-core/bcftools/filter/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/filter/tests/main.nf.test.snap @@ -17,7 +17,11 @@ ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ @@ -33,16 +37,20 @@ "bcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-08T09:14:47.394005264" + "timestamp": "2026-01-20T12:02:38.075538496" }, "sarscov2 - vcf_gz_index_tbi - stub": { "content": [ @@ -67,7 +75,11 @@ ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ @@ -88,16 +100,20 @@ "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:59:08.235854993" + "timestamp": "2026-01-20T12:03:09.787136694" }, "vcf": { "content": [ @@ -117,7 +133,11 @@ ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ @@ -133,16 +153,20 @@ "vcf_test.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T15:20:28.427974818" + "timestamp": "2026-01-20T12:02:00.400038419" }, "bcf output": { "content": [ @@ -162,7 +186,11 @@ ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ @@ -178,16 +206,20 @@ "bcf_test.bcf.gz:md5,c8a304c8d2892039201154153c8cd536" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T15:20:34.049236749" + "timestamp": "2026-01-20T12:02:30.237925195" }, "sarscov2 - vcf_gz_index": { "content": [ @@ -210,15 +242,21 @@ [ ], - [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T08:09:49.837854646" + "timestamp": "2026-01-20T12:02:07.949745874" }, "sarscov2 - vcf_gz_index_csi": { "content": [ @@ -241,15 +279,21 @@ [ ], - [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:57:19.513365022" + "timestamp": "2026-01-20T12:02:15.417109301" }, "vcf - stub": { "content": [ @@ -269,7 +313,11 @@ ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ @@ -285,16 +333,20 @@ "vcf_test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T15:29:55.846566153" + "timestamp": "2026-01-20T12:02:46.265722559" }, "sarscov2 - vcf_gz_index - stub": { "content": [ @@ -319,7 +371,11 @@ ] ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -340,16 +396,20 @@ "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T15:59:37.636874258" + "timestamp": "2026-01-20T12:02:54.301083152" }, "sarscov2 - vcf_gz_index_csi - stub": { "content": [ @@ -374,7 +434,11 @@ ] ], "3": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -395,16 +459,20 @@ "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:58:46.36278584" + "timestamp": "2026-01-20T12:03:02.260111336" }, "sarscov2 - vcf_gz_index_tbi": { "content": [ @@ -427,14 +495,20 @@ "vcf_test_vcf.vcf.gz.tbi" ] ], - [ - "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_FILTER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:57:34.748836577" + "timestamp": "2026-01-20T12:02:23.055607519" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/filter/tests/region_filter.config b/modules/nf-core/bcftools/filter/tests/region_filter.config new file mode 100644 index 000000000..b18fb4bf0 --- /dev/null +++ b/modules/nf-core/bcftools/filter/tests/region_filter.config @@ -0,0 +1,4 @@ +process { + ext.prefix = { "${meta.id}_vcf" } + ext.args = "--output-type z -r MT192765.1 --no-version" +} diff --git a/modules/nf-core/bcftools/filter/tests/tags.yml b/modules/nf-core/bcftools/filter/tests/tags.yml deleted file mode 100644 index d5e010800..000000000 --- a/modules/nf-core/bcftools/filter/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/filter: - - "modules/nf-core/bcftools/filter/**" diff --git a/modules/nf-core/bcftools/merge/environment.yml b/modules/nf-core/bcftools/merge/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/merge/environment.yml +++ b/modules/nf-core/bcftools/merge/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/merge/main.nf b/modules/nf-core/bcftools/merge/main.nf index facb14ea1..f1acbd3da 100644 --- a/modules/nf-core/bcftools/merge/main.nf +++ b/modules/nf-core/bcftools/merge/main.nf @@ -1,22 +1,20 @@ process BCFTOOLS_MERGE { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: - tuple val(meta), path(vcfs), path(tbis) - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) - tuple val(meta4), path(bed) + tuple val(meta), path(vcfs), path(tbis), path(bed) + tuple val(meta2), path(fasta), path(fai) output: tuple val(meta), path("*.{bcf,vcf}{,.gz}"), emit: vcf - tuple val(meta), path("*.{csi,tbi}") , emit: index, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.{csi,tbi}"), emit: index, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -25,50 +23,51 @@ process BCFTOOLS_MERGE { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def input = (vcfs.collect().size() > 1) ? vcfs.sort{ it.name } : vcfs - def regions = bed ? "--regions-file $bed" : "" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" + def input = vcfs.collect().size() > 1 ? vcfs.sort { vcf -> vcf.name } : vcfs + def regions = bed ? "--regions-file ${bed}" : "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" """ bcftools merge \\ - $args \\ - $regions \\ - --threads $task.cpus \\ + ${args} \\ + ${regions} \\ + --threads ${task.cpus} \\ --output ${prefix}.${extension} \\ - $input - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS + ${input} """ stub: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/merge/meta.yml b/modules/nf-core/bcftools/merge/meta.yml index 2cf09a1d4..445e5c56b 100644 --- a/modules/nf-core/bcftools/merge/meta.yml +++ b/modules/nf-core/bcftools/merge/meta.yml @@ -24,11 +24,18 @@ input: description: | List containing 2 or more vcf files e.g. [ 'file1.vcf', 'file2.vcf' ] + ontologies: [] - tbis: type: file description: | List containing the tbi index files corresponding to the vcfs input files e.g. [ 'file1.vcf.tbi', 'file2.vcf.tbi' ] + ontologies: [] + - bed: + type: file + description: "(Optional) The bed regions to merge on" + pattern: "*.bed" + ontologies: [] - - meta2: type: map description: | @@ -39,28 +46,16 @@ input: description: "(Optional) The fasta reference file (only necessary for the `--gvcf FILE` parameter)" pattern: "*.{fasta,fa}" - - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] + ontologies: [] - fai: type: file description: "(Optional) The fasta reference file index (only necessary for the `--gvcf FILE` parameter)" pattern: "*.fai" - - - meta4: - type: map - description: | - Groovy Map containing bed information - e.g. [ id:'genome' ] - - bed: - type: file - description: "(Optional) The bed regions to merge on" - pattern: "*.bed" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -69,8 +64,9 @@ output: type: file description: merged output file pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" - - index: - - meta: + ontologies: [] + index: + - - meta: type: map description: | Groovy Map containing sample information @@ -79,11 +75,28 @@ output: type: file description: index of merged output pattern: "*.{csi,tbi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/bcftools/merge/tests/bcf.config b/modules/nf-core/bcftools/merge/tests/bcf.config deleted file mode 100644 index 4467d07d9..000000000 --- a/modules/nf-core/bcftools/merge/tests/bcf.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = '--output-type u --no-version' -} diff --git a/modules/nf-core/bcftools/merge/tests/bcf_gz.config b/modules/nf-core/bcftools/merge/tests/bcf_gz.config deleted file mode 100644 index 280de8db0..000000000 --- a/modules/nf-core/bcftools/merge/tests/bcf_gz.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = '--output-type b --no-version' -} diff --git a/modules/nf-core/bcftools/merge/tests/main.nf.test b/modules/nf-core/bcftools/merge/tests/main.nf.test index 3995fc1a9..3a1f12206 100644 --- a/modules/nf-core/bcftools/merge/tests/main.nf.test +++ b/modules/nf-core/bcftools/merge/tests/main.nf.test @@ -2,6 +2,8 @@ nextflow_process { name "Test Process BCFTOOLS_MERGE" script "../main.nf" + config "./nextflow.config" + process "BCFTOOLS_MERGE" tag "modules" @@ -11,9 +13,10 @@ nextflow_process { test("sarscov2 - [vcf, tbi], [], [], []") { - config "./nextflow.config" - when { + params { + args_modules = "--force-samples --force-single --no-version" + } process { """ input[0] = [ @@ -25,11 +28,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -40,18 +42,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf output") { - config "./vcf.config" - when { + params { + args_modules = "--output-type v --no-version" + } process { """ input[0] = [ @@ -63,11 +65,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -78,18 +79,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).md5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output") { - config "./vcf_gz.config" - when { + params { + args_modules = "--output-type z --no-version" + } process { """ input[0] = [ @@ -101,11 +102,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -116,18 +116,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf.gz") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - bcf output") { - config "./bcf.config" - when { + params { + args_modules = "--output-type u --no-version" + } process { """ input[0] = [ @@ -139,11 +139,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -154,18 +153,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("bcf") }, { assert snapshot( file(process.out.vcf.get(0).get(1)).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - bcf.gz output") { - config "./bcf_gz.config" - when { + params { + args_modules = "--output-type b --no-version" + } process { """ input[0] = [ @@ -177,11 +176,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -192,18 +190,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("bcf.gz") }, { assert snapshot( file(process.out.vcf.get(0).get(1)).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - index") { - config "./vcf_gz_index.config" - when { + params { + args_modules = "--output-type z --write-index --no-version" + } process { """ input[0] = [ @@ -215,11 +213,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -232,19 +229,18 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, file(process.out.index.get(0).get(1)).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - csi index") { - config "./vcf_gz_index_csi.config" - when { - + params { + args_modules = "--output-type z --write-index=csi --no-version" + } process { """ input[0] = [ @@ -256,11 +252,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -273,18 +268,18 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, file(process.out.index.get(0).get(1)).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - tbi index") { - config "./vcf_gz_index_tbi.config" - when { + params { + args_modules = "--output-type z --write-index=tbi --no-version" + } process { """ input[0] = [ @@ -296,11 +291,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -313,18 +307,18 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, file(process.out.index.get(0).get(1)).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], bed") { - config "./nextflow.config" - when { + params { + args_modules = "--force-samples --force-single --no-version" + } process { """ input[0] = [ @@ -336,14 +330,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] - ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] + ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] + input[1] = [[],[],[]] """ } } @@ -354,18 +344,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).md5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("homo_sapiens - [vcf, tbi], fasta, fai, bed - vcf.gz output") { - config "./nextflow.gvcf.config" - when { + params { + args_modules = "--force-samples --no-version --output-type z --gvcf genome.fasta" + } process { """ input[0] = [ @@ -377,20 +367,14 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz.tbi', checkIfExists: true), - ] + ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) ] input[1] = [ [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] - ] - input[2] = [ - [ id:'test' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ], [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] ] - input[3] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) ] - ] """ } } @@ -401,17 +385,18 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf.gz") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - one sample") { - config "./nextflow.config" when { + params { + args_modules = "--force-samples --force-single --no-version" + } process { """ input[0] = [ @@ -421,11 +406,10 @@ nextflow_process { ], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -436,19 +420,20 @@ nextflow_process { { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, { assert snapshot( path(process.out.vcf.get(0).get(1)).md5, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - stub") { options "-stub" - config "./nextflow.config" when { + params { + args_modules = "--force-samples --force-single --no-version" + } process { """ input[0] = [ @@ -460,11 +445,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -476,15 +460,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf output - stub") { options "-stub" - config "./vcf.config" when { + params { + args_modules = "--output-type v --no-version" + } process { """ input[0] = [ @@ -496,11 +481,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -512,15 +496,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - stub") { options "-stub" - config "./vcf_gz.config" when { + params { + args_modules = "--output-type z --no-version" + } process { """ input[0] = [ @@ -532,11 +517,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -548,15 +532,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - bcf output - stub") { options "-stub" - config "./bcf.config" when { + params { + args_modules = "--output-type u --no-version" + } process { """ input[0] = [ @@ -568,11 +553,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -584,15 +568,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - bcf.gz output - stub") { options "-stub" - config "./bcf_gz.config" when { + params { + args_modules = "--output-type b --no-version" + } process { """ input[0] = [ @@ -604,11 +589,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -620,15 +604,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - index - stub") { options "-stub" - config "./vcf_gz_index.config" when { + params { + args_modules = "--output-type z --write-index --no-version" + } process { """ input[0] = [ @@ -640,11 +625,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -657,15 +641,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - csi index - stub") { options "-stub" - config "./vcf_gz_index_csi.config" when { + params { + args_modules = "--output-type z --write-index=csi --no-version" + } process { """ input[0] = [ @@ -677,11 +662,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] + ], + [] ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -694,52 +678,16 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - tbi index - stub") { options "-stub" - config "./vcf_gz_index_tbi.config" when { - process { - """ - input[0] = [ - [ id:'test' ], // meta map - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz', checkIfExists: true) - ], - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] - ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] - """ + params { + args_modules = "--output-type z --write-index=tbi --no-version" } - } - - then { - assertAll( - { assert process.success }, - { assert process.out.vcf.get(0).get(1).endsWith("vcf.gz") }, - { assert process.out.index.get(0).get(1).endsWith("tbi") }, - { assert snapshot(process.out).match() } - ) - } - - } - - test("sarscov2 - [vcf, tbi], [], [], bed - stub") { - - options "-stub" - config "./nextflow.config" - - when { process { """ input[0] = [ @@ -751,58 +699,10 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz.tbi', checkIfExists: true), - ] - ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] - ] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, - { assert snapshot(process.out).match() } - ) - } - - } - - test("homo_sapiens - [vcf, tbi], fasta, fai, bed - vcf.gz output - stub") { - - options "-stub" - config "./nextflow.gvcf.config" - when { - process { - """ - input[0] = [ - [ id:'test' ], // meta map - [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz', checkIfExists: true) ], - [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz.tbi', checkIfExists: true), - ] - ] - input[1] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] - ] - input[2] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] - ] - input[3] = [ - [ id:'test' ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) ] + [] ] + input[1] = [[],[],[]] """ } } @@ -811,43 +711,9 @@ nextflow_process { assertAll( { assert process.success }, { assert process.out.vcf.get(0).get(1).endsWith("vcf.gz") }, + { assert process.out.index.get(0).get(1).endsWith("tbi") }, { assert snapshot(process.out).match() } ) } - - } - - test("sarscov2 - [vcf, tbi], [], [], [] - one sample - stub") { - - options "-stub" - config "./nextflow.config" - - when { - process { - """ - input[0] = [ - [ id:'test' ], // meta map - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz', checkIfExists: true) - ], - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf.gz.tbi', checkIfExists: true) - ] - ] - input[1] = [[],[]] - input[2] = [[],[]] - input[3] = [[],[]] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert process.out.vcf.get(0).get(1).endsWith("vcf") }, - { assert snapshot(process.out).match() } - ) - } - } } diff --git a/modules/nf-core/bcftools/merge/tests/main.nf.test.snap b/modules/nf-core/bcftools/merge/tests/main.nf.test.snap index b3b625563..9dd091783 100644 --- a/modules/nf-core/bcftools/merge/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/merge/tests/main.nf.test.snap @@ -3,15 +3,21 @@ "content": [ "e0de448dc8e712956a03ce68d79a0b3a", "test.vcf.gz.tbi", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T12:34:16.977726522" + "timestamp": "2026-01-20T12:05:01.453191274" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf output - stub": { "content": [ @@ -28,7 +34,11 @@ ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ @@ -41,29 +51,39 @@ "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:17:34.532910365" + "timestamp": "2026-01-20T12:05:43.064165277" }, "sarscov2 - [vcf, tbi], [], [], bed": { "content": [ "febdcfb851dcfc83d8248520830aef10", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:29:48.630057872" + "timestamp": "2026-01-20T12:05:09.906419282" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - index - stub": { "content": [ @@ -85,7 +105,11 @@ ] ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -103,29 +127,39 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:17:59.983157569" + "timestamp": "2026-01-20T12:06:17.06290054" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf output": { "content": [ "57bb84274f336465d0a0946b532093b0", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:29:05.528412678" + "timestamp": "2026-01-20T12:04:14.044948834" }, "sarscov2 - [vcf, tbi], [], [], [] - bcf.gz output - stub": { "content": [ @@ -142,7 +176,11 @@ ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ @@ -155,16 +193,20 @@ "test.bcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T11:58:46.619657457" + "timestamp": "2026-01-20T12:06:08.633006073" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - tbi index - stub": { "content": [ @@ -186,7 +228,11 @@ ] ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -204,16 +250,20 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:18:12.848227353" + "timestamp": "2026-01-20T12:06:33.897407991" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - stub": { "content": [ @@ -230,7 +280,11 @@ ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ @@ -243,95 +297,78 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T11:23:15.794389239" + "timestamp": "2026-01-20T12:05:51.445673109" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - csi index": { "content": [ "e0de448dc8e712956a03ce68d79a0b3a", "test.vcf.gz.csi", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T11:57:16.850641473" + "timestamp": "2026-01-20T12:04:53.868676326" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output": { "content": [ "e0de448dc8e712956a03ce68d79a0b3a", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-09-05T11:56:27.949031071" - }, - "sarscov2 - [vcf, tbi], [], [], bed - stub": { - "content": [ { - "0": [ + "versions_bcftools": [ [ - { - "id": "test" - }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "BCFTOOLS_MERGE", + "bcftools", + "1.22" ] - ], - "1": [ - - ], - "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ], - "index": [ - - ], - "vcf": [ - [ - { - "id": "test" - }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:18:19.273064822" + "timestamp": "2026-01-20T12:04:22.660557224" }, "sarscov2 - [vcf, tbi], [], [], [] - bcf output": { "content": [ "test.bcf", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T11:56:38.567500859" + "timestamp": "2026-01-20T12:04:30.965022315" }, "sarscov2 - [vcf, tbi], [], [], [] - bcf output - stub": { "content": [ @@ -348,7 +385,11 @@ ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ @@ -361,134 +402,78 @@ "test.bcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:17:47.356328326" + "timestamp": "2026-01-20T12:05:59.932077434" }, - "sarscov2 - [vcf, tbi], [], [], [] - one sample - stub": { + "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - index": { "content": [ + "e0de448dc8e712956a03ce68d79a0b3a", + "test.vcf.gz.csi", { - "0": [ + "versions_bcftools": [ [ - { - "id": "test" - }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "BCFTOOLS_MERGE", + "bcftools", + "1.22" ] - ], - "1": [ - - ], - "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ], - "index": [ - - ], - "vcf": [ - [ - { - "id": "test" - }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T15:13:18.708495878" + "timestamp": "2026-01-20T12:04:46.41923299" }, - "homo_sapiens - [vcf, tbi], fasta, fai, bed - vcf.gz output - stub": { + "homo_sapiens - [vcf, tbi], fasta, fai, bed - vcf.gz output": { "content": [ + "645b7f7f9131bfe350a9ec3cf82c17fe", { - "0": [ + "versions_bcftools": [ [ - { - "id": "test" - }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "BCFTOOLS_MERGE", + "bcftools", + "1.22" ] - ], - "1": [ - - ], - "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ], - "index": [ - - ], - "vcf": [ - [ - { - "id": "test" - }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-05T13:56:45.706125286" - }, - "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - index": { - "content": [ - "e0de448dc8e712956a03ce68d79a0b3a", - "test.vcf.gz.csi", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T12:33:43.639646108" - }, - "homo_sapiens - [vcf, tbi], fasta, fai, bed - vcf.gz output": { - "content": [ - "645b7f7f9131bfe350a9ec3cf82c17fe", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-05T13:55:44.299812124" + "timestamp": "2026-01-20T12:05:18.989455751" }, "sarscov2 - [vcf, tbi], [], [], [] - one sample": { "content": [ "2a374cf02f0c32cf607646167e7f153b", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T15:37:38.491844702" + "timestamp": "2026-01-20T12:05:26.431607458" }, "sarscov2 - [vcf, tbi], [], [], [] - stub": { "content": [ @@ -505,7 +490,11 @@ ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ @@ -518,16 +507,20 @@ "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:17:28.188178904" + "timestamp": "2026-01-20T12:05:34.692613749" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf.gz output - csi index - stub": { "content": [ @@ -549,7 +542,11 @@ ] ], "2": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -567,41 +564,57 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T13:18:06.430943593" + "timestamp": "2026-01-20T12:06:25.137261969" }, "sarscov2 - [vcf, tbi], [], [], []": { "content": [ "e0de448dc8e712956a03ce68d79a0b3a", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T12:31:03.893007442" + "timestamp": "2026-01-20T12:04:05.637837157" }, "sarscov2 - [vcf, tbi], [], [], [] - bcf.gz output": { "content": [ "test.bcf.gz", - [ - "versions.yml:md5,d2c0a30d9a4cc6df89a464ae82e0c38a" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_MERGE", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-05T11:56:56.416361069" + "timestamp": "2026-01-20T12:04:38.467108836" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/merge/tests/nextflow.config b/modules/nf-core/bcftools/merge/tests/nextflow.config index c3f0b7159..36f2fa1a5 100644 --- a/modules/nf-core/bcftools/merge/tests/nextflow.config +++ b/modules/nf-core/bcftools/merge/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: BCFTOOLS_MERGE { - ext.args = '--force-samples --force-single --no-version' + ext.args = "${params.args_modules}" } } diff --git a/modules/nf-core/bcftools/merge/tests/nextflow.gvcf.config b/modules/nf-core/bcftools/merge/tests/nextflow.gvcf.config deleted file mode 100644 index 8c457b716..000000000 --- a/modules/nf-core/bcftools/merge/tests/nextflow.gvcf.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BCFTOOLS_MERGE { - ext.args = { "--force-samples --no-version --output-type z --gvcf $fasta" } - } -} diff --git a/modules/nf-core/bcftools/merge/tests/tags.yml b/modules/nf-core/bcftools/merge/tests/tags.yml deleted file mode 100644 index 1464d0c1c..000000000 --- a/modules/nf-core/bcftools/merge/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/merge: - - "modules/nf-core/bcftools/merge/**" diff --git a/modules/nf-core/bcftools/merge/tests/vcf.config b/modules/nf-core/bcftools/merge/tests/vcf.config deleted file mode 100644 index 759222e58..000000000 --- a/modules/nf-core/bcftools/merge/tests/vcf.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = '--output-type v --no-version' -} diff --git a/modules/nf-core/bcftools/merge/tests/vcf_gz.config b/modules/nf-core/bcftools/merge/tests/vcf_gz.config deleted file mode 100644 index 8b6ad8b4f..000000000 --- a/modules/nf-core/bcftools/merge/tests/vcf_gz.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = '--output-type z --no-version' -} diff --git a/modules/nf-core/bcftools/norm/environment.yml b/modules/nf-core/bcftools/norm/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/norm/environment.yml +++ b/modules/nf-core/bcftools/norm/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/norm/main.nf b/modules/nf-core/bcftools/norm/main.nf index bd7a25012..443c8bbbc 100644 --- a/modules/nf-core/bcftools/norm/main.nf +++ b/modules/nf-core/bcftools/norm/main.nf @@ -1,11 +1,11 @@ process BCFTOOLS_NORM { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf), path(tbi) @@ -13,9 +13,9 @@ process BCFTOOLS_NORM { output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi, optional: true - tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -23,48 +23,49 @@ process BCFTOOLS_NORM { script: def args = task.ext.args ?: '--output-type z' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf.gz" - + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf.gz" """ bcftools norm \\ --fasta-ref ${fasta} \\ --output ${prefix}.${extension} \\ - $args \\ - --threads $task.cpus \\ + ${args} \\ + --threads ${task.cpus} \\ ${vcf} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ stub: def args = task.ext.args ?: '--output-type z' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf.gz" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf.gz" + def index = '' + if (extension in ['vcf.gz', 'bcf', 'bcf.gz']) { + if (['--write-index=tbi', '-W=tbi'].any { arg -> args.contains(arg) } && extension == 'vcf.gz') { + index = 'tbi' + } + else if (['--write-index=tbi', '-W=tbi', '--write-index=csi', '-W=csi', '--write-index', '-W'].any { arg -> args.contains(arg) }) { + index = 'csi' + } + } def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" - def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" - + def create_index = index ? "touch ${prefix}.${extension}.${index}" : "" """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/norm/meta.yml b/modules/nf-core/bcftools/norm/meta.yml index b6edeb4aa..9feecac0d 100644 --- a/modules/nf-core/bcftools/norm/meta.yml +++ b/modules/nf-core/bcftools/norm/meta.yml @@ -26,11 +26,13 @@ input: The vcf file to be normalized e.g. 'file1.vcf' pattern: "*.{vcf,vcf.gz}" + ontologies: [] - tbi: type: file description: | An optional index of the VCF file (for when the VCF is compressed) pattern: "*.vcf.gz.tbi" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +42,10 @@ input: type: file description: FASTA reference file pattern: "*.{fasta,fa}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -52,8 +55,9 @@ output: description: One of uncompressed VCF (.vcf), compressed VCF (.vcf.gz), compressed BCF (.bcf.gz) or uncompressed BCF (.bcf) normalized output file pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -62,8 +66,9 @@ output: type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -72,11 +77,28 @@ output: type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@abhi18av" - "@ramprasadn" diff --git a/modules/nf-core/bcftools/norm/tests/main.nf.test b/modules/nf-core/bcftools/norm/tests/main.nf.test index dbc415023..058517530 100644 --- a/modules/nf-core/bcftools/norm/tests/main.nf.test +++ b/modules/nf-core/bcftools/norm/tests/main.nf.test @@ -35,7 +35,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index") { @@ -68,7 +67,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_csi") { @@ -101,7 +99,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_tbi") { @@ -134,7 +131,6 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } test("sarscov2 - [ vcf, tbi ], fasta") { @@ -163,7 +159,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - vcf output") { @@ -192,7 +187,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - vcf_gz output") { @@ -222,11 +216,10 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - bcf output") { @@ -255,7 +248,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - bcf_gz output") { @@ -284,7 +276,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, [] ], fasta - stub") { @@ -314,7 +305,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta -stub") { @@ -344,7 +334,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - vcf output -stub") { @@ -374,7 +363,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - vcf_gz output - stub") { @@ -403,7 +391,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - bcf output - stub") { @@ -433,7 +420,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, tbi ], fasta - bcf_gz output - stub") { @@ -463,7 +449,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index - stub") { @@ -494,7 +479,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_csi - stub") { @@ -525,7 +509,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_tbi - stub") { @@ -556,8 +539,7 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/norm/tests/main.nf.test.snap b/modules/nf-core/bcftools/norm/tests/main.nf.test.snap index 3be52116a..ee2dadf77 100644 --- a/modules/nf-core/bcftools/norm/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/norm/tests/main.nf.test.snap @@ -17,7 +17,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -33,16 +37,20 @@ "test_norm.vcf:md5,63e5adbaf3dd94550e9e3d7935dd28db" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:38:42.639095032" + "timestamp": "2026-01-20T12:09:29.987030961" }, "sarscov2 - [ vcf, [] ], fasta - stub": { "content": [ @@ -62,7 +70,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -78,16 +90,20 @@ "test_norm.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:38:05.448449893" + "timestamp": "2026-01-20T12:09:06.488086505" }, "sarscov2 - [ vcf, tbi ], fasta - vcf output": { "content": [ @@ -107,7 +123,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -123,16 +143,20 @@ "test_norm.vcf:md5,63e5adbaf3dd94550e9e3d7935dd28db" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:37:12.741719961" + "timestamp": "2026-01-20T12:08:34.863776359" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index - stub": { "content": [ @@ -157,7 +181,11 @@ ] ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -178,16 +206,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:39:22.875147941" + "timestamp": "2026-01-20T12:09:54.718705045" }, "sarscov2 - [ vcf, tbi ], fasta - vcf_gz output": { "content": [ @@ -205,15 +237,21 @@ [ ], - [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T08:15:23.38765384" + "timestamp": "2026-01-20T12:08:43.007377633" }, "sarscov2 - [ vcf, [] ], fasta": { "content": [ @@ -233,7 +271,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -249,16 +291,20 @@ "test_norm.vcf.gz:md5,63e5adbaf3dd94550e9e3d7935dd28db" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:36:21.519977754" + "timestamp": "2026-01-20T12:07:54.877084219" }, "sarscov2 - [ vcf, tbi ], fasta - vcf output -stub": { "content": [ @@ -278,7 +324,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -294,16 +344,20 @@ "test_norm.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:38:27.8230994" + "timestamp": "2026-01-20T12:09:22.220435939" }, "sarscov2 - [ vcf, tbi ], fasta - bcf_gz output": { "content": [ @@ -313,7 +367,7 @@ { "id": "test" }, - "test_norm.bcf:md5,f35545c26a788b5eb697d9c0490339d9" + "test_norm.bcf:md5,bf88706ef69c44ca9e287bc953ba3593" ] ], "1": [ @@ -323,7 +377,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -336,19 +394,23 @@ { "id": "test" }, - "test_norm.bcf:md5,f35545c26a788b5eb697d9c0490339d9" + "test_norm.bcf:md5,bf88706ef69c44ca9e287bc953ba3593" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:37:53.942403192" + "timestamp": "2026-01-20T12:08:58.483532889" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_csi - stub": { "content": [ @@ -373,7 +435,11 @@ ] ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -394,16 +460,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:56:05.3799488" + "timestamp": "2026-01-20T12:10:03.22576704" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_tbi": { "content": [ @@ -443,7 +513,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -459,16 +533,20 @@ "test_norm.vcf.gz:md5,63e5adbaf3dd94550e9e3d7935dd28db" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:36:58.39445154" + "timestamp": "2026-01-20T12:08:27.281315407" }, "sarscov2 - [ vcf, tbi ], fasta -stub": { "content": [ @@ -488,7 +566,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -504,16 +586,20 @@ "test_norm.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:38:16.259516142" + "timestamp": "2026-01-20T12:09:14.249715835" }, "sarscov2 - [ vcf, tbi ], fasta - bcf_gz output - stub": { "content": [ @@ -533,7 +619,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -549,16 +639,20 @@ "test_norm.bcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:39:10.503208929" + "timestamp": "2026-01-20T12:09:46.665932019" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index": { "content": [ @@ -603,7 +697,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -619,16 +717,20 @@ "test_norm.bcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:38:59.121377258" + "timestamp": "2026-01-20T12:09:38.144449162" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_tbi - stub": { "content": [ @@ -653,7 +755,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -674,16 +780,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T13:56:16.404380471" + "timestamp": "2026-01-20T12:10:10.602984345" }, "sarscov2 - [ vcf, [] ], fasta - vcf_gz_index_csi": { "content": [ @@ -728,7 +838,11 @@ ], "3": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ], "csi": [ @@ -744,15 +858,19 @@ "test_norm.bcf.gz:md5,638c3c25bdd495c90ecbccb69ee77f07" ] ], - "versions": [ - "versions.yml:md5,ff760495922469e56d0fc3372773000d" + "versions_bcftools": [ + [ + "BCFTOOLS_NORM", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T14:37:42.141945244" + "timestamp": "2026-01-20T12:08:51.053195842" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/norm/tests/tags.yml b/modules/nf-core/bcftools/norm/tests/tags.yml deleted file mode 100644 index f6f5e3561..000000000 --- a/modules/nf-core/bcftools/norm/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/norm: - - "modules/nf-core/bcftools/norm/**" diff --git a/modules/nf-core/bcftools/pluginsetgt/environment.yml b/modules/nf-core/bcftools/pluginsetgt/environment.yml new file mode 100644 index 000000000..ba863b388 --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/pluginsetgt/main.nf b/modules/nf-core/bcftools/pluginsetgt/main.nf new file mode 100644 index 000000000..5516d7375 --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/main.nf @@ -0,0 +1,80 @@ +process BCFTOOLS_PLUGINSETGT { + tag "${meta.id}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" + + input: + tuple val(meta), path(vcf), path(index) + val target_gt + val new_gt + path regions + path targets + + output: + tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf + tuple val(meta), path("*.tbi"), emit: tbi, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def regions_file = regions ? "--regions-file ${regions}" : "" + def targets_file = targets ? "--targets-file ${targets}" : "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + """ + bcftools plugin setGT \\ + --output ${prefix}.${extension} \\ + ${regions_file} \\ + ${targets_file} \\ + ${args} \\ + --threads ${task.cpus} \\ + ${vcf} \\ + -- \\ + --target-gt ${target_gt} \\ + --new-gt ${new_gt} \\ + ${args2} + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def stub_index = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" + def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" + def create_index = extension.endsWith(".gz") && stub_index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${stub_index}" : "" + """ + ${create_cmd} ${prefix}.${extension} + ${create_index} + """ +} diff --git a/modules/nf-core/bcftools/pluginsetgt/meta.yml b/modules/nf-core/bcftools/pluginsetgt/meta.yml new file mode 100644 index 000000000..51233bc83 --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/meta.yml @@ -0,0 +1,133 @@ +name: "bcftools_pluginsetgt" +description: Sets genotypes according to the specified criteria and filtering expressions. + For example, missing genotypes can be set to ref, but much more than that. +keywords: + - setgt + - bcftools + - genotype + - vcf +tools: + - "bcftools": + description: "BCFtools is a set of utilities that manipulate variant calls in + the Variant Call Format (VCF) and its binary counterpart BCF. All commands work + transparently with both VCFs and BCFs, both uncompressed and BGZF-compressed.\ + \ Most commands accept VCF, bgzipped VCF and BCF with filetype detected automatically + even when streaming from a pipe. Indexed VCF and BCF will work in all situations. + Un-indexed VCF and BCF and streams will work in most, but not all situations." + homepage: "https://samtools.github.io/bcftools/howtos/index.html" + documentation: "https://samtools.github.io/bcftools/bcftools.html" + tool_dev_url: "https://github.com/samtools/bcftools" + doi: "10.1093/bioinformatics/btp352" + licence: ["MIT"] + args_id: "$args" + identifier: biotools:bcftools + - "bcftools plugin setGT": + description: "Bcftools plugins are tools that can be used with bcftools to manipulate + variant calls in Variant Call Format (VCF) and BCF. The setGT plugin sets genotypes + according to the specified criteria and filtering expressions. For example, + missing genotypes can be set to ref, but much more than that." + homepage: "https://samtools.github.io/bcftools/howtos/plugins.html" + documentation: "https://samtools.github.io/bcftools/howtos/plugin.setGT.html" + tool_dev_url: "https://github.com/samtools/bcftools" + doi: "10.1093/bioinformatics/btp352" + licence: ["MIT"] + args_id: "$args2" + identifier: biotools:bcftools + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: | + The vcf file to be inspected. + e.g. 'file.vcf' + ontologies: [] + - index: + type: file + description: | + The tab index for the VCF file to be inspected. + e.g. 'file.tbi' + ontologies: [] + - target_gt: + type: string + description: | + Genotypes to change + - new_gt: + type: string + description: | + Genotypes to set + - regions: + type: file + description: | + Optionally, restrict the operation to regions listed in this file. + e.g. 'file.vcf' + ontologies: [] + - targets: + type: file + description: | + Optionally, restrict the operation to regions listed in this file (doesn't rely upon index files) + e.g. 'file.vcf' + ontologies: [] +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.{vcf,vcf.gz,bcf,bcf.gz}": + type: file + description: VCF output file containing set genotypes + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: [] + tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.tbi": + type: file + description: Alternative VCF file index + pattern: "*.tbi" + ontologies: [] + csi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.csi": + type: file + description: Default VCF file index + pattern: "*.csi" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +authors: + - "@eweizy" +maintainers: + - "@eweizy" diff --git a/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test b/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test new file mode 100644 index 000000000..b4f7ffa04 --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test @@ -0,0 +1,298 @@ +nextflow_process { + + name "Test Process BCFTOOLS_PLUGINSETGT" + script "../main.nf" + process "BCFTOOLS_PLUGINSETGT" + + tag "modules" + tag "modules_nfcore" + tag "bcftools" + tag "bcftools/pluginsetgt" + + test("sarscov2 - [vcf, tbi], [], []") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index") { + + config "./vcf_gz_index.config" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi") { + + config "./vcf_gz_index_csi.config" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi") { + + config "./vcf_gz_index_tbi.config" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, + { assert process.out.tbi[0][1].endsWith(".tbi") } + ) + } + } + + test("sarscov2 - [vcf, tbi], vcf, tsv, []") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test3.vcf.gz', checkIfExists: true) + input[4] = file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.targets.tsv.gz', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - stub") { + + config "./nextflow.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.vcf[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index - stub") { + + config "./vcf_gz_index.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi - stub") { + + config "./vcf_gz_index_csi.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + } + + test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi - stub") { + + config "./vcf_gz_index_tbi.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'out', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = "a" + input[2] = "p" + input[3] = [] + input[4] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.tbi[0][1].endsWith(".tbi") } + ) + } + } +} diff --git a/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test.snap b/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test.snap new file mode 100644 index 000000000..b1e83501a --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/tests/main.nf.test.snap @@ -0,0 +1,393 @@ +{ + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi - stub": { + "content": [ + { + "0": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ], + "csi": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + + ], + "vcf": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:37.442607574" + }, + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi": { + "content": [ + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,9fb75c9fdb304b49c3895476666a85bb" + ] + ], + [ + + ], + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.tbi" + ] + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:06.297712936" + }, + "sarscov2 - [vcf, tbi], [], []": { + "content": [ + [ + [ + { + "id": "out", + "single_end": false + }, + "out.vcf:md5,9fb75c9fdb304b49c3895476666a85bb" + ] + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:13:42.984688381" + }, + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ], + "csi": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + + ], + "vcf": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:30.014429156" + }, + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi - stub": { + "content": [ + { + "0": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ], + "csi": [ + + ], + "tbi": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:45.443617875" + }, + "sarscov2 - [vcf, tbi], vcf, tsv, []": { + "content": [ + [ + [ + { + "id": "out", + "single_end": false + }, + "out.vcf:md5,55e955c359bf9094bb692660f3c1c677" + ] + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:14.614556139" + }, + "sarscov2 - [vcf, tbi], [], [], [] - stub": { + "content": [ + "out.vcf", + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:14:21.981644974" + }, + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index": { + "content": [ + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,9fb75c9fdb304b49c3895476666a85bb" + ] + ], + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi" + ] + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:13:51.040151596" + }, + "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi": { + "content": [ + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz:md5,9fb75c9fdb304b49c3895476666a85bb" + ] + ], + [ + [ + { + "id": "out", + "single_end": false + }, + "out_vcf.vcf.gz.csi" + ] + ], + [ + + ], + { + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINSETGT", + "bcftools", + "1.22" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-20T12:13:58.936771199" + } +} \ No newline at end of file diff --git a/modules/nf-core/bcftools/pluginsetgt/tests/nextflow.config b/modules/nf-core/bcftools/pluginsetgt/tests/nextflow.config new file mode 100644 index 000000000..eb8000d60 --- /dev/null +++ b/modules/nf-core/bcftools/pluginsetgt/tests/nextflow.config @@ -0,0 +1,4 @@ +process { + ext.args = '--no-version --output-type v' + ext.args2 = "-s 42" +} diff --git a/modules/nf-core/bcftools/merge/tests/vcf_gz_index.config b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index.config similarity index 53% rename from modules/nf-core/bcftools/merge/tests/vcf_gz_index.config rename to modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index.config index 9f1e9b1d8..9507854d7 100644 --- a/modules/nf-core/bcftools/merge/tests/vcf_gz_index.config +++ b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index.config @@ -1,3 +1,5 @@ process { + ext.prefix = { "${meta.id}_vcf" } ext.args = "--output-type z --write-index --no-version" + ext.args2 = "-s 42" } diff --git a/modules/nf-core/bcftools/merge/tests/vcf_gz_index_csi.config b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_csi.config similarity index 55% rename from modules/nf-core/bcftools/merge/tests/vcf_gz_index_csi.config rename to modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_csi.config index 8308ee1ae..9e53fe259 100644 --- a/modules/nf-core/bcftools/merge/tests/vcf_gz_index_csi.config +++ b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_csi.config @@ -1,3 +1,5 @@ process { + ext.prefix = { "${meta.id}_vcf" } ext.args = "--output-type z --write-index=csi --no-version" + ext.args2 = "-s 42" } diff --git a/modules/nf-core/bcftools/merge/tests/vcf_gz_index_tbi.config b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_tbi.config similarity index 55% rename from modules/nf-core/bcftools/merge/tests/vcf_gz_index_tbi.config rename to modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_tbi.config index 9be4075bc..38abb7860 100644 --- a/modules/nf-core/bcftools/merge/tests/vcf_gz_index_tbi.config +++ b/modules/nf-core/bcftools/pluginsetgt/tests/vcf_gz_index_tbi.config @@ -1,3 +1,5 @@ process { + ext.prefix = { "${meta.id}_vcf" } ext.args = "--output-type z --write-index=tbi --no-version" + ext.args2 = "-s 42" } diff --git a/modules/nf-core/bcftools/reheader/environment.yml b/modules/nf-core/bcftools/reheader/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/reheader/environment.yml +++ b/modules/nf-core/bcftools/reheader/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/reheader/main.nf b/modules/nf-core/bcftools/reheader/main.nf index 9cf6d0d38..443cb4756 100644 --- a/modules/nf-core/bcftools/reheader/main.nf +++ b/modules/nf-core/bcftools/reheader/main.nf @@ -1,11 +1,11 @@ process BCFTOOLS_REHEADER { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf), path(header), path(samples) @@ -13,8 +13,8 @@ process BCFTOOLS_REHEADER { output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - tuple val(meta), path("*.{csi,tbi}") , emit: index, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.{csi,tbi}"), emit: index, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -22,58 +22,59 @@ process BCFTOOLS_REHEADER { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def fai_argument = fai ? "--fai $fai" : "" - def header_argument = header ? "--header $header" : "" - def samples_argument = samples ? "--samples $samples" : "" + def fai_argument = fai ? "--fai ${fai}" : "" + def header_argument = header ? "--header ${header}" : "" + def samples_argument = samples ? "--samples ${samples}" : "" def args2 = task.ext.args2 ?: '--output-type z' - def extension = args2.contains("--output-type b") || args2.contains("-Ob") ? "bcf.gz" : - args2.contains("--output-type u") || args2.contains("-Ou") ? "bcf" : - args2.contains("--output-type z") || args2.contains("-Oz") ? "vcf.gz" : - args2.contains("--output-type v") || args2.contains("-Ov") ? "vcf" : - "vcf" + def extension = args2.contains("--output-type b") || args2.contains("-Ob") + ? "bcf.gz" + : args2.contains("--output-type u") || args2.contains("-Ou") + ? "bcf" + : args2.contains("--output-type z") || args2.contains("-Oz") + ? "vcf.gz" + : args2.contains("--output-type v") || args2.contains("-Ov") + ? "vcf" + : "vcf" """ bcftools \\ reheader \\ - $fai_argument \\ - $header_argument \\ - $samples_argument \\ - $args \\ - --threads $task.cpus \\ - $vcf \\ + ${fai_argument} \\ + ${header_argument} \\ + ${samples_argument} \\ + ${args} \\ + --threads ${task.cpus} \\ + ${vcf} \\ | bcftools view \\ - $args2 \\ + ${args2} \\ --output ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ stub: def args2 = task.ext.args2 ?: '--output-type z' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args2.contains("--output-type b") || args2.contains("-Ob") ? "bcf.gz" : - args2.contains("--output-type u") || args2.contains("-Ou") ? "bcf" : - args2.contains("--output-type z") || args2.contains("-Oz") ? "vcf.gz" : - args2.contains("--output-type v") || args2.contains("-Ov") ? "vcf" : - "vcf" - def index = args2.contains("--write-index=tbi") || args2.contains("-W=tbi") ? "tbi" : - args2.contains("--write-index=csi") || args2.contains("-W=csi") ? "csi" : - args2.contains("--write-index") || args2.contains("-W") ? "csi" : - "" + def extension = args2.contains("--output-type b") || args2.contains("-Ob") + ? "bcf.gz" + : args2.contains("--output-type u") || args2.contains("-Ou") + ? "bcf" + : args2.contains("--output-type z") || args2.contains("-Oz") + ? "vcf.gz" + : args2.contains("--output-type v") || args2.contains("-Ov") + ? "vcf" + : "vcf" + def index = args2.contains("--write-index=tbi") || args2.contains("-W=tbi") + ? "tbi" + : args2.contains("--write-index=csi") || args2.contains("-W=csi") + ? "csi" + : args2.contains("--write-index") || args2.contains("-W") + ? "csi" + : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/reheader/meta.yml b/modules/nf-core/bcftools/reheader/meta.yml index 47e5344cd..77d3e96b1 100644 --- a/modules/nf-core/bcftools/reheader/meta.yml +++ b/modules/nf-core/bcftools/reheader/meta.yml @@ -23,14 +23,17 @@ input: type: file description: VCF/BCF file pattern: "*.{vcf.gz,vcf,bcf}" + ontologies: [] - header: type: file description: New header to add to the VCF pattern: "*.{header.txt}" + ontologies: [] - samples: type: file description: File containing sample names to update (one sample per line) pattern: "*.{samples.txt}" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +43,10 @@ input: type: file description: Fasta index to update header sequences with pattern: "*.{fai}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,8 +55,9 @@ output: type: file description: VCF with updated header, bgzipped per default pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" - - index: - - meta: + ontologies: [] + index: + - - meta: type: map description: | Groovy Map containing sample information @@ -61,11 +66,28 @@ output: type: file description: Index of VCF with updated header pattern: "*.{csi,tbi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@bjohnnyd" - "@jemten" diff --git a/modules/nf-core/bcftools/reheader/tests/bcf.config b/modules/nf-core/bcftools/reheader/tests/bcf.config index 2b7dff551..05ef8990f 100644 --- a/modules/nf-core/bcftools/reheader/tests/bcf.config +++ b/modules/nf-core/bcftools/reheader/tests/bcf.config @@ -1,4 +1,4 @@ process { ext.args2 = { "--no-version --output-type b" } ext.prefix = "tested" -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/reheader/tests/main.nf.test b/modules/nf-core/bcftools/reheader/tests/main.nf.test index 96c1b7b0e..6d557bdbe 100644 --- a/modules/nf-core/bcftools/reheader/tests/main.nf.test +++ b/modules/nf-core/bcftools/reheader/tests/main.nf.test @@ -35,7 +35,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output") { @@ -65,7 +64,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - index") { @@ -95,12 +93,11 @@ nextflow_process { { assert snapshot( process.out.vcf, process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.index[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - csi index") { @@ -130,12 +127,11 @@ nextflow_process { { assert snapshot( process.out.vcf, process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.index[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - tbi index") { @@ -165,12 +161,11 @@ nextflow_process { { assert snapshot( process.out.vcf, process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.index[0][1].endsWith(".tbi") } ) } - } test("sarscov2 - [vcf, [], []], fai - bcf output") { @@ -200,7 +195,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, header, []], []") { @@ -230,7 +224,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], samples], fai") { @@ -262,7 +255,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - stub") { @@ -292,11 +284,10 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.vcf[0][1]).name, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - index -stub") { @@ -326,7 +317,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - csi index -stub") { @@ -357,7 +347,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - [vcf, [], []], fai - vcf.gz output - tbi index -stub") { @@ -388,7 +377,5 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/bcftools/reheader/tests/main.nf.test.snap b/modules/nf-core/bcftools/reheader/tests/main.nf.test.snap index 87a3654a5..ccfd36cad 100644 --- a/modules/nf-core/bcftools/reheader/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/reheader/tests/main.nf.test.snap @@ -19,15 +19,21 @@ "test_vcf.vcf.gz.tbi" ] ], - [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T10:09:05.955833763" + "timestamp": "2026-01-20T12:17:33.223574431" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output - index -stub": { "content": [ @@ -51,7 +57,11 @@ ] ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -71,16 +81,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:52:41.444952182" + "timestamp": "2026-01-20T12:18:06.228305957" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output - tbi index -stub": { "content": [ @@ -104,7 +118,11 @@ ] ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -124,16 +142,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:53:04.314827944" + "timestamp": "2026-01-20T12:18:19.515117697" }, "sarscov2 - [vcf, [], []], fai - vcf output": { "content": [ @@ -151,7 +173,11 @@ ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ @@ -165,16 +191,20 @@ "tested.vcf:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:50:41.983008108" + "timestamp": "2026-01-20T12:17:07.237153461" }, "sarscov2 - [vcf, [], []], fai - bcf output": { "content": [ @@ -192,7 +222,11 @@ ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ @@ -206,16 +240,20 @@ "tested.bcf.gz:md5,c8a304c8d2892039201154153c8cd536" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:51:43.072513252" + "timestamp": "2026-01-20T12:17:39.607699561" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output": { "content": [ @@ -233,7 +271,11 @@ ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ @@ -247,16 +289,20 @@ "tested.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:50:53.055630152" + "timestamp": "2026-01-20T12:17:13.971326724" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output - index": { "content": [ @@ -278,15 +324,21 @@ "test_vcf.vcf.gz.csi" ] ], - [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T10:08:37.999924355" + "timestamp": "2026-01-20T12:17:20.34202516" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output - csi index -stub": { "content": [ @@ -310,7 +362,11 @@ ] ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ [ @@ -330,29 +386,39 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:52:52.512269206" + "timestamp": "2026-01-20T12:18:12.675831882" }, "sarscov2 - [vcf, [], []], fai - stub": { "content": [ "tested.vcf", - [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-31T15:16:36.337112514" + "timestamp": "2026-01-20T12:17:59.535920415" }, "sarscov2 - [vcf, [], []], fai - vcf.gz output - csi index": { "content": [ @@ -374,15 +440,21 @@ "test_vcf.vcf.gz.csi" ] ], - [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T10:08:55.434831174" + "timestamp": "2026-01-20T12:17:26.832291904" }, "sarscov2 - [vcf, [], samples], fai": { "content": [ @@ -400,7 +472,11 @@ ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ @@ -414,16 +490,20 @@ "tested.vcf:md5,c64c373c10b0be24b29d6f18708ec1e8" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:52:12.216002665" + "timestamp": "2026-01-20T12:17:52.840234682" }, "sarscov2 - [vcf, header, []], []": { "content": [ @@ -441,7 +521,11 @@ ], "2": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ], "index": [ @@ -455,15 +539,19 @@ "tested.vcf:md5,3189bc9a720d5d5d3006bf72d91300cb" ] ], - "versions": [ - "versions.yml:md5,486e3d4ebc1dbf5c0a4dfaebae12ea34" + "versions_bcftools": [ + [ + "BCFTOOLS_REHEADER", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-03T09:51:54.062386022" + "timestamp": "2026-01-20T12:17:46.214653984" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/reheader/tests/tags.yml b/modules/nf-core/bcftools/reheader/tests/tags.yml deleted file mode 100644 index c252941e0..000000000 --- a/modules/nf-core/bcftools/reheader/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/reheader: - - modules/nf-core/bcftools/reheader/** diff --git a/modules/nf-core/bcftools/reheader/tests/vcf.config b/modules/nf-core/bcftools/reheader/tests/vcf.config index 820f2ae66..3fed69282 100644 --- a/modules/nf-core/bcftools/reheader/tests/vcf.config +++ b/modules/nf-core/bcftools/reheader/tests/vcf.config @@ -1,4 +1,4 @@ process { ext.args2 = { "--no-version" } ext.prefix = "tested" -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/reheader/tests/vcf.gz.config b/modules/nf-core/bcftools/reheader/tests/vcf.gz.config index c3031c317..abc12ca36 100644 --- a/modules/nf-core/bcftools/reheader/tests/vcf.gz.config +++ b/modules/nf-core/bcftools/reheader/tests/vcf.gz.config @@ -1,4 +1,4 @@ process { ext.args2 = { "--no-version --output-type z" } ext.prefix = "tested" -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/roh/environment.yml b/modules/nf-core/bcftools/roh/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/roh/environment.yml +++ b/modules/nf-core/bcftools/roh/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/roh/main.nf b/modules/nf-core/bcftools/roh/main.nf index ac96eef54..e275d64d5 100644 --- a/modules/nf-core/bcftools/roh/main.nf +++ b/modules/nf-core/bcftools/roh/main.nf @@ -1,11 +1,11 @@ process BCFTOOLS_ROH { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf), path(tbi) @@ -17,45 +17,35 @@ process BCFTOOLS_ROH { output: tuple val(meta), path("*.roh"), emit: roh - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def af_read = af_file ? "--AF-file ${af_file}" : '' - def gen_map = genetic_map ? "--genetic-map ${genetic_map}" : '' - def reg_file = regions_file ? "--regions-file ${regions_file}" : '' - def samp_file = samples_file ? "--samples-file ${samples_file}" : '' - def targ_file = targets_file ? "--targets-file ${targets_file}" : '' + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def af_read = af_file ? "--AF-file ${af_file}" : '' + def gen_map = genetic_map ? "--genetic-map ${genetic_map}" : '' + def reg_file = regions_file ? "--regions-file ${regions_file}" : '' + def samp_file = samples_file ? "--samples-file ${samples_file}" : '' + def targ_file = targets_file ? "--targets-file ${targets_file}" : '' """ bcftools \\ roh \\ - $args \\ - $af_read \\ - $gen_map \\ - $reg_file \\ - $samp_file \\ - $targ_file \\ + ${args} \\ + ${af_read} \\ + ${gen_map} \\ + ${reg_file} \\ + ${samp_file} \\ + ${targ_file} \\ -o ${prefix}.roh \\ - $vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS + ${vcf} """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.roh - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/roh/meta.yml b/modules/nf-core/bcftools/roh/meta.yml index 032148fa4..aada879c9 100644 --- a/modules/nf-core/bcftools/roh/meta.yml +++ b/modules/nf-core/bcftools/roh/meta.yml @@ -25,34 +25,42 @@ input: type: file description: VCF file pattern: "*.{vcf,.vcf.gz}" + ontologies: [] - tbi: type: file description: TBI file patthern: "*.tbi" + ontologies: [] - - af_file: type: file description: "Read allele frequencies from a tab-delimited file containing the columns: CHROM\tPOS\tREF,ALT\tAF." + ontologies: [] - af_file_tbi: type: file description: "tbi index of af_file." - - - genetic_map: - type: file - description: "Genetic map in the format required also by IMPUTE2." - - - regions_file: - type: file - description: "Regions can be specified either on command line or in a VCF, BED, - or tab-delimited file (the default)." - - - samples_file: - type: file - description: "File of sample names to include or exclude if prefixed with '^'." - - - targets_file: - type: file - description: "Targets can be specified either on command line or in a VCF, BED, - or tab-delimited file (the default)." + ontologies: [] + - genetic_map: + type: file + description: "Genetic map in the format required also by IMPUTE2." + ontologies: [] + - regions_file: + type: file + description: "Regions can be specified either on command line or in a VCF, BED, + or tab-delimited file (the default)." + ontologies: [] + - samples_file: + type: file + description: "File of sample names to include or exclude if prefixed with '^'." + ontologies: [] + - targets_file: + type: file + description: "Targets can be specified either on command line or in a VCF, BED, + or tab-delimited file (the default)." + ontologies: [] output: - - roh: - - meta: + roh: + - - meta: type: map description: | Groovy Map containing sample information @@ -62,11 +70,28 @@ output: description: Contains site-specific and/or per-region runs of homo/autozygosity calls. pattern: "*.{roh}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/bcftools/roh/tests/main.nf.test b/modules/nf-core/bcftools/roh/tests/main.nf.test index bb73b80c0..67cd98e53 100644 --- a/modules/nf-core/bcftools/roh/tests/main.nf.test +++ b/modules/nf-core/bcftools/roh/tests/main.nf.test @@ -63,5 +63,4 @@ nextflow_process { ) } } - } diff --git a/modules/nf-core/bcftools/roh/tests/main.nf.test.snap b/modules/nf-core/bcftools/roh/tests/main.nf.test.snap index 3b008a01e..281d96630 100644 --- a/modules/nf-core/bcftools/roh/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/roh/tests/main.nf.test.snap @@ -7,30 +7,38 @@ { "id": "test" }, - "test.roh:md5,853de778be3030754be40e11be0aa557" + "test.roh:md5,a75b347243c2e955ad4203a6be6dc616" ] ], "1": [ - "versions.yml:md5,684b9cddcfaf57299e6e245b12b7d710" + [ + "BCFTOOLS_ROH", + "bcftools", + "1.22" + ] ], "roh": [ [ { "id": "test" }, - "test.roh:md5,853de778be3030754be40e11be0aa557" + "test.roh:md5,a75b347243c2e955ad4203a6be6dc616" ] ], - "versions": [ - "versions.yml:md5,684b9cddcfaf57299e6e245b12b7d710" + "versions_bcftools": [ + [ + "BCFTOOLS_ROH", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T14:19:06.961553" + "timestamp": "2026-01-20T12:18:25.872864592" }, "test-bcftools-roh-stub": { "content": [ @@ -44,7 +52,11 @@ ] ], "1": [ - "versions.yml:md5,684b9cddcfaf57299e6e245b12b7d710" + [ + "BCFTOOLS_ROH", + "bcftools", + "1.22" + ] ], "roh": [ [ @@ -54,15 +66,19 @@ "test.roh:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,684b9cddcfaf57299e6e245b12b7d710" + "versions_bcftools": [ + [ + "BCFTOOLS_ROH", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T14:19:11.161719" + "timestamp": "2026-01-20T12:18:32.403407806" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/sort/environment.yml b/modules/nf-core/bcftools/sort/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/sort/environment.yml +++ b/modules/nf-core/bcftools/sort/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/sort/main.nf b/modules/nf-core/bcftools/sort/main.nf index 7d4c9b8e9..e0dfad2df 100644 --- a/modules/nf-core/bcftools/sort/main.nf +++ b/modules/nf-core/bcftools/sort/main.nf @@ -1,20 +1,20 @@ process BCFTOOLS_SORT { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf) output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi, optional: true - tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -22,49 +22,51 @@ process BCFTOOLS_SORT { script: def args = task.ext.args ?: '--output-type z' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def max_memory = task.memory ? "--max-mem ${task.memory.toUnit('MB') * 0.9}M" : "" """ bcftools \\ sort \\ --output ${prefix}.${extension} \\ --temp-dir . \\ - $args \\ - $vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS + ${max_memory} \\ + ${args} \\ + ${vcf} """ stub: def args = task.ext.args ?: '--output-type z' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/sort/meta.yml b/modules/nf-core/bcftools/sort/meta.yml index f7a6eff17..1c3f2a540 100644 --- a/modules/nf-core/bcftools/sort/meta.yml +++ b/modules/nf-core/bcftools/sort/meta.yml @@ -23,9 +23,10 @@ input: type: file description: The VCF/BCF file to be sorted pattern: "*.{vcf.gz,vcf,bcf}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -34,8 +35,9 @@ output: type: file description: Sorted VCF file pattern: "*.{vcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -44,8 +46,9 @@ output: type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -54,11 +57,28 @@ output: type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@Gwennid" maintainers: diff --git a/modules/nf-core/bcftools/sort/tests/main.nf.test b/modules/nf-core/bcftools/sort/tests/main.nf.test index b9bdd76a0..bda7bacee 100644 --- a/modules/nf-core/bcftools/sort/tests/main.nf.test +++ b/modules/nf-core/bcftools/sort/tests/main.nf.test @@ -27,7 +27,6 @@ nextflow_process { { assert snapshot(process.out).match("vcf") } ) } - } test("sarscov2 - vcf_gz_index") { @@ -52,12 +51,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_csi") { @@ -82,12 +80,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_tbi") { @@ -112,12 +109,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } test("sarscov2 - vcf - stub") { @@ -139,7 +135,6 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } test("sarscov2 - vcf_gz_index - stub") { @@ -165,7 +160,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_csi - stub") { @@ -191,7 +185,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - vcf_gz_index_tbi - stub") { @@ -217,6 +210,5 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/sort/tests/main.nf.test.snap b/modules/nf-core/bcftools/sort/tests/main.nf.test.snap index f38272cb2..9b9e4dc7c 100644 --- a/modules/nf-core/bcftools/sort/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/sort/tests/main.nf.test.snap @@ -22,7 +22,11 @@ ], "3": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ], "csi": [ @@ -43,16 +47,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:06:05.201680777" + "timestamp": "2026-01-20T12:19:24.286732272" }, "vcf": { "content": [ @@ -72,7 +80,11 @@ ], "3": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ], "csi": [ @@ -88,16 +100,20 @@ "test.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:04:43.889971134" + "timestamp": "2026-01-20T12:18:38.783455397" }, "sarscov2 - vcf_gz_index": { "content": [ @@ -120,15 +136,21 @@ [ ], - [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:04:55.385964497" + "timestamp": "2026-01-20T12:18:45.081447395" }, "sarscov2 - vcf_gz_index_csi": { "content": [ @@ -151,15 +173,21 @@ [ ], - [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:05:06.662818922" + "timestamp": "2026-01-20T12:18:51.194304667" }, "sarscov2 - vcf_gz_index - stub": { "content": [ @@ -184,7 +212,11 @@ ] ], "3": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -205,16 +237,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:05:40.012912381" + "timestamp": "2026-01-20T12:19:11.413154111" }, "sarscov2 - vcf_gz_index_csi - stub": { "content": [ @@ -239,7 +275,11 @@ ] ], "3": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -260,16 +300,20 @@ "test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:05:52.405673587" + "timestamp": "2026-01-20T12:19:17.770087535" }, "sarscov2 - vcf - stub": { "content": [ @@ -289,7 +333,11 @@ ], "3": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ], "csi": [ @@ -305,16 +353,20 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:05:29.117946461" + "timestamp": "2026-01-20T12:19:04.409593559" }, "sarscov2 - vcf_gz_index_tbi": { "content": [ @@ -337,14 +389,20 @@ "test_vcf.vcf.gz.tbi" ] ], - [ - "versions.yml:md5,2c9f26ca356ef71199c3a7d1742974cb" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_SORT", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:05:17.217274984" + "timestamp": "2026-01-20T12:18:57.536633502" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/sort/tests/tags.yml b/modules/nf-core/bcftools/sort/tests/tags.yml deleted file mode 100644 index 6e9520dd3..000000000 --- a/modules/nf-core/bcftools/sort/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/sort: - - "modules/nf-core/bcftools/sort/**" diff --git a/modules/nf-core/bcftools/view/environment.yml b/modules/nf-core/bcftools/view/environment.yml index 5c00b116a..ba863b388 100644 --- a/modules/nf-core/bcftools/view/environment.yml +++ b/modules/nf-core/bcftools/view/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::bcftools=1.20 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/bcftools + - bioconda::bcftools=1.22 diff --git a/modules/nf-core/bcftools/view/main.nf b/modules/nf-core/bcftools/view/main.nf index 7fe4303c0..b3fd7b733 100644 --- a/modules/nf-core/bcftools/view/main.nf +++ b/modules/nf-core/bcftools/view/main.nf @@ -1,23 +1,23 @@ process BCFTOOLS_VIEW { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': - 'biocontainers/bcftools:1.20--h8b25389_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/47/474a5ea8dc03366b04df884d89aeacc4f8e6d1ad92266888e7a8e7958d07cde8/data' + : 'community.wave.seqera.io/library/bcftools_htslib:0a3fa2654b52006f'}" input: tuple val(meta), path(vcf), path(index) - path(regions) - path(targets) - path(samples) + path regions + path targets + path samples output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi, optional: true - tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools when: task.ext.when == null || task.ext.when @@ -25,52 +25,52 @@ process BCFTOOLS_VIEW { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def regions_file = regions ? "--regions-file ${regions}" : "" + def regions_file = regions ? "--regions-file ${regions}" : "" def targets_file = targets ? "--targets-file ${targets}" : "" - def samples_file = samples ? "--samples-file ${samples}" : "" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" + def samples_file = samples ? "--samples-file ${samples}" : "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" """ bcftools view \\ --output ${prefix}.${extension} \\ ${regions_file} \\ ${targets_file} \\ ${samples_file} \\ - $args \\ - --threads $task.cpus \\ + ${args} \\ + --threads ${task.cpus} \\ ${vcf} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : - args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : - args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : - args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : - "vcf" - def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : - args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : - args.contains("--write-index") || args.contains("-W") ? "csi" : - "" + def extension = args.contains("--output-type b") || args.contains("-Ob") + ? "bcf.gz" + : args.contains("--output-type u") || args.contains("-Ou") + ? "bcf" + : args.contains("--output-type z") || args.contains("-Oz") + ? "vcf.gz" + : args.contains("--output-type v") || args.contains("-Ov") + ? "vcf" + : "vcf" + def stub_index = args.contains("--write-index=tbi") || args.contains("-W=tbi") + ? "tbi" + : args.contains("--write-index=csi") || args.contains("-W=csi") + ? "csi" + : args.contains("--write-index") || args.contains("-W") + ? "csi" + : "" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" - def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" - + def create_index = extension.endsWith(".gz") && stub_index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${stub_index}" : "" """ ${create_cmd} ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bcftools/view/meta.yml b/modules/nf-core/bcftools/view/meta.yml index aa7785f12..46761894d 100644 --- a/modules/nf-core/bcftools/view/meta.yml +++ b/modules/nf-core/bcftools/view/meta.yml @@ -26,29 +26,34 @@ input: description: | The vcf file to be inspected. e.g. 'file.vcf' + ontologies: [] - index: type: file description: | The tab index for the VCF file to be inspected. e.g. 'file.tbi' - - - regions: - type: file - description: | - Optionally, restrict the operation to regions listed in this file. - e.g. 'file.vcf' - - - targets: - type: file - description: | - Optionally, restrict the operation to regions listed in this file (doesn't rely upon index files) - e.g. 'file.vcf' - - - samples: - type: file - description: | - Optional, file of sample names to be included or excluded. - e.g. 'file.tsv' + ontologies: [] + - regions: + type: file + description: | + Optionally, restrict the operation to regions listed in this file. + e.g. 'file.vcf' + ontologies: [] + - targets: + type: file + description: | + Optionally, restrict the operation to regions listed in this file (doesn't rely upon index files) + e.g. 'file.vcf' + ontologies: [] + - samples: + type: file + description: | + Optional, file of sample names to be included or excluded. + e.g. 'file.tsv' + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -57,8 +62,9 @@ output: type: file description: VCF normalized output file pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -67,8 +73,9 @@ output: type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -77,11 +84,28 @@ output: type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bcftools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bcftools: + type: string + description: The tool name + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: string + description: The command used to generate the version of the tool authors: - "@abhi18av" maintainers: diff --git a/modules/nf-core/bcftools/view/tests/main.nf.test b/modules/nf-core/bcftools/view/tests/main.nf.test index 1e60c50d5..3ed2b90c1 100644 --- a/modules/nf-core/bcftools/view/tests/main.nf.test +++ b/modules/nf-core/bcftools/view/tests/main.nf.test @@ -33,11 +33,10 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.vcf, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index") { @@ -66,12 +65,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi") { @@ -100,12 +98,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi") { @@ -134,12 +131,11 @@ nextflow_process { process.out.vcf, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() }, { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } test("sarscov2 - [vcf, tbi], vcf, tsv, []") { @@ -166,11 +162,10 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.vcf, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - stub") { @@ -198,11 +193,10 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.vcf[0][1]).name, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index - stub") { @@ -232,7 +226,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi - stub") { @@ -262,7 +255,6 @@ nextflow_process { { assert process.out.csi[0][1].endsWith(".csi") } ) } - } test("sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi - stub") { @@ -292,7 +284,5 @@ nextflow_process { { assert process.out.tbi[0][1].endsWith(".tbi") } ) } - } - -} \ No newline at end of file +} diff --git a/modules/nf-core/bcftools/view/tests/main.nf.test.snap b/modules/nf-core/bcftools/view/tests/main.nf.test.snap index fec22e366..92972d192 100644 --- a/modules/nf-core/bcftools/view/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/view/tests/main.nf.test.snap @@ -24,7 +24,11 @@ ] ], "3": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -47,16 +51,20 @@ "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:14:38.717458272" + "timestamp": "2026-01-20T12:21:02.710815567" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi": { "content": [ @@ -81,15 +89,21 @@ "out_vcf.vcf.gz.tbi" ] ], - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:13:44.760671384" + "timestamp": "2026-01-20T12:20:36.071823323" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index - stub": { "content": [ @@ -116,7 +130,11 @@ ] ], "3": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ], "csi": [ [ @@ -139,16 +157,20 @@ "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-04T16:06:21.669668533" + "timestamp": "2026-01-20T12:20:56.054811979" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_tbi - stub": { "content": [ @@ -175,7 +197,11 @@ ], "3": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ], "csi": [ @@ -198,16 +224,20 @@ "out_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:14:53.026083914" + "timestamp": "2026-01-20T12:21:09.229049434" }, "sarscov2 - [vcf, tbi], vcf, tsv, []": { "content": [ @@ -220,28 +250,40 @@ "out.vcf:md5,1bcbd0eff25d316ba915d06463aab17b" ] ], - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-31T15:15:14.663512924" + "timestamp": "2026-01-20T12:20:42.68820706" }, "sarscov2 - [vcf, tbi], [], [], [] - stub": { "content": [ "out.vcf", - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-31T15:15:19.723448323" + "timestamp": "2026-01-20T12:20:49.538986405" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index": { "content": [ @@ -266,15 +308,21 @@ [ ], - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T08:24:36.358469315" + "timestamp": "2026-01-20T12:20:22.451426124" }, "sarscov2 - [vcf, tbi], [], [], []": { "content": [ @@ -287,15 +335,21 @@ "out.vcf:md5,8e722884ffb75155212a3fc053918766" ] ], - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-31T15:15:09.588867653" + "timestamp": "2026-01-20T12:20:16.040611233" }, "sarscov2 - [vcf, tbi], [], [], [] - vcf_gz_index_csi": { "content": [ @@ -320,14 +374,20 @@ [ ], - [ - "versions.yml:md5,241125d00357804552689c37bbabe1f5" - ] + { + "versions_bcftools": [ + [ + "BCFTOOLS_VIEW", + "bcftools", + "1.22" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-06-05T12:13:33.834986869" + "timestamp": "2026-01-20T12:20:29.512063514" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/view/tests/tags.yml b/modules/nf-core/bcftools/view/tests/tags.yml deleted file mode 100644 index 43b1f0aa0..000000000 --- a/modules/nf-core/bcftools/view/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bcftools/view: - - "modules/nf-core/bcftools/view/**" diff --git a/modules/nf-core/bedtools/genomecov/environment.yml b/modules/nf-core/bedtools/genomecov/environment.yml index 5683bc05f..45c307b0e 100644 --- a/modules/nf-core/bedtools/genomecov/environment.yml +++ b/modules/nf-core/bedtools/genomecov/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/bedtools/genomecov/main.nf b/modules/nf-core/bedtools/genomecov/main.nf index 35e2ab14b..710da5b47 100644 --- a/modules/nf-core/bedtools/genomecov/main.nf +++ b/modules/nf-core/bedtools/genomecov/main.nf @@ -1,66 +1,57 @@ process BEDTOOLS_GENOMECOV { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/63/6397750e9730a3fbcc5b4c43f14bd141c64c723fd7dad80e47921a68a7c3cd21/data': - 'community.wave.seqera.io/library/bedtools_coreutils:a623c13f66d5262b' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/63/6397750e9730a3fbcc5b4c43f14bd141c64c723fd7dad80e47921a68a7c3cd21/data' + : 'community.wave.seqera.io/library/bedtools_coreutils:a623c13f66d5262b'}" input: tuple val(meta), path(intervals), val(scale) - path sizes - val extension - val sort + path sizes + val extension + val sort output: tuple val(meta), path("*.${extension}"), emit: genomecov - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bedtools'), eval("bedtools --version | sed -e 's/bedtools v//g'"), topic: versions, emit: versions_bedtools when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def args_list = args.tokenize() - args += (scale > 0 && scale != 1) ? " -scale $scale" : "" + args += scale > 0 && scale != 1 ? " -scale ${scale}" : "" if (!args_list.contains('-bg') && (scale > 0 && scale != 1)) { args += " -bg" } // Sorts output file by chromosome and position using additional options for performance and consistency // See https://www.biostars.org/p/66927/ for further details - def buffer = task.memory ? "--buffer-size=${task.memory.toGiga().intdiv(2)}G" : '' - def sort_cmd = sort ? "| LC_ALL=C sort --parallel=$task.cpus $buffer -k1,1 -k2,2n" : '' + def buffer = task.memory ? "--buffer-size=${task.memory.toGiga().intdiv(2)}G" : '' + def sort_cmd = sort ? "| LC_ALL=C sort --parallel=${task.cpus} ${buffer} -k1,1 -k2,2n" : '' def prefix = task.ext.prefix ?: "${meta.id}" if (intervals.name =~ /\.bam/) { """ bedtools \\ genomecov \\ - -ibam $intervals \\ - $args \\ - $sort_cmd \\ + -ibam ${intervals} \\ + ${args} \\ + ${sort_cmd} \\ > ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bedtools: \$(bedtools --version | sed -e "s/bedtools v//g") - END_VERSIONS """ - } else { + } + else { """ bedtools \\ genomecov \\ - -i $intervals \\ - -g $sizes \\ - $args \\ - $sort_cmd \\ + -i ${intervals} \\ + -g ${sizes} \\ + ${args} \\ + ${sort_cmd} \\ > ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bedtools: \$(bedtools --version | sed -e "s/bedtools v//g") - END_VERSIONS """ } @@ -68,10 +59,5 @@ process BEDTOOLS_GENOMECOV { def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bedtools: \$(bedtools --version | sed -e "s/bedtools v//g") - END_VERSIONS """ } diff --git a/modules/nf-core/bedtools/genomecov/meta.yml b/modules/nf-core/bedtools/genomecov/meta.yml index 41b1f8f49..69b911c23 100644 --- a/modules/nf-core/bedtools/genomecov/meta.yml +++ b/modules/nf-core/bedtools/genomecov/meta.yml @@ -24,26 +24,28 @@ input: type: file description: BAM/BED/GFF/VCF pattern: "*.{bam|bed|gff|vcf}" + ontologies: [] - scale: type: integer description: Number containing the scale factor for the output. Set to 1 to disable. Setting to a value other than 1 will also get the -bg bedgraph output format as this is required for this command switch - - - sizes: - type: file - description: Tab-delimited table of chromosome names in the first column and - chromosome sizes in the second column - - - extension: - type: string - description: Extension of the output file (e. g., ".bg", ".bedgraph", ".txt", - ".tab", etc.) It is set arbitrarily by the user and corresponds to the file - format which depends on arguments. - - - sort: - type: boolean - description: Sort the output + - sizes: + type: file + description: Tab-delimited table of chromosome names in the first column and chromosome + sizes in the second column + ontologies: [] + - extension: + type: string + description: Extension of the output file (e. g., ".bg", ".bedgraph", ".txt", + ".tab", etc.) It is set arbitrarily by the user and corresponds to the file + format which depends on arguments. + - sort: + type: boolean + description: Sort the output output: - - genomecov: - - meta: + genomecov: + - - meta: type: map description: | Groovy Map containing sample information @@ -52,11 +54,28 @@ output: type: file description: Computed genome coverage file pattern: "*.${extension}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bedtools: + - - ${task.process}: + type: string + description: The name of the process + - bedtools: + type: string + description: The name of the tool + - "bedtools --version | sed -e 's/bedtools v//g'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bedtools: + type: string + description: The name of the tool + - "bedtools --version | sed -e 's/bedtools v//g'": + type: eval + description: The expression to obtain the version of the tool authors: - "@edmundmiller" - "@sruthipsuresh" diff --git a/modules/nf-core/bedtools/genomecov/tests/main.nf.test.snap b/modules/nf-core/bedtools/genomecov/tests/main.nf.test.snap index da6dbe875..4175ae7c9 100644 --- a/modules/nf-core/bedtools/genomecov/tests/main.nf.test.snap +++ b/modules/nf-core/bedtools/genomecov/tests/main.nf.test.snap @@ -11,7 +11,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -21,16 +25,20 @@ "test.coverage.txt:md5,01291b6e1beab72e046653e709eb0e10" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T11:59:33.898146" + "timestamp": "2026-01-21T11:30:01.187722797" }, "sarscov2 - no scale - stub": { "content": [ @@ -44,7 +52,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -54,16 +66,20 @@ "test.coverage.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T11:59:52.483371" + "timestamp": "2026-01-21T11:30:16.248235814" }, "sarscov2 - scale": { "content": [ @@ -77,7 +93,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -87,16 +107,20 @@ "test.coverage.txt:md5,de3c59c0ea123bcdbbad27bc0a0a601e" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T11:59:43.69501" + "timestamp": "2026-01-21T11:30:08.76325362" }, "sarscov2 - scale - stub": { "content": [ @@ -110,7 +134,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -120,16 +148,20 @@ "test.coverage.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T12:00:09.930036" + "timestamp": "2026-01-21T11:30:32.324649338" }, "sarscov2 - no scale": { "content": [ @@ -143,7 +175,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -153,16 +189,20 @@ "test.coverage.txt:md5,66083198daca6c001d328ba9616e9b53" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T11:59:25.448817" + "timestamp": "2026-01-21T11:29:54.109132031" }, "sarscov2 - dummy sizes - stub": { "content": [ @@ -176,7 +216,11 @@ ] ], "1": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ], "genomecov": [ [ @@ -186,15 +230,19 @@ "test.coverage.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5fd44452613992a6f71f2c73d2e117f2" + "versions_bedtools": [ + [ + "BEDTOOLS_GENOMECOV", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T12:00:01.086433" + "timestamp": "2026-01-21T11:30:23.839839194" } } \ No newline at end of file diff --git a/modules/nf-core/bedtools/genomecov/tests/nextflow.config b/modules/nf-core/bedtools/genomecov/tests/nextflow.config index bdb74ae5a..670ef7fd5 100644 --- a/modules/nf-core/bedtools/genomecov/tests/nextflow.config +++ b/modules/nf-core/bedtools/genomecov/tests/nextflow.config @@ -3,5 +3,5 @@ process { withName: BEDTOOLS_GENOMECOV { ext.prefix = { "${meta.id}.coverage" } } - + } diff --git a/modules/nf-core/bedtools/slop/environment.yml b/modules/nf-core/bedtools/slop/environment.yml index 5683bc05f..45c307b0e 100644 --- a/modules/nf-core/bedtools/slop/environment.yml +++ b/modules/nf-core/bedtools/slop/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/bedtools/slop/main.nf b/modules/nf-core/bedtools/slop/main.nf index e5b8e1ef0..b0e636bf7 100644 --- a/modules/nf-core/bedtools/slop/main.nf +++ b/modules/nf-core/bedtools/slop/main.nf @@ -1,19 +1,19 @@ process BEDTOOLS_SLOP { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_0' : - 'biocontainers/bedtools:2.31.1--hf5e1c6e_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_0' + : 'biocontainers/bedtools:2.31.1--hf5e1c6e_0'}" input: tuple val(meta), path(bed) - path sizes + path sizes output: tuple val(meta), path("*.bed"), emit: bed - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bedtools'), eval("bedtools --version | sed -e 's/bedtools v//g'"), topic: versions, emit: versions_bedtools when: task.ext.when == null || task.ext.when @@ -21,29 +21,21 @@ process BEDTOOLS_SLOP { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - if ("$bed" == "${prefix}.bed") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${bed}" == "${prefix}.bed") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ bedtools \\ slop \\ - -i $bed \\ - -g $sizes \\ - $args \\ + -i ${bed} \\ + -g ${sizes} \\ + ${args} \\ > ${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bedtools: \$(bedtools --version | sed -e "s/bedtools v//g") - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bedtools: \$(bedtools --version | sed -e "s/bedtools v//g") - END_VERSIONS """ } diff --git a/modules/nf-core/bedtools/slop/meta.yml b/modules/nf-core/bedtools/slop/meta.yml index 762db534a..681ee3164 100644 --- a/modules/nf-core/bedtools/slop/meta.yml +++ b/modules/nf-core/bedtools/slop/meta.yml @@ -22,12 +22,14 @@ input: type: file description: Input BED file pattern: "*.{bed}" - - - sizes: - type: file - description: Chromosome sizes file + ontologies: [] + - sizes: + type: file + description: Chromosome sizes file + ontologies: [] output: - - bed: - - meta: + bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -36,11 +38,28 @@ output: type: file description: Slopped BED file pattern: "*.{bed}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bedtools: + - - ${task.process}: + type: string + description: The name of the process + - bedtools: + type: string + description: The name of the tool + - "bedtools --version | sed -e 's/bedtools v//g'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bedtools: + type: string + description: The name of the tool + - "bedtools --version | sed -e 's/bedtools v//g'": + type: eval + description: The expression to obtain the version of the tool authors: - "@edmundmiller" - "@sruthipsuresh" diff --git a/modules/nf-core/bedtools/slop/tests/main.nf.test.snap b/modules/nf-core/bedtools/slop/tests/main.nf.test.snap index 899ac21ba..1da1814d7 100644 --- a/modules/nf-core/bedtools/slop/tests/main.nf.test.snap +++ b/modules/nf-core/bedtools/slop/tests/main.nf.test.snap @@ -11,7 +11,11 @@ ] ], "1": [ - "versions.yml:md5,ee6210f0a2c4a60d9cad324bfe18e0cf" + [ + "BEDTOOLS_SLOP", + "bedtools", + "2.31.1" + ] ], "bed": [ [ @@ -21,15 +25,19 @@ "test_out.bed:md5,4f1d8924925fe5d205c9e1981fe290a4" ] ], - "versions": [ - "versions.yml:md5,ee6210f0a2c4a60d9cad324bfe18e0cf" + "versions_bedtools": [ + [ + "BEDTOOLS_SLOP", + "bedtools", + "2.31.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T13:52:04.945029" + "timestamp": "2026-01-21T11:43:36.722281618" } } \ No newline at end of file diff --git a/modules/nf-core/bwa/index/environment.yml b/modules/nf-core/bwa/index/environment.yml index d8789a209..54e679492 100644 --- a/modules/nf-core/bwa/index/environment.yml +++ b/modules/nf-core/bwa/index/environment.yml @@ -1,5 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda + dependencies: - - bioconda::bwa=0.7.18 + # renovate: datasource=conda depName=bioconda/bwa + - bioconda::bwa=0.7.19 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/bwa/index/main.nf b/modules/nf-core/bwa/index/main.nf index 2e48b6caa..6be2c43b7 100644 --- a/modules/nf-core/bwa/index/main.nf +++ b/modules/nf-core/bwa/index/main.nf @@ -1,18 +1,20 @@ process BWA_INDEX { tag "$fasta" - label 'process_single' + // NOTE requires 5.37N memory where N is the size of the database + // source: https://bio-bwa.sourceforge.net/bwa.shtml#8 + memory { 6.B * fasta.size() } conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bwa:0.7.18--he4a0461_0' : - 'biocontainers/bwa:0.7.18--he4a0461_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d7/d7e24dc1e4d93ca4d3a76a78d4c834a7be3985b0e1e56fddd61662e047863a8a/data' : + 'community.wave.seqera.io/library/bwa_htslib_samtools:83b50ff84ead50d0' }" input: tuple val(meta), path(fasta) output: - tuple val(meta), path(bwa) , emit: index - path "versions.yml" , emit: versions + tuple val(meta), path("bwa"), emit: index + tuple val("${task.process}"), val('bwa'), eval('bwa 2>&1 | sed -n "s/^Version: //p"'), topic: versions, emit: versions_bwa when: task.ext.when == null || task.ext.when @@ -27,27 +29,16 @@ process BWA_INDEX { $args \\ -p bwa/${prefix} \\ $fasta - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${fasta.baseName}" """ mkdir bwa - touch bwa/${prefix}.amb touch bwa/${prefix}.ann touch bwa/${prefix}.bwt touch bwa/${prefix}.pac touch bwa/${prefix}.sa - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwa/index/meta.yml b/modules/nf-core/bwa/index/meta.yml index 4884bca2a..f5bf7f52a 100644 --- a/modules/nf-core/bwa/index/meta.yml +++ b/modules/nf-core/bwa/index/meta.yml @@ -14,7 +14,7 @@ tools: documentation: https://bio-bwa.sourceforge.net/bwa.shtml arxiv: arXiv:1303.3997 licence: ["GPL-3.0-or-later"] - identifier: "" + identifier: "biotools:bwa" input: - - meta: type: map @@ -24,26 +24,48 @@ input: - fasta: type: file description: Input genome fasta file + ontologies: + - edam: "http://edamontology.org/data_2044" # Sequence + - edam: "http://edamontology.org/format_1929" # FASTA output: - - index: - - meta: + index: + - - meta: type: map description: | Groovy Map containing reference information. e.g. [ id:'test', single_end:false ] - bwa: - type: file - description: BWA genome index files + type: map + description: | + Groovy Map containing reference information. + e.g. [ id:'test', single_end:false ] pattern: "*.{amb,ann,bwt,pac,sa}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/data_3210" # Genome index + versions_bwa: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bwa: + type: string + description: The tool name + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bwa: + type: string + description: The tool name + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: string + description: The command used to generate the version of the tool authors: - "@drpatelh" - "@maxulysse" maintainers: - - "@drpatelh" - "@maxulysse" - "@gallvp" diff --git a/modules/nf-core/bwa/index/tests/main.nf.test b/modules/nf-core/bwa/index/tests/main.nf.test index af33e73ca..f0fba82a1 100644 --- a/modules/nf-core/bwa/index/tests/main.nf.test +++ b/modules/nf-core/bwa/index/tests/main.nf.test @@ -22,8 +22,32 @@ nextflow_process { } then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + + test("BWA index - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/bwa/index/tests/main.nf.test.snap b/modules/nf-core/bwa/index/tests/main.nf.test.snap index 7c8f04657..21a6f73c3 100644 --- a/modules/nf-core/bwa/index/tests/main.nf.test.snap +++ b/modules/nf-core/bwa/index/tests/main.nf.test.snap @@ -1,4 +1,57 @@ { + "BWA index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "BWA_INDEX", + "bwa", + "0.7.19-r1273" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_bwa": [ + [ + "BWA_INDEX", + "bwa", + "0.7.19-r1273" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-23T16:58:59.966558606" + }, "BWA index": { "content": [ { @@ -17,7 +70,11 @@ ] ], "1": [ - "versions.yml:md5,a64462ac7dfb21f4ade9b02e7f65c5bb" + [ + "BWA_INDEX", + "bwa", + "0.7.19-r1273" + ] ], "index": [ [ @@ -33,15 +90,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,a64462ac7dfb21f4ade9b02e7f65c5bb" + "versions_bwa": [ + [ + "BWA_INDEX", + "bwa", + "0.7.19-r1273" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-16T11:40:09.925307" + "timestamp": "2026-01-23T16:58:53.330725134" } } \ No newline at end of file diff --git a/modules/nf-core/bwa/index/tests/tags.yml b/modules/nf-core/bwa/index/tests/tags.yml deleted file mode 100644 index 28bb483c4..000000000 --- a/modules/nf-core/bwa/index/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bwa/index: - - modules/nf-core/bwa/index/** diff --git a/modules/nf-core/bwa/mem/environment.yml b/modules/nf-core/bwa/mem/environment.yml index ef7b966c0..54e679492 100644 --- a/modules/nf-core/bwa/mem/environment.yml +++ b/modules/nf-core/bwa/mem/environment.yml @@ -1,8 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bwa=0.7.18 - - htslib=1.20.0 - - samtools=1.20 + # renovate: datasource=conda depName=bioconda/bwa + - bioconda::bwa=0.7.19 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/bwa/mem/main.nf b/modules/nf-core/bwa/mem/main.nf index 9c815f0c8..e3732673e 100644 --- a/modules/nf-core/bwa/mem/main.nf +++ b/modules/nf-core/bwa/mem/main.nf @@ -4,8 +4,8 @@ process BWA_MEM { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-fe8faa35dbf6dc65a0f7f5d4ea12e31a79f73e40:1bd8542a8a0b42e0981337910954371d0230828e-0' : - 'biocontainers/mulled-v2-fe8faa35dbf6dc65a0f7f5d4ea12e31a79f73e40:1bd8542a8a0b42e0981337910954371d0230828e-0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d7/d7e24dc1e4d93ca4d3a76a78d4c834a7be3985b0e1e56fddd61662e047863a8a/data' : + 'community.wave.seqera.io/library/bwa_htslib_samtools:83b50ff84ead50d0' }" input: tuple val(meta) , path(reads) @@ -18,7 +18,8 @@ process BWA_MEM { tuple val(meta), path("*.cram") , emit: cram, optional: true tuple val(meta), path("*.csi") , emit: csi, optional: true tuple val(meta), path("*.crai") , emit: crai, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bwa'), eval('bwa 2>&1 | sed -n "s/^Version: //p"'), topic: versions, emit: versions_bwa + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -44,19 +45,11 @@ process BWA_MEM { \$INDEX \\ $reads \\ | samtools $samtools_command $args2 ${reference} --threads $task.cpus -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: - def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def samtools_command = sort_bam ? 'sort' : 'view' def extension = args2.contains("--output-fmt sam") ? "sam" : args2.contains("--output-fmt cram") ? "cram": sort_bam && args2.contains("-O cram")? "cram": @@ -66,11 +59,5 @@ process BWA_MEM { touch ${prefix}.${extension} touch ${prefix}.csi touch ${prefix}.crai - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwa/mem/meta.yml b/modules/nf-core/bwa/mem/meta.yml index 37467d291..450a3fe99 100644 --- a/modules/nf-core/bwa/mem/meta.yml +++ b/modules/nf-core/bwa/mem/meta.yml @@ -16,8 +16,9 @@ tools: homepage: http://bio-bwa.sourceforge.net/ documentation: https://bio-bwa.sourceforge.net/bwa.shtml arxiv: arXiv:1303.3997 - licence: ["GPL-3.0-or-later"] - identifier: "" + licence: + - "GPL-3.0-or-later" + identifier: "biotools:bwa" input: - - meta: type: map @@ -29,6 +30,9 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1930" - - meta2: type: map description: | @@ -38,6 +42,8 @@ input: type: file description: BWA genome index files pattern: "Directory containing BWA index *.{amb,ann,bwt,pac,sa}" + ontologies: + - edam: "http://edamontology.org/data_3210" - - meta3: type: map description: | @@ -47,52 +53,92 @@ input: type: file description: Reference genome in FASTA format pattern: "*.{fasta,fa}" - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - bam: - - meta: - type: file - description: Output BAM file containing read alignments - pattern: "*.{bam}" + bam: + - - meta: + type: map + description: Groovy Map containing sample information - "*.bam": type: file description: Output BAM file containing read alignments pattern: "*.{bam}" - - cram: - - meta: - type: file - description: Output CRAM file containing read alignments - pattern: "*.{cram}" + ontologies: + - edam: "http://edamontology.org/format_2572" + cram: + - - meta: + type: map + description: Groovy Map containing sample information - "*.cram": type: file description: Output CRAM file containing read alignments pattern: "*.{cram}" - - csi: - - meta: - type: file - description: Optional index file for BAM file - pattern: "*.{csi}" + ontologies: + - edam: "http://edamontology.org/format_3462" + csi: + - - meta: + type: map + description: Groovy Map containing sample information - "*.csi": type: file description: Optional index file for BAM file pattern: "*.{csi}" - - crai: - - meta: - type: file - description: Optional index file for CRAM file - pattern: "*.{crai}" + ontologies: [] + crai: + - - meta: + type: map + description: Groovy Map containing sample information - "*.crai": type: file description: Optional index file for CRAM file pattern: "*.{crai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwa: + - - ${task.process}: + type: string + description: The name of the process + - bwa: + type: string + description: The name of the tool + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwa: + type: string + description: The name of the tool + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@jeremy1805" diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test b/modules/nf-core/bwa/mem/tests/main.nf.test index 5de2c2f45..6486ab000 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test +++ b/modules/nf-core/bwa/mem/tests/main.nf.test @@ -48,8 +48,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -83,8 +82,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -119,8 +117,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -155,8 +152,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -191,8 +187,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test.snap b/modules/nf-core/bwa/mem/tests/main.nf.test.snap index 2079ea224..8aca4b234 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwa/mem/tests/main.nf.test.snap @@ -10,17 +10,29 @@ [ ], - [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" - ], - "b6d9cb250261a4c125413c5d867d87a7", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "798439cbd7fd81cbcc5078022dc5479d" ], + "timestamp": "2026-02-18T12:42:52.901827", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:22:28.051598" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Single-End Sort": { "content": [ @@ -33,17 +45,29 @@ [ ], - [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" - ], - "848434ae4b79cfdcb2281c60b33663ce", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "94fcf617f5b994584c4e8d4044e16b4f" ], + "timestamp": "2026-02-18T12:43:01.149915", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:22:39.671154" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End": { "content": [ @@ -56,17 +80,29 @@ [ ], - [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" - ], - "5b34d31be84478761f789e3e2e805e31", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], + "timestamp": "2026-02-18T12:43:09.528042", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:22:51.919479" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End Sort": { "content": [ @@ -79,17 +115,29 @@ [ ], - [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" - ], - "69003376d9a8952622d8587b39c3eaae", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "af8628d9df18b2d3d4f6fd47ef2bb872" ], + "timestamp": "2026-02-18T12:43:17.876121", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:00.833562" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Single-end - stub": { "content": [ @@ -125,7 +173,18 @@ ] ], "4": [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "5": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ], "bam": [ [ @@ -157,16 +216,27 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-18T12:43:33.853248", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:31:29.46282" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End - no fasta": { "content": [ @@ -179,17 +249,29 @@ [ ], - [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" - ], - "5b34d31be84478761f789e3e2e805e31", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], + "timestamp": "2026-02-18T12:43:26.121474", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:09.942545" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-end - stub": { "content": [ @@ -225,7 +307,18 @@ ] ], "4": [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "5": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ], "bam": [ [ @@ -257,15 +350,26 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,478b816fbd37871f5e8c617833d51d80" + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-18T12:43:42.119907", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:31:37.757037" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/bwa/mem/tests/tags.yml b/modules/nf-core/bwa/mem/tests/tags.yml deleted file mode 100644 index 82992d1f0..000000000 --- a/modules/nf-core/bwa/mem/tests/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -bwa/mem: - - modules/nf-core/bwa/index/** - - modules/nf-core/bwa/mem/** diff --git a/modules/nf-core/bwafastalign/index/environment.yml b/modules/nf-core/bwafastalign/index/environment.yml new file mode 100644 index 000000000..a89afa0a9 --- /dev/null +++ b/modules/nf-core/bwafastalign/index/environment.yml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bwa-fastalign=1.0.0 + - bioconda::mbuffer=20160228 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/bwafastalign/index/main.nf b/modules/nf-core/bwafastalign/index/main.nf new file mode 100644 index 000000000..8bf8d7eb3 --- /dev/null +++ b/modules/nf-core/bwafastalign/index/main.nf @@ -0,0 +1,48 @@ +process BWAFASTALIGN_INDEX { + tag "$fasta" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f8/f8c975324a12014c8a817c2c1ad0cd68b077cf09c4370717589177b262dcd1dc/data': + 'community.wave.seqera.io/library/bwa-fastalign_mbuffer_samtools:35f24ce8addcd26b'}" + + input: + tuple val(meta), path(fasta) + + output: + tuple val(meta), path("bwafastalign"), emit: index + tuple val("${task.process}"), val('bwafastalign'), val('1.0.0'), topic: versions, emit: versions_bwafastalign + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + tuple val("${task.process}"), val('samtools'), eval("samtools --version 2>&1 | sed '1!d;s/.* //'") , topic: versions, emit: versions_samtools + tuple val("${task.process}"), val('mbuffer'), eval("mbuffer --version 2>&1 | sed -n 's/mbuffer //p'") , topic: versions, emit: versions_mbuffer + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${fasta}" + """ + mkdir bwafastalign + + bwa-fastalign index \\ + $args \\ + -p bwafastalign/$prefix \\ + $fasta + """ + + stub: + def prefix = task.ext.prefix ?: "${fasta}" + """ + mkdir bwafastalign + touch bwafastalign/${prefix}.amb + touch bwafastalign/${prefix}.ann + touch bwafastalign/${prefix}.bwt + touch bwafastalign/${prefix}.bytesa + touch bwafastalign/${prefix}.fmt + touch bwafastalign/${prefix}.kmer + touch bwafastalign/${prefix}.pac + touch bwafastalign/${prefix}.sa + """ +} diff --git a/modules/nf-core/bwafastalign/index/meta.yml b/modules/nf-core/bwafastalign/index/meta.yml new file mode 100644 index 000000000..5c2fdbca4 --- /dev/null +++ b/modules/nf-core/bwafastalign/index/meta.yml @@ -0,0 +1,106 @@ +name: "bwafastalign_index" +description: Create BWA-FASTALIGN index for reference genome +keywords: + - index + - fasta + - genome + - reference +tools: + - "bwafastalign": + description: "Faster and Cheaper Sequence Alignment on Commercial CPUs (A faster + version of bwa-mem with identical outputs)." + homepage: "https://github.com/zzhofict/BWA-FastAlign" + documentation: "https://github.com/zzhofict/BWA-FastAlign" + doi: "10.1145/3774934.3786421" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - fasta: + type: file + description: Input genome fasta file + ontologies: [] +output: + index: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - bwafastalign: + type: string + description: BWA-FASTALIGN genome index files + pattern: "*.{0123,amb,ann,pac,pos_packed,suffixarray_uint64,suffixarray_uint64_L0_PARAMETERS,suffixarray_uint64_L1_PARAMETERS,suffixarray_uint64_L2_PARAMETERS}" + ontologies: [] + versions_bwafastalign: + - - ${task.process}: + type: string + description: The name of the process + - bwafastalign: + type: string + description: BWA-FASTALIGN genome index files + pattern: "*.{0123,amb,ann,pac,pos_packed,suffixarray_uint64,suffixarray_uint64_L0_PARAMETERS,suffixarray_uint64_L1_PARAMETERS,suffixarray_uint64_L2_PARAMETERS}" + ontologies: [] + - 1.0.0: + type: string + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools --version 2>&1 | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + versions_mbuffer: + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer //p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwafastalign: + type: string + description: BWA-FASTALIGN genome index files + pattern: "*.{0123,amb,ann,pac,pos_packed,suffixarray_uint64,suffixarray_uint64_L0_PARAMETERS,suffixarray_uint64_L1_PARAMETERS,suffixarray_uint64_L2_PARAMETERS}" + ontologies: [] + - 1.0.0: + type: string + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools --version 2>&1 | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer //p': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@peterpru" +maintainers: + - "@peterpru" diff --git a/modules/nf-core/bwafastalign/index/tests/main.nf.test b/modules/nf-core/bwafastalign/index/tests/main.nf.test new file mode 100644 index 000000000..3173287b8 --- /dev/null +++ b/modules/nf-core/bwafastalign/index/tests/main.nf.test @@ -0,0 +1,64 @@ +nextflow_process { + + name "Test Process BWAFASTALIGN_INDEX" + script "../main.nf" + process "BWAFASTALIGN_INDEX" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "bwafastalign" + tag "bwafastalign/index" + + test("BWAFASTALIGN index") { + + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + // genome.fasta.kmer is a fixed-size ~4.8 GB hash table — snapshot by name only, MD5 all others + { assert snapshot( + new File(process.out.index[0][1].toString()).listFiles() + .sort { it.name } + .collect { f -> f.name.endsWith('.kmer') ? f.name : file(f.absolutePath) }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("BWAFASTALIGN index - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/bwafastalign/index/tests/main.nf.test.snap b/modules/nf-core/bwafastalign/index/tests/main.nf.test.snap new file mode 100644 index 000000000..38524381b --- /dev/null +++ b/modules/nf-core/bwafastalign/index/tests/main.nf.test.snap @@ -0,0 +1,131 @@ +{ + "BWAFASTALIGN index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bytesa:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.fmt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.kmer:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "BWAFASTALIGN_INDEX", + "bwafastalign", + "1.0.0" + ] + ], + "2": [ + [ + "BWAFASTALIGN_INDEX", + "samtools", + "1.21" + ] + ], + "3": [ + [ + "BWAFASTALIGN_INDEX", + "mbuffer", + "version 20160228" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bytesa:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.fmt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.kmer:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_INDEX", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_INDEX", + "mbuffer", + "version 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_INDEX", + "samtools", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.0" + }, + "timestamp": "2026-06-08T12:26:53.94075" + }, + "BWAFASTALIGN index": { + "content": [ + [ + "genome.fasta.amb:md5,3a68b8b2287e07dd3f5f95f4344ba76e", + "genome.fasta.ann:md5,c32e11f6c859f166c7525a9c1d583567", + "genome.fasta.bwt:md5,0469c30a1e239dd08f68afe66fde99da", + "genome.fasta.bytesa:md5,9e4ae311370960b31268a5ef0bde324a", + "genome.fasta.fmt:md5,f993b15dc5f10271f3fa0a68720219b6", + "genome.fasta.kmer", + "genome.fasta.pac:md5,983e3d2cd6f36e2546e6d25a0da78d66", + "genome.fasta.sa:md5,ab3952cabf026b48cd3eb5bccbb636d1" + ], + { + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_INDEX", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_INDEX", + "mbuffer", + "version 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_INDEX", + "samtools", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.0" + }, + "timestamp": "2026-06-08T12:26:41.54578" + } +} \ No newline at end of file diff --git a/modules/nf-core/bwafastalign/index/tests/nextflow.config b/modules/nf-core/bwafastalign/index/tests/nextflow.config new file mode 100644 index 000000000..ffc65676f --- /dev/null +++ b/modules/nf-core/bwafastalign/index/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: BWAFASTALIGN_INDEX { + memory = 15.GB + } +} diff --git a/modules/nf-core/bwafastalign/mem/README.md b/modules/nf-core/bwafastalign/mem/README.md new file mode 100644 index 000000000..f991034a2 --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/README.md @@ -0,0 +1,51 @@ +# bwafastalign/mem options + +bwa-fastalign is a high-throughput aligner that produces alignments faster than samtools can consume them. To prevent bwa-fastalign from stalling while samtools processes data, mbuffer is used as an intermediary to absorb alignments until samtools is ready. The mbuffer and samtools options are configurable via `ext.args2` and `ext.args3` respectively. + +## Configuring mbuffer (`ext.args2`) + +`ext.args2` is passed to mbuffer. The default buffer size is 3GB (`-m 3072M`). If `-m` is not present in `ext.args2`, the default is injected automatically. + +The mbuffer size should match the total memory allocated to `samtools sort` (`-m` × `-@`) so it can absorb bwa-fastalign output while samtools is flushing its sort buffer to disk. + +``` +withName: 'BWAFASTALIGN_MEM' { + ext.args2 = '-m 20480M' // 20GB mbuffer to match samtools sort total (e.g. -m 1024M x -@ 20) +} +``` + +## Configuring samtools (`ext.args3`) + +`ext.args3` is passed to `samtools sort` or `samtools view` depending on the `sort_bam` input. Defaults are injected if not supplied: + +- `-@ 3` (threads) — always injected if `-@` is absent +- `-m 1024M` (memory per thread) — injected if `-m` is absent and `sort_bam` is true + +``` +withName: 'BWAFASTALIGN_MEM' { + ext.args3 = '-@ 20 -m 1024M' // 20 threads, 1GB per thread = 20GB total +} +``` + +## Example: tuning for human genome alignment + +For a large reference (e.g. human genome) on a well-resourced machine, you may want to increase both values. The mbuffer size should equal the total samtools sort memory: + +``` +withName: 'BWAFASTALIGN_MEM' { + ext.args2 = '-m 20480M' // mbuffer = samtools total (20 threads x 1GB) + ext.args3 = '-@ 20 -m 1024M' +} +``` + +## CRAM output + +To produce CRAM output, pass `--output-fmt` via `ext.args3`: + +``` +withName: 'BWAFASTALIGN_MEM' { + ext.args3 = '--output-fmt cram' +} +``` + +A FASTA reference must be provided as `input[2]` when using CRAM output. diff --git a/modules/nf-core/bwafastalign/mem/environment.yml b/modules/nf-core/bwafastalign/mem/environment.yml new file mode 100644 index 000000000..a89afa0a9 --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/environment.yml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bwa-fastalign=1.0.0 + - bioconda::mbuffer=20160228 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/bwafastalign/mem/main.nf b/modules/nf-core/bwafastalign/mem/main.nf new file mode 100644 index 000000000..36bca6fed --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/main.nf @@ -0,0 +1,73 @@ +process BWAFASTALIGN_MEM { + tag "$meta.id" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f8/f8c975324a12014c8a817c2c1ad0cd68b077cf09c4370717589177b262dcd1dc/data': + 'community.wave.seqera.io/library/bwa-fastalign_mbuffer_samtools:35f24ce8addcd26b'}" + + input: + tuple val(meta), path(reads) + tuple val(meta2), path(index) + tuple val(meta3), path(fasta) + val sort_bam + + output: + tuple val(meta), path("${prefix}.{sam,bam,cram}"), emit: output + tuple val(meta), path("${prefix}.{csi,crai}") , emit: index , optional: true + tuple val("${task.process}"), val('bwafastalign'), val('1.0.0'), topic: versions, emit: versions_bwafastalign + tuple val("${task.process}"), val('samtools'), eval("samtools --version 2>&1 | sed '1!d;s/.* //'") , topic: versions, emit: versions_samtools + tuple val("${task.process}"), val('mbuffer'), eval("mbuffer --version 2>&1 | sed -n 's/mbuffer version//p'") , topic: versions, emit: versions_mbuffer + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def args3 = task.ext.args3 ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + + def samtools_command = sort_bam ? 'sort' : 'view' + // ext.args2 controls mbuffer options; inject default -m if not supplied + def mbuffer_args = args2.contains('-m') ? args2 : "-m 3072M ${args2}" + def mbuffer_command = sort_bam ? "| mbuffer ${mbuffer_args}" : "" + // ext.args3 controls samtools options; inject defaults for -@ and -m (sort only) if not supplied + def samtools_threads_arg = args3.contains('-@') ? '' : '-@ 3' + def samtools_mem_arg = (sort_bam && !args3.contains('-m')) ? '-m 1024M' : '' + def samtools_args = "${samtools_mem_arg} ${samtools_threads_arg} ${args3}" + def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ + def extension_matcher = (args3 =~ extension_pattern) + def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" + def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" + if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + """ + INDEX=`find -L ./ -name "*.amb" | sed 's/\\.amb\$//'` + + bwa-fastalign \\ + mem \\ + $args \\ + -t $task.cpus \\ + \$INDEX \\ + $reads \\ + $mbuffer_command \\ + | samtools $samtools_command $samtools_args ${reference} -o ${prefix}.${extension} - + """ + + stub: + + def args3 = task.ext.args3 ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ + def extension_matcher = (args3 =~ extension_pattern) + def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" + if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + + def create_index = extension == "cram" ? "touch ${prefix}.crai" : + extension == "bam" ? "touch ${prefix}.csi" : "" + """ + touch ${prefix}.${extension} + ${create_index} + """ +} diff --git a/modules/nf-core/bwafastalign/mem/meta.yml b/modules/nf-core/bwafastalign/mem/meta.yml new file mode 100644 index 000000000..0a6dfe042 --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/meta.yml @@ -0,0 +1,144 @@ +name: "bwafastalign_mem" +description: Performs fastq alignment to a fasta reference using BWA-FastAlign. +keywords: + - mem + - bwa + - bwafastalign + - alignment + - map + - fastq + - bam + - sam + - cram +tools: + - "bwafastalign": + description: "Faster and Cheaper Sequence Alignment on Commercial CPUs (A faster + version of bwa-mem with identical outputs)." + homepage: "https://github.com/zzhofict/BWA-FastAlign" + documentation: "https://github.com/zzhofict/BWA-FastAlign" + doi: "10.1145/3774934.3786421" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference/index information + e.g. [ id:'test' ] + - index: + type: file + description: BWA genome index files + pattern: "Directory containing BWA index *.{0132,amb,ann,bwt.2bit.64,pac}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Reference genome in FASTA format + pattern: "*.{fa,fasta,fna}" + ontologies: [] + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" +output: + output: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.{sam,bam,cram}: + type: file + description: Output alignment file (SAM, BAM, or CRAM) + pattern: "*.{sam,bam,cram}" + ontologies: [] + index: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.{csi,crai}: + type: file + description: Index file for BAM (.csi) or CRAM (.crai) output + pattern: "*.{csi,crai}" + ontologies: [] + versions_bwafastalign: + - - ${task.process}: + type: string + description: The name of the process + - bwafastalign: + type: string + description: The name of the tool + - 1.0.0: + type: string + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: Name of the tool + - samtools --version 2>&1 | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + versions_mbuffer: + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer version//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwafastalign: + type: string + description: The name of the tool + - 1.0.0: + type: string + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: Name of the tool + - samtools --version 2>&1 | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer version//p': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@peterpru" +maintainers: + - "@peterpru" diff --git a/modules/nf-core/bwafastalign/mem/tests/main.nf.test b/modules/nf-core/bwafastalign/mem/tests/main.nf.test new file mode 100644 index 000000000..83fef0386 --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/tests/main.nf.test @@ -0,0 +1,204 @@ +nextflow_process { + + name "Test Process BWAFASTALIGN_MEM" + script "../main.nf" + process "BWAFASTALIGN_MEM" + + tag "modules" + tag "modules_nfcore" + tag "bwafastalign" + tag "bwafastalign/mem" + tag "bwafastalign/index" + config "./nextflow.config" + + setup { + run("BWAFASTALIGN_INDEX") { + script "../../index/main.nf" + config "./nextflow.config" + process { + """ + input[0] = Channel.of([ + [:], // meta map + [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + ]) + """ + } + } + } + + test("sarscov2 - fastq, index, fasta, false") { + + when { + params { + module_args2 = "" + module_args3 = "" + } + + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, true") { + + when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, false") { + + when { + params { + module_args2 = "" + module_args3 = "" + } + + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, true") { + + when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, true - stub") { + + options "-stub" + when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } +} diff --git a/modules/nf-core/bwafastalign/mem/tests/main.nf.test.snap b/modules/nf-core/bwafastalign/mem/tests/main.nf.test.snap new file mode 100644 index 000000000..c3064b6ff --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/tests/main.nf.test.snap @@ -0,0 +1,227 @@ +{ + "sarscov2 - [fastq1, fastq2], index, fasta, false": { + "content": [ + "49bb35727c1eec2fc59473c0cf26c09c", + "57aeef88ed701a8ebc8e2f0a381b2a6", + { + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:29:18.833924106", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "3": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ], + "4": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "index": [ + [ + { + "id": "test", + "single_end": false + }, + "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "output": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:32:15.456124051", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - [fastq1, fastq2], index, fasta, true": { + "content": [ + "ff9384834da1473da24b9e75718695f8", + "af8628d9df18b2d3d4f6fd47ef2bb872", + { + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:32:05.037964846", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq, index, fasta, false": { + "content": [ + "8f2ce115e2c6aabbd963c5375dc4637a", + "798439cbd7fd81cbcc5078022dc5479d", + { + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:23:56.737918563", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq, index, fasta, true": { + "content": [ + "bf990ba932129f47990a9a9f98c30038", + "94fcf617f5b994584c4e8d4044e16b4f", + { + "versions_bwafastalign": [ + [ + "BWAFASTALIGN_MEM", + "bwafastalign", + "1.0.0" + ] + ], + "versions_mbuffer": [ + [ + "BWAFASTALIGN_MEM", + "mbuffer", + " 20160228" + ] + ], + "versions_samtools": [ + [ + "BWAFASTALIGN_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:26:37.839861629", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/bwafastalign/mem/tests/nextflow.config b/modules/nf-core/bwafastalign/mem/tests/nextflow.config new file mode 100644 index 000000000..fc560b4f6 --- /dev/null +++ b/modules/nf-core/bwafastalign/mem/tests/nextflow.config @@ -0,0 +1,9 @@ +process { + withName: 'BWAFASTALIGN.*' { + memory = 15.GB + } + withName: 'BWAFASTALIGN_MEM' { + ext.args2 = { params.module_args2 } + ext.args3 = { params.module_args3 } + } +} diff --git a/modules/nf-core/bwamem2/index/environment.yml b/modules/nf-core/bwamem2/index/environment.yml index 15cee2387..f3637444a 100644 --- a/modules/nf-core/bwamem2/index/environment.yml +++ b/modules/nf-core/bwamem2/index/environment.yml @@ -1,5 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda + dependencies: - - bioconda::bwa-mem2=2.2.1 + # renovate: datasource=conda depName=bioconda/bwa-mem2 + - bwa-mem2=2.3 + # renovate: datasource=conda depName=bioconda/htslib + - htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - samtools=1.22.1 diff --git a/modules/nf-core/bwamem2/index/main.nf b/modules/nf-core/bwamem2/index/main.nf index b7688285d..cb2c4bb2f 100644 --- a/modules/nf-core/bwamem2/index/main.nf +++ b/modules/nf-core/bwamem2/index/main.nf @@ -1,18 +1,20 @@ process BWAMEM2_INDEX { tag "$fasta" - label 'process_single' + // NOTE Requires 28N GB memory where N is the size of the reference sequence, floor of 280M + // source: https://github.com/bwa-mem2/bwa-mem2/issues/9 + memory { 280.MB * Math.ceil(fasta.size() / 10000000) * task.attempt } conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bwa-mem2:2.2.1--he513fc3_0' : - 'biocontainers/bwa-mem2:2.2.1--he513fc3_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/e0/e05ce34b46ad42810eb29f74e4e304c0cb592b2ca15572929ed8bbaee58faf01/data' : + 'community.wave.seqera.io/library/bwa-mem2_htslib_samtools:db98f81f55b64113' }" input: tuple val(meta), path(fasta) output: tuple val(meta), path("bwamem2"), emit: index - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bwamem2'), eval('bwa-mem2 version | grep -o -E "[0-9]+(\\.[0-9]+)+"'), emit: versions_bwamem2, topic: versions when: task.ext.when == null || task.ext.when @@ -25,12 +27,8 @@ process BWAMEM2_INDEX { bwa-mem2 \\ index \\ $args \\ - $fasta -p bwamem2/${prefix} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - END_VERSIONS + -p bwamem2/${prefix} \\ + $fasta """ stub: @@ -43,10 +41,5 @@ process BWAMEM2_INDEX { touch bwamem2/${prefix}.pac touch bwamem2/${prefix}.amb touch bwamem2/${prefix}.bwt.2bit.64 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - END_VERSIONS """ } diff --git a/modules/nf-core/bwamem2/index/meta.yml b/modules/nf-core/bwamem2/index/meta.yml index 74f54ef0d..120748601 100644 --- a/modules/nf-core/bwamem2/index/meta.yml +++ b/modules/nf-core/bwamem2/index/meta.yml @@ -12,8 +12,9 @@ tools: a large reference genome, such as the human genome. homepage: https://github.com/bwa-mem2/bwa-mem2 documentation: https://github.com/bwa-mem2/bwa-mem2#usage - licence: ["MIT"] - identifier: "" + licence: + - "MIT" + identifier: "biotools:bwa-mem2" input: - - meta: type: map @@ -23,22 +24,49 @@ input: - fasta: type: file description: Input genome fasta file + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" output: - - index: - - meta: + index: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - bwamem2: - type: file + type: string description: BWA genome index files pattern: "*.{0123,amb,ann,bwt.2bit.64,pac}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/data_3210" + versions_bwamem2: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: BWA genome index files + pattern: "*.{0123,amb,ann,bwt.2bit.64,pac}" + ontologies: + - edam: "http://edamontology.org/data_3210" + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: BWA genome index files + pattern: "*.{0123,amb,ann,bwt.2bit.64,pac}" + ontologies: + - edam: "http://edamontology.org/data_3210" + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" maintainers: diff --git a/modules/nf-core/bwamem2/index/tests/main.nf.test b/modules/nf-core/bwamem2/index/tests/main.nf.test index dbf11132c..3ee91048a 100644 --- a/modules/nf-core/bwamem2/index/tests/main.nf.test +++ b/modules/nf-core/bwamem2/index/tests/main.nf.test @@ -8,7 +8,30 @@ nextflow_process { script "../main.nf" process "BWAMEM2_INDEX" - test("BWAMEM2 index") { + test("fasta") { + + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("fasta - stub") { + + options "-stub" when { process { diff --git a/modules/nf-core/bwamem2/index/tests/main.nf.test.snap b/modules/nf-core/bwamem2/index/tests/main.nf.test.snap index 69b268ee4..776e87be1 100644 --- a/modules/nf-core/bwamem2/index/tests/main.nf.test.snap +++ b/modules/nf-core/bwamem2/index/tests/main.nf.test.snap @@ -1,5 +1,58 @@ { - "BWAMEM2 index": { + "fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.fasta.0123:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bwt.2bit.64:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "BWAMEM2_INDEX", + "bwamem2", + "2.2.1" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.fasta.0123:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.bwt.2bit.64:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_bwamem2": [ + [ + "BWAMEM2_INDEX", + "bwamem2", + "2.2.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-09T16:19:38.013344" + }, + "fasta": { "content": [ { "0": [ @@ -17,7 +70,11 @@ ] ], "1": [ - "versions.yml:md5,9ffd13d12e7108ed15c58566bc4717d6" + [ + "BWAMEM2_INDEX", + "bwamem2", + "2.2.1" + ] ], "index": [ [ @@ -33,15 +90,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,9ffd13d12e7108ed15c58566bc4717d6" + "versions_bwamem2": [ + [ + "BWAMEM2_INDEX", + "bwamem2", + "2.2.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.02.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-18T12:59:39.132616" + "timestamp": "2026-02-09T16:19:32.542622" } } \ No newline at end of file diff --git a/modules/nf-core/bwamem2/index/tests/tags.yml b/modules/nf-core/bwamem2/index/tests/tags.yml deleted file mode 100644 index 3953018ee..000000000 --- a/modules/nf-core/bwamem2/index/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bwamem2/index: - - modules/nf-core/bwamem2/index/** diff --git a/modules/nf-core/bwamem2/mem/environment.yml b/modules/nf-core/bwamem2/mem/environment.yml index 7e0b5a347..f3637444a 100644 --- a/modules/nf-core/bwamem2/mem/environment.yml +++ b/modules/nf-core/bwamem2/mem/environment.yml @@ -1,8 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bwa-mem2=2.2.1 - - htslib=1.19.1 - - samtools=1.19.2 + # renovate: datasource=conda depName=bioconda/bwa-mem2 + - bwa-mem2=2.3 + # renovate: datasource=conda depName=bioconda/htslib + - htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - samtools=1.22.1 diff --git a/modules/nf-core/bwamem2/mem/main.nf b/modules/nf-core/bwamem2/mem/main.nf index 729428c4e..b8ac263b5 100644 --- a/modules/nf-core/bwamem2/mem/main.nf +++ b/modules/nf-core/bwamem2/mem/main.nf @@ -1,25 +1,26 @@ process BWAMEM2_MEM { - tag "$meta.id" + tag "${meta.id}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-e5d375990341c5aef3c9aff74f96f66f65375ef6:2d15960ccea84e249a150b7f5d4db3a42fc2d6c3-0' : - 'biocontainers/mulled-v2-e5d375990341c5aef3c9aff74f96f66f65375ef6:2d15960ccea84e249a150b7f5d4db3a42fc2d6c3-0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/e0/e05ce34b46ad42810eb29f74e4e304c0cb592b2ca15572929ed8bbaee58faf01/data' + : 'community.wave.seqera.io/library/bwa-mem2_htslib_samtools:db98f81f55b64113'}" input: tuple val(meta), path(reads) tuple val(meta2), path(index) tuple val(meta3), path(fasta) - val sort_bam + val sort_bam output: - tuple val(meta), path("*.sam") , emit: sam , optional:true - tuple val(meta), path("*.bam") , emit: bam , optional:true - tuple val(meta), path("*.cram") , emit: cram, optional:true - tuple val(meta), path("*.crai") , emit: crai, optional:true - tuple val(meta), path("*.csi") , emit: csi , optional:true - path "versions.yml" , emit: versions + tuple val(meta), path("*.sam"), emit: sam, optional: true + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bwamem2'), eval('bwa-mem2 version | grep -o -E "[0-9]+(\\.[0-9]+)+"'), emit: versions_bwamem2, topic: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -31,56 +32,43 @@ process BWAMEM2_MEM { def samtools_command = sort_bam ? 'sort' : 'view' def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args2 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" - def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" - if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" - + def reference = fasta && extension == "cram" ? "--reference ${fasta}" : "" + if (!fasta && extension == "cram") { + error("Fasta reference is required for CRAM output") + } """ INDEX=`find -L ./ -name "*.amb" | sed 's/\\.amb\$//'` bwa-mem2 \\ mem \\ - $args \\ - -t $task.cpus \\ + ${args} \\ + -t ${task.cpus} \\ \$INDEX \\ - $reads \\ - | samtools $samtools_command $args2 -@ $task.cpus ${reference} -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + ${reads} \\ + | samtools ${samtools_command} ${args2} -@ ${task.cpus} ${reference} -o ${prefix}.${extension} - """ stub: - - def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def samtools_command = sort_bam ? 'sort' : 'view' def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args2 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" - def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" - if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + if (!fasta && extension == "cram") { + error("Fasta reference is required for CRAM output") + } def create_index = "" if (extension == "cram") { create_index = "touch ${prefix}.crai" - } else if (extension == "bam") { + } + else if (extension == "bam") { create_index = "touch ${prefix}.csi" } - """ touch ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwamem2/mem/meta.yml b/modules/nf-core/bwamem2/mem/meta.yml index c6333ca17..a60d67889 100644 --- a/modules/nf-core/bwamem2/mem/meta.yml +++ b/modules/nf-core/bwamem2/mem/meta.yml @@ -16,8 +16,9 @@ tools: homepage: https://github.com/bwa-mem2/bwa-mem2 documentation: http://www.htslib.org/doc/samtools.html arxiv: arXiv:1303.3997 - licence: ["MIT"] - identifier: "" + licence: + - "MIT" + identifier: "biotools:bwa-mem2" input: - - meta: type: map @@ -29,6 +30,9 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1930" - - meta2: type: map description: | @@ -38,6 +42,8 @@ input: type: file description: BWA genome index files pattern: "Directory containing BWA index *.{0132,amb,ann,bwt.2bit.64,pac}" + ontologies: + - edam: "http://edamontology.org/data_3210" - - meta3: type: map description: | @@ -47,13 +53,16 @@ input: type: file description: Reference genome in FASTA format pattern: "*.{fa,fasta,fna}" - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - sam: - - meta: + sam: + - - meta: type: map description: | Groovy Map containing sample information @@ -62,8 +71,10 @@ output: type: file description: Output SAM file containing read alignments pattern: "*.{sam}" - - bam: - - meta: + ontologies: + - edam: "http://edamontology.org/format_2573" + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -72,8 +83,10 @@ output: type: file description: Output BAM file containing read alignments pattern: "*.{bam}" - - cram: - - meta: + ontologies: + - edam: "http://edamontology.org/format_2572" + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -82,8 +95,10 @@ output: type: file description: Output CRAM file containing read alignments pattern: "*.{cram}" - - crai: - - meta: + ontologies: + - edam: "http://edamontology.org/format_3462" + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -92,8 +107,9 @@ output: type: file description: Index file for CRAM file pattern: "*.{crai}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -102,11 +118,47 @@ output: type: file description: Index file for BAM file pattern: "*.{csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwamem2: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: The name of the tool + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: The name of the tool + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" - "@matthdsm" diff --git a/modules/nf-core/bwamem2/mem/tests/main.nf.test b/modules/nf-core/bwamem2/mem/tests/main.nf.test index 9e0ab14ae..be33a3a7e 100644 --- a/modules/nf-core/bwamem2/mem/tests/main.nf.test +++ b/modules/nf-core/bwamem2/mem/tests/main.nf.test @@ -46,11 +46,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - fastq, index, fasta, true") { @@ -75,11 +74,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, false") { @@ -107,11 +105,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, true") { @@ -139,11 +136,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, true - stub") { @@ -170,10 +166,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } - } diff --git a/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap b/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap index 69bc3612b..06d854b00 100644 --- a/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap @@ -1,51 +1,34 @@ { "sarscov2 - [fastq1, fastq2], index, fasta, false": { "content": [ - "eefa0f44493fd0504e734efd2f1f4a9e", + "e414c2d48e2e44c2c52c20ecd88e8bd8", "57aeef88ed701a8ebc8e2f0a381b2a6", - [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:37.929675" - }, - "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { - "content": [ { - "0": [ - - ], - "1": [ + "versions_bwamem2": [ [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" ] ], - "2": [ - - ], - "3": [ - - ], - "4": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BWAMEM2_MEM", + "samtools", + "1.22.1" ] - ], - "5": [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" - ], + ] + } + ], + "timestamp": "2026-02-19T11:51:27.481278728", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { + "content": [ + { "bam": [ [ { @@ -73,57 +56,107 @@ "sam": [ ], - "versions": [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-19T11:54:06.902806102", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:12:06.693567" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - [fastq1, fastq2], index, fasta, true": { "content": [ - "7aba324f82d5b4e926a5dd7b46029cb4", + "716ed1ef39deaad346ca7cf86e08f959", "af8628d9df18b2d3d4f6fd47ef2bb872", - [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:40.483217643", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:53.488374" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, index, fasta, false": { "content": [ - "bc02b41697b3a8f1021b02becec24052", + "283a83f604f3f5338acedfee349dccf4", "798439cbd7fd81cbcc5078022dc5479d", - [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:02.459481643", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:05.644682" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, index, fasta, true": { "content": [ - "e41d67320815d29ba5f6e9d1ae21902a", + "ed99048bb552cac58e39923b550b6d5b", "94fcf617f5b994584c4e8d4044e16b4f", - [ - "versions.yml:md5,1c1a9566f189ec077b5179bbf453c51a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:15.170720681", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:21.837763" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/bwamem2/mem/tests/tags.yml b/modules/nf-core/bwamem2/mem/tests/tags.yml deleted file mode 100644 index 134efb2b3..000000000 --- a/modules/nf-core/bwamem2/mem/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bwamem2/mem: - - "modules/nf-core/bwamem2/mem/**" diff --git a/modules/nf-core/bwameme/index/environment.yml b/modules/nf-core/bwameme/index/environment.yml index f209d62e8..21fb9c42f 100644 --- a/modules/nf-core/bwameme/index/environment.yml +++ b/modules/nf-core/bwameme/index/environment.yml @@ -1,5 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - "bioconda::bwa-meme=1.0.6" + - bioconda::bwa-meme=1.0.6 + - bioconda::mbuffer=20160228 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/bwameme/index/main.nf b/modules/nf-core/bwameme/index/main.nf index 870f494cc..ca13f8971 100644 --- a/modules/nf-core/bwameme/index/main.nf +++ b/modules/nf-core/bwameme/index/main.nf @@ -4,15 +4,16 @@ process BWAMEME_INDEX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bwa-meme:1.0.6--hdcf5f25_2': - 'biocontainers/bwa-meme:1.0.6--hdcf5f25_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9d/9ddd41b93c5e182db9d643ca266dd1677e59593a9cb49904b982ff45ad5aa8c3/data': + 'community.wave.seqera.io/library/bwa-meme_mbuffer_samtools:03f3f60b6c289776' }" input: tuple val(meta), path(fasta) output: tuple val(meta), path("bwameme"), emit: index - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bwameme'), val('1.0.6'), topic: versions, emit: versions_bwameme + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. when: task.ext.when == null || task.ext.when @@ -20,7 +21,6 @@ process BWAMEME_INDEX { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${fasta}" - def VERSION = '1.0.6' // WARN: Version information provided by tool on CLI is incorrect. Please update this string when bumping container versions. """ mkdir bwameme @@ -31,16 +31,10 @@ process BWAMEME_INDEX { $fasta build_rmis_dna.sh bwameme/$prefix - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwameme: $VERSION - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${fasta}" - def VERSION = '1.0.6' // WARN: Version information provided by tool on CLI is incorrect. Please update this string when bumping container versions. """ mkdir bwameme touch bwameme/${prefix}.0123 @@ -52,10 +46,5 @@ process BWAMEME_INDEX { touch bwameme/${prefix}.suffixarray_uint64_L0_PARAMETERS touch bwameme/${prefix}.suffixarray_uint64_L1_PARAMETERS touch bwameme/${prefix}.suffixarray_uint64_L2_PARAMETERS - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwameme: $VERSION - END_VERSIONS """ } diff --git a/modules/nf-core/bwameme/index/meta.yml b/modules/nf-core/bwameme/index/meta.yml index e0cb04a63..b89af8713 100644 --- a/modules/nf-core/bwameme/index/meta.yml +++ b/modules/nf-core/bwameme/index/meta.yml @@ -23,9 +23,10 @@ input: - fasta: type: file description: Input genome fasta file + ontologies: [] output: - - index: - - meta: + index: + - - meta: type: map description: | Groovy Map containing sample information @@ -34,11 +35,28 @@ output: type: file description: BWA-MEME genome index files pattern: "*.{0123,amb,ann,pac,pos_packed,suffixarray_uint64,suffixarray_uint64_L0_PARAMETERS,suffixarray_uint64_L1_PARAMETERS,suffixarray_uint64_L2_PARAMETERS}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwameme: + - - ${task.process}: + type: string + description: The name of the process + - bwameme: + type: string + description: The name of the tool + - 1.0.6: + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwameme: + type: string + description: The name of the tool + - 1.0.6: + type: string + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/bwameme/index/tests/main.nf.test.snap b/modules/nf-core/bwameme/index/tests/main.nf.test.snap index e608af8b9..282e2e7f3 100644 --- a/modules/nf-core/bwameme/index/tests/main.nf.test.snap +++ b/modules/nf-core/bwameme/index/tests/main.nf.test.snap @@ -21,7 +21,11 @@ ] ], "1": [ - "versions.yml:md5,c80b8097b8a9c022e4c1e2617771ea3d" + [ + "BWAMEME_INDEX", + "bwameme", + "1.0.6" + ] ], "index": [ [ @@ -41,16 +45,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,c80b8097b8a9c022e4c1e2617771ea3d" + "versions_bwameme": [ + [ + "BWAMEME_INDEX", + "bwameme", + "1.0.6" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T13:44:38.551252246" + "timestamp": "2026-02-13T18:49:37.030181" }, "BWAMEME index": { "content": [ @@ -74,7 +82,11 @@ ] ], "1": [ - "versions.yml:md5,c80b8097b8a9c022e4c1e2617771ea3d" + [ + "BWAMEME_INDEX", + "bwameme", + "1.0.6" + ] ], "index": [ [ @@ -94,15 +106,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,c80b8097b8a9c022e4c1e2617771ea3d" + "versions_bwameme": [ + [ + "BWAMEME_INDEX", + "bwameme", + "1.0.6" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T13:44:25.040725565" + "timestamp": "2026-02-13T18:49:29.151239" } } \ No newline at end of file diff --git a/modules/nf-core/bwameme/index/tests/tags.yml b/modules/nf-core/bwameme/index/tests/tags.yml deleted file mode 100644 index ddbcab044..000000000 --- a/modules/nf-core/bwameme/index/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bwameme/index: - - "modules/nf-core/bwameme/index/**" diff --git a/modules/nf-core/bwameme/mem/README.md b/modules/nf-core/bwameme/mem/README.md new file mode 100644 index 000000000..b681f9a02 --- /dev/null +++ b/modules/nf-core/bwameme/mem/README.md @@ -0,0 +1,51 @@ +# bwameme/mem options + +bwa-meme is a high-throughput aligner that produces alignments faster than samtools can consume them. To prevent bwa-meme from stalling while samtools processes data, mbuffer is used as an intermediary to absorb alignments until samtools is ready. The mbuffer and samtools options are configurable via `ext.args2` and `ext.args3` respectively. + +## Configuring mbuffer (`ext.args2`) + +`ext.args2` is passed to mbuffer. The default buffer size is 3GB (`-m 3072M`). If `-m` is not present in `ext.args2`, the default is injected automatically. + +The mbuffer size should match the total memory allocated to `samtools sort` (`-m` × `-@`) so it can absorb bwa-meme output while samtools is flushing its sort buffer to disk. + +``` +withName: 'BWAMEME_MEM' { + ext.args2 = '-m 20480M' // 20GB mbuffer to match samtools sort total (e.g. -m 1024M x -@ 20) +} +``` + +## Configuring samtools (`ext.args3`) + +`ext.args3` is passed to `samtools sort` or `samtools view` depending on the `sort_bam` input. Defaults are injected if not supplied: + +- `-@ 3` (threads) — always injected if `-@` is absent +- `-m 1024M` (memory per thread) — injected if `-m` is absent and `sort_bam` is true + +``` +withName: 'BWAMEME_MEM' { + ext.args3 = '-@ 20 -m 1024M' // 20 threads, 1GB per thread = 20GB total +} +``` + +## Example: tuning for human genome alignment + +For a large reference (e.g. human genome) on a well-resourced machine, you may want to increase both values. The mbuffer size should equal the total samtools sort memory: + +``` +withName: 'BWAMEME_MEM' { + ext.args2 = '-m 20480M' // mbuffer = samtools total (20 threads x 1GB) + ext.args3 = '-@ 20 -m 1024M' +} +``` + +## CRAM output + +To produce CRAM output, pass `--output-fmt` via `ext.args3`: + +``` +withName: 'BWAMEME_MEM' { + ext.args3 = '--output-fmt cram' +} +``` + +A FASTA reference must be provided as `input[2]` when using CRAM output. diff --git a/modules/nf-core/bwameme/mem/environment.yml b/modules/nf-core/bwameme/mem/environment.yml index cad794404..21fb9c42f 100644 --- a/modules/nf-core/bwameme/mem/environment.yml +++ b/modules/nf-core/bwameme/mem/environment.yml @@ -4,6 +4,6 @@ channels: - conda-forge - bioconda dependencies: - - "bioconda::bwa-meme=1.0.6" - - "bioconda::mbuffer=20160228" - - "bioconda::samtools=1.20" + - bioconda::bwa-meme=1.0.6 + - bioconda::mbuffer=20160228 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/bwameme/mem/main.nf b/modules/nf-core/bwameme/mem/main.nf index 2efc8c0fa..6b356e302 100644 --- a/modules/nf-core/bwameme/mem/main.nf +++ b/modules/nf-core/bwameme/mem/main.nf @@ -3,54 +3,44 @@ process BWAMEME_MEM { label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-ed29b84fa94419f5a7bf6a841ddbcb964768825b:139b5e403886ad278b9ad139174967441c1c6ff3-0': - 'biocontainers/mulled-v2-ed29b84fa94419f5a7bf6a841ddbcb964768825b:139b5e403886ad278b9ad139174967441c1c6ff3-0' }" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9d/9ddd41b93c5e182db9d643ca266dd1677e59593a9cb49904b982ff45ad5aa8c3/data': + 'community.wave.seqera.io/library/bwa-meme_mbuffer_samtools:03f3f60b6c289776' }" input: tuple val(meta), path(reads) tuple val(meta2), path(index) tuple val(meta3), path(fasta) val sort_bam - val mbuffer - val samtools_threads output: - tuple val(meta), path("*.sam") , emit: sam , optional:true - tuple val(meta), path("*.bam") , emit: bam , optional:true - tuple val(meta), path("*.cram") , emit: cram, optional:true - tuple val(meta), path("*.crai") , emit: crai, optional:true - tuple val(meta), path("*.csi") , emit: csi , optional:true - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.{sam,bam,cram}"), emit: output + tuple val(meta), path("${prefix}.{csi,crai}") , emit: index , optional: true + tuple val("${task.process}"), val('bwameme'), val('1.0.6'), topic: versions, emit: versions_bwameme + tuple val("${task.process}"), val('samtools'), eval('samtools version | sed "1!d;s/.* //"'), topic: versions, emit: versions_samtools // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + tuple val("${task.process}"), val('mbuffer'), eval("mbuffer --version 2>&1 | sed -n 's/mbuffer version //p'") , topic: versions, emit: versions_mbuffer when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args3 = task.ext.args3 ?: '' + prefix = task.ext.prefix ?: "${meta.id}" def samtools_command = sort_bam ? 'sort' : 'view' - if (!mbuffer) { - log.info '[bwameme-mbuffer] Memory for mbuffer is not set - defaulting to 3GB for mbuffer.' - mbuffer_mem = 3072 - } else { - mbuffer_mem = mbuffer - } - if (!samtools_threads) { - log.info 'Number of threads for samtools is not set - defaulting to 2 threads.' - threads = 2 - } else { - threads = samtools_threads - } - mbuffer_command = sort_bam ? "| mbuffer -m ${mbuffer_mem}M" : "" - mem_per_thread = sort_bam ? "-m "+ (mbuffer_mem/threads).intValue()+"M" : "" + // ext.args2 controls mbuffer options; inject default -m if not supplied + def mbuffer_args = args2.contains('-m') ? args2 : "-m 3072M ${args2}".trim() + def mbuffer_command = sort_bam ? "| mbuffer ${mbuffer_args}" : "" + // ext.args3 controls samtools options; inject defaults for -@ and -m (sort only) if not supplied + def samtools_threads_arg = args3.contains('-@') ? '' : '-@ 3' + def samtools_mem_arg = (sort_bam && !args3.contains('-m')) ? '-m 1024M' : '' + def samtools_args = "${samtools_mem_arg} ${samtools_threads_arg} ${args3}".trim() def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args3 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" - def VERSION = '1.0.6' // WARN: Version information provided by tool on CLI is incorrect. Please update this string when bumping container versions. """ INDEX=`find -L ./ -name "*.amb" | sed 's/\\.amb\$//'` @@ -61,42 +51,22 @@ process BWAMEME_MEM { \$INDEX \\ $reads \\ $mbuffer_command \\ - | samtools $samtools_command $args2 $mem_per_thread -@ $threads ${reference} -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwameme: $VERSION - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + | samtools $samtools_command $samtools_args ${reference} -o ${prefix}.${extension} - """ stub: - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def samtools_command = sort_bam ? 'sort' : 'view' + def args3 = task.ext.args3 ?: '' + prefix = task.ext.prefix ?: "${meta.id}" def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args3 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" - def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" - def create_index = "" - if (extension == "cram") { - create_index = "touch ${prefix}.crai" - } else if (extension == "bam") { - create_index = "touch ${prefix}.csi" - } - def VERSION = '1.0.6' // WARN: Version information provided by tool on CLI is incorrect. Please update this string when bumping container versions. + def create_index = extension == "cram" ? "touch ${prefix}.crai" : + extension == "bam" ? "touch ${prefix}.csi" : "" """ touch ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwameme: $VERSION - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwameme/mem/meta.yml b/modules/nf-core/bwameme/mem/meta.yml index 070aefebf..32620223e 100644 --- a/modules/nf-core/bwameme/mem/meta.yml +++ b/modules/nf-core/bwameme/mem/meta.yml @@ -17,9 +17,9 @@ tools: homepage: https://github.com/kaist-ina/BWA-MEME documentation: https://github.com/kaist-ina/BWA-MEME#getting-started doi: "10.1093/bioinformatics/btac137" - licence: ["MIT"] + licence: + - "MIT" identifier: "" - input: - - meta: type: map @@ -31,6 +31,7 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: [] - - meta2: type: map description: | @@ -40,6 +41,7 @@ input: type: file description: BWA genome index files pattern: "Directory containing BWA index *.{0132,amb,ann,bwt.2bit.64,pac}" + ontologies: [] - - meta3: type: map description: | @@ -49,72 +51,93 @@ input: type: file description: Reference genome in FASTA format pattern: "*.{fa,fasta,fna}" - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" - - - mbuffer: - type: integer - description: memory for mbuffer in megabytes (default 3072) - - - samtools_threads: - type: integer - description: number of threads for samtools (default 2) + ontologies: [] + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - sam: - - meta: + output: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.sam": + - ${prefix}.{sam,bam,cram}: type: file - description: Output SAM file containing read alignments - pattern: "*.{sam}" - - bam: - - meta: + description: Output alignment file (SAM, BAM, or CRAM) + pattern: "*.{sam,bam,cram}" + ontologies: [] + index: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.bam": + - ${prefix}.{csi,crai}: type: file - description: Output BAM file containing read alignments - pattern: "*.{bam}" - - cram: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.cram": - type: file - description: Output CRAM file containing read alignments - pattern: "*.{cram}" - - crai: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.crai": - type: file - description: Index file for CRAM file - pattern: "*.{crai}" - - csi: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.csi": - type: file - description: Index file for BAM file - pattern: "*.{csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + description: Index file for BAM (.csi) or CRAM (.crai) output + pattern: "*.{csi,crai}" + ontologies: [] + versions_bwameme: + - - ${task.process}: + type: string + description: The name of the process + - bwameme: + type: string + description: The name of the tool + - 1.0.6: + type: string + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + versions_mbuffer: + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer version //p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwameme: + type: string + description: The name of the tool + - 1.0.6: + type: string + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - mbuffer: + type: string + description: The name of the tool + - mbuffer --version 2>&1 | sed -n 's/mbuffer version //p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/bwameme/mem/tests/main.nf.test b/modules/nf-core/bwameme/mem/tests/main.nf.test index 6d93fd6eb..31911da25 100644 --- a/modules/nf-core/bwameme/mem/tests/main.nf.test +++ b/modules/nf-core/bwameme/mem/tests/main.nf.test @@ -26,9 +26,14 @@ nextflow_process { } } - test("sarscov2 - fastq, index, fasta, false, 0, 4") { + test("sarscov2 - fastq, index, fasta, false") { when { + params { + module_args2 = "" + module_args3 = "" + } + process { """ input[0] = Channel.of([ @@ -38,8 +43,6 @@ nextflow_process { input[1] = BWAMEME_INDEX.out.index input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) input[3] = false - input[4] = 0 - input[5] = 4 """ } } @@ -48,18 +51,23 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getHeaderMD5(), - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } } - test("sarscov2 - fastq, index, fasta, true, 2048, 4") { + test("sarscov2 - fastq, index, fasta, true") { when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + process { """ input[0] = Channel.of([ @@ -69,8 +77,6 @@ nextflow_process { input[1] = BWAMEME_INDEX.out.index input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) input[3] = true - input[4] = 2048 - input[5] = 4 """ } } @@ -79,18 +85,23 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getHeaderMD5(), - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } } - test("sarscov2 - [fastq1, fastq2], index, fasta, false, 0, 4") { + test("sarscov2 - [fastq1, fastq2], index, fasta, false") { when { + params { + module_args2 = "" + module_args3 = "" + } + process { """ input[0] = Channel.of([ @@ -103,8 +114,6 @@ nextflow_process { input[1] = BWAMEME_INDEX.out.index input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) input[3] = false - input[4] = 0 - input[5] = 4 """ } } @@ -113,18 +122,23 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getHeaderMD5(), - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } } - test("sarscov2 - [fastq1, fastq2], index, fasta, true, 2048, ''") { + test("sarscov2 - [fastq1, fastq2], index, fasta, true") { when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + process { """ input[0] = Channel.of([ @@ -137,8 +151,6 @@ nextflow_process { input[1] = BWAMEME_INDEX.out.index input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) input[3] = true - input[4] = 2048 - input[5] = "" """ } } @@ -147,20 +159,25 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getHeaderMD5(), - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + bam(process.out.output[0][1]).getHeaderMD5(), + bam(process.out.output[0][1]).getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } } - test("sarscov2 - [fastq1, fastq2], index, fasta, true, 2048, 4 - stub") { + test("sarscov2 - [fastq1, fastq2], index, fasta, true - stub") { options "-stub" when { + params { + module_args2 = "-m 2048M" + module_args3 = "-@ 4" + } + process { """ input[0] = Channel.of([ @@ -173,8 +190,6 @@ nextflow_process { input[1] = BWAMEME_INDEX.out.index input[2] = Channel.of([[:], [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) input[3] = true - input[4] = 2048 - input[5] = 4 """ } } @@ -187,4 +202,4 @@ nextflow_process { } } -} \ No newline at end of file +} diff --git a/modules/nf-core/bwameme/mem/tests/main.nf.test.snap b/modules/nf-core/bwameme/mem/tests/main.nf.test.snap index bc845155c..5d3180a46 100644 --- a/modules/nf-core/bwameme/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwameme/mem/tests/main.nf.test.snap @@ -1,65 +1,49 @@ { - "sarscov2 - [fastq1, fastq2], index, fasta, false, 0, 4": { + "sarscov2 - [fastq1, fastq2], index, fasta, false": { "content": [ - "640e6a53bedb535837cc35cc1c145dcb", + "2dd7c6542f553040eebaa572c10fe035", "57aeef88ed701a8ebc8e2f0a381b2a6", - [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:25:03.99184" - }, - "sarscov2 - [fastq1, fastq2], index, fasta, true, 2048, ''": { - "content": [ - "7af5d6b93d3f8bd4f53d4f9ace7ee981", - "af8628d9df18b2d3d4f6fd47ef2bb872", - [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:26:17.237557" - }, - "sarscov2 - fastq, index, fasta, true, 2048, 4": { - "content": [ - "4ccda5ce5d3b09b697786589b3753825", - "94fcf617f5b994584c4e8d4044e16b4f", - [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:24:07.289865" - }, - "sarscov2 - fastq, index, fasta, false, 0, 4": { - "content": [ - "a58fa4a997be7d13a3dc62c9c9eb83d2", - "798439cbd7fd81cbcc5078022dc5479d", - [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" - ] + { + "versions_bwameme": [ + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" + ] + ], + "versions_mbuffer": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] + ], + "versions_samtools": [ + [ + "BWAMEME_MEM", + "samtools", + "1.21" + ] + ] + } ], + "timestamp": "2026-06-12T08:19:39.496429529", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:23:17.201419" + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } }, - "sarscov2 - [fastq1, fastq2], index, fasta, true, 2048, 4 - stub": { + "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { "content": [ { "0": [ - + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "1": [ [ @@ -67,16 +51,31 @@ "id": "test", "single_end": false }, - "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "2": [ - + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" + ] ], "3": [ - + [ + "BWAMEME_MEM", + "samtools", + "1.21" + ] ], "4": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] + ], + "index": [ [ { "id": "test", @@ -85,10 +84,7 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "5": [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" - ], - "bam": [ + "output": [ [ { "id": "test", @@ -97,33 +93,135 @@ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "crai": [ - + "versions_bwameme": [ + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" + ] ], - "cram": [ - + "versions_mbuffer": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] ], - "csi": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BWAMEME_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:20:13.023631084", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - [fastq1, fastq2], index, fasta, true": { + "content": [ + "8c45fe3cdc7021ffab9c5eea83fc5850", + "af8628d9df18b2d3d4f6fd47ef2bb872", + { + "versions_bwameme": [ + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" ] ], - "sam": [ - + "versions_mbuffer": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] ], - "versions": [ - "versions.yml:md5,700d57071f430eb29b3c67d0a199eb95" + "versions_samtools": [ + [ + "BWAMEME_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:20:02.737739229", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq, index, fasta, false": { + "content": [ + "9661f4c03c6b2abdc93204890aa61673", + "798439cbd7fd81cbcc5078022dc5479d", + { + "versions_bwameme": [ + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" + ] + ], + "versions_mbuffer": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] + ], + "versions_samtools": [ + [ + "BWAMEME_MEM", + "samtools", + "1.21" + ] + ] + } + ], + "timestamp": "2026-06-12T08:18:55.571422607", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq, index, fasta, true": { + "content": [ + "30aae1770b553c055553c48dcad73384", + "94fcf617f5b994584c4e8d4044e16b4f", + { + "versions_bwameme": [ + [ + "BWAMEME_MEM", + "bwameme", + "1.0.6" + ] + ], + "versions_mbuffer": [ + [ + "BWAMEME_MEM", + "mbuffer", + "20160228" + ] + ], + "versions_samtools": [ + [ + "BWAMEME_MEM", + "samtools", + "1.21" + ] ] } ], + "timestamp": "2026-06-12T08:19:17.606378245", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-02T12:31:46.777111" + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/bwameme/mem/tests/nextflow.config b/modules/nf-core/bwameme/mem/tests/nextflow.config index e7dd707ea..835b858dc 100644 --- a/modules/nf-core/bwameme/mem/tests/nextflow.config +++ b/modules/nf-core/bwameme/mem/tests/nextflow.config @@ -1,9 +1,10 @@ process { - withName: BWAMEME_INDEX { ext.args = '-a meme' } withName: BWAMEME_MEM { - ext.args = '-7' + ext.args = '-7' + ext.args2 = { params.module_args2 } + ext.args3 = { params.module_args3 } } } diff --git a/modules/nf-core/bwameme/mem/tests/tags.yml b/modules/nf-core/bwameme/mem/tests/tags.yml deleted file mode 100644 index 9e3a26cfe..000000000 --- a/modules/nf-core/bwameme/mem/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bwameme/mem: - - "modules/nf-core/bwameme/mem/**" diff --git a/modules/nf-core/cadd/environment.yml b/modules/nf-core/cadd/environment.yml index 4477e16e5..39701b4ab 100644 --- a/modules/nf-core/cadd/environment.yml +++ b/modules/nf-core/cadd/environment.yml @@ -1,7 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::cadd-scripts=1.6.post1 - - conda-forge::conda=4.14.0 - - conda-forge::mamba=1.4.0 + - bioconda::cadd-scripts=1.7.3 diff --git a/modules/nf-core/cadd/main.nf b/modules/nf-core/cadd/main.nf index 0af87f6e5..771d1445d 100644 --- a/modules/nf-core/cadd/main.nf +++ b/modules/nf-core/cadd/main.nf @@ -1,53 +1,53 @@ process CADD { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container 'docker.io/biocontainers/cadd-scripts-with-envs:1.6.post1_cv1' + container 'docker.io/clinicalgenomics/cadd-with-scripts:1.7.3' containerOptions { - (workflow.containerEngine == 'singularity') ? - "-B ${annotation_dir}:/opt/CADD-scripts-1.6.post1/data/annotations" : - "-v ${annotation_dir}:/opt/CADD-scripts-1.6.post1/data/annotations" + if (prescored_dir) { + ['singularity', 'apptainer'].contains(workflow.containerEngine) ? + "-B ${annotation_dir}:/cadd-scripts/data/annotations -B ${prescored_dir}:/cadd-scripts/data/prescored" : + "-v ${annotation_dir}:/cadd-scripts/data/annotations -v ${prescored_dir}:/cadd-scripts/data/prescored" + } else { + ['singularity', 'apptainer'].contains(workflow.containerEngine) ? + "-B ${annotation_dir}:/cadd-scripts/data/annotations" : + "-v ${annotation_dir}:/cadd-scripts/data/annotations" } + } input: tuple val(meta), path(vcf) - path(annotation_dir) + tuple val(meta2), val(annotation_dir) + tuple val(meta3), val(prescored_dir) output: - tuple val(meta), path("*.tsv.gz"), emit: tsv - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.tsv.gz"), emit: tsv + tuple val("${task.process}"), val("cadd"), val("1.7.3"), emit: versions_cadd, topic: versions + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.6.post1" // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" """ - cadd.sh \\ - -o ${prefix}.tsv.gz \\ - $args \\ - $vcf + export XDG_CACHE_HOME=\$PWD/snakemake_cache + export MPLCONFIGDIR=. + mkdir -p \$XDG_CACHE_HOME - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cadd: $VERSION - END_VERSIONS + CADD.sh \\ + -m \\ + -o ${prefix}.tsv.gz \\ + ${args} \\ + ${vcf} """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.6.post1" // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.tsv.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cadd: $VERSION - END_VERSIONS + echo "" | gzip > ${prefix}.tsv.gz """ } diff --git a/modules/nf-core/cadd/meta.yml b/modules/nf-core/cadd/meta.yml index 751bea454..1efaa94f0 100644 --- a/modules/nf-core/cadd/meta.yml +++ b/modules/nf-core/cadd/meta.yml @@ -1,6 +1,6 @@ name: "cadd" -description: CADD is a tool for scoring the deleteriousness of single nucleotide variants - as well as insertion/deletions variants in the human genome. +description: CADD is a tool for scoring the deleteriousness of single nucleotide + variants as well as insertion/deletions variants in the human genome. keywords: - cadd - annotate @@ -25,28 +25,69 @@ input: type: file description: Input file for annotation in vcf or vcf.gz format pattern: "*.{vcf,vcf.gz}" - - - annotation_dir: - type: file + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - annotation_dir: + type: directory description: | Path to folder containing the vcf files with precomputed CADD scores. This folder contains the uncompressed files that would otherwise be in data/annotation folder as described in https://github.com/kircherlab/CADD-scripts/#manual-installation. - pattern: "*.{vcf,vcf.gz}" + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - prescored_dir: + type: directory + description: | + Path to folder containing prescored CADD score files. + Expected structure mirrors data/prescored/ from the CADD-scripts installation: + / + GRCh38_v1.7/ + incl_anno/ # *.tsv.gz + *.tsv.gz.tbi (scores with annotations) + no_anno/ # *.tsv.gz + *.tsv.gz.tbi (scores only) + GRCh37_v1.7/ + incl_anno/ + no_anno/ + See https://github.com/kircherlab/CADD-scripts/#manual-installation for details. output: - - tsv: - - meta: + tsv: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.tsv.gz": + - ${prefix}.tsv.gz: type: file description: Annotated tsv file pattern: "*.{tsv,tsv.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 + versions_cadd: + - - ${task.process}: + type: string + description: The name of the process + - cadd: + type: string + description: The name of the tool + - 1.7.3: + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - cadd: + type: string + description: The name of the tool + - 1.7.3: + type: string + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/cadd/tests/main.nf.test b/modules/nf-core/cadd/tests/main.nf.test new file mode 100644 index 000000000..c3287907b --- /dev/null +++ b/modules/nf-core/cadd/tests/main.nf.test @@ -0,0 +1,39 @@ +nextflow_process { + + name "Test Process CADD" + + script "../main.nf" + process "CADD" + + tag "modules" + tag "modules_nfcore" + tag "cadd" + + config "./nextflow.config" + + test("test_cadd - stub") { + options '-stub' + when { + + process { + """ + input[0] = [ + [id:'test',single_end:false],// meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf',checkIfExists:true) + ] + input[1] = Channel.from("\$PWD").map { dir -> [ [ id: dir ], dir ] } + input[2] = Channel.from("/").map { dir -> [ [ id: dir ], dir ] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out, + process.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/cadd/tests/main.nf.test.snap b/modules/nf-core/cadd/tests/main.nf.test.snap new file mode 100644 index 000000000..5e38eeaf5 --- /dev/null +++ b/modules/nf-core/cadd/tests/main.nf.test.snap @@ -0,0 +1,48 @@ +{ + "test_cadd - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CADD", + "cadd", + "1.7.3" + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_cadd": [ + [ + "CADD", + "cadd", + "1.7.3" + ] + ] + }, + [ + + ] + ], + "timestamp": "2026-03-01T12:08:37.372500636", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/cadd/tests/nextflow.config b/modules/nf-core/cadd/tests/nextflow.config new file mode 100644 index 000000000..bd24d9f3b --- /dev/null +++ b/modules/nf-core/cadd/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'CADD' { + container = "nf-core/ubuntu:22.04" //Using an basic container because v1.7.3 is too big for CI. + } +} diff --git a/modules/nf-core/cat/cat/environment.yml b/modules/nf-core/cat/cat/environment.yml index 9b01c865a..985117698 100644 --- a/modules/nf-core/cat/cat/environment.yml +++ b/modules/nf-core/cat/cat/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - conda-forge::pigz=2.3.4 + - conda-forge::pigz=2.8 diff --git a/modules/nf-core/cat/cat/main.nf b/modules/nf-core/cat/cat/main.nf index 2862c64cd..15274c4ce 100644 --- a/modules/nf-core/cat/cat/main.nf +++ b/modules/nf-core/cat/cat/main.nf @@ -4,15 +4,15 @@ process CAT_CAT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : - 'biocontainers/pigz:2.3.4' }" + 'https://depot.galaxyproject.org/singularity/pigz:2.8' : + 'biocontainers/pigz:2.8' }" input: tuple val(meta), path(files_in) output: tuple val(meta), path("${prefix}"), emit: file_out - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("pigz"), eval("pigz --version 2>&1 | sed 's/pigz //g'"), topic: versions, emit: versions_cat when: task.ext.when == null || task.ext.when @@ -20,7 +20,7 @@ process CAT_CAT { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - def file_list = files_in.collect { it.toString() } + def file_list = files_in.collect { file -> file.toString() } // choose appropriate concatenation tool depending on input and output format @@ -55,7 +55,7 @@ process CAT_CAT { """ stub: - def file_list = files_in.collect { it.toString() } + def file_list = files_in.collect { file -> file.toString() } prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" if(file_list.contains(prefix.trim())) { error "The name of the input file can't be the same as for the output prefix in the " + diff --git a/modules/nf-core/cat/cat/meta.yml b/modules/nf-core/cat/cat/meta.yml index 81778a067..36a7359bb 100644 --- a/modules/nf-core/cat/cat/meta.yml +++ b/modules/nf-core/cat/cat/meta.yml @@ -20,21 +20,41 @@ input: type: file description: List of compressed / uncompressed files pattern: "*" + ontologies: [] output: - - file_out: - - meta: - type: file - description: Concatenated file. Will be gzipped if file_out ends with ".gz" - pattern: "${file_out}" + file_out: + - - meta: + type: map + description: Groovy Map containing sample information - ${prefix}: type: file - description: Concatenated file. Will be gzipped if file_out ends with ".gz" + description: Concatenated file. Will be gzipped if file_out ends with + ".gz" pattern: "${file_out}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_cat: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //g'": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //g'": + type: eval + description: The expression to obtain the version of the tool + authors: - "@erikrikarddaniel" - "@FriederikeHanssen" diff --git a/modules/nf-core/cat/cat/tests/main.nf.test b/modules/nf-core/cat/cat/tests/main.nf.test index 9cb161788..030c6649d 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test +++ b/modules/nf-core/cat/cat/tests/main.nf.test @@ -3,16 +3,14 @@ nextflow_process { name "Test Process CAT_CAT" script "../main.nf" process "CAT_CAT" + tag "modules" tag "modules_nfcore" tag "cat" tag "cat/cat" - test("test_cat_name_conflict") { + test("sarscov2 - genome - error: name conflict") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -30,16 +28,13 @@ nextflow_process { assertAll( { assert !process.success }, { assert process.stdout.toString().contains("The name of the input file can't be the same as for the output prefix") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(process.out).match() } ) } } - test("test_cat_unzipped_unzipped") { + test("sarscov2 - [ fasta, sizes ] - unzipped") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -62,11 +57,8 @@ nextflow_process { } - test("test_cat_zipped_zipped") { + test("sarscov2 - [ gff3_gz, maf_gz ] - zipped") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -81,25 +73,20 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() + { assert snapshot(process.out).match() } ) } } - test("test_cat_zipped_unzipped") { - config './nextflow_zipped_unzipped.config' + test("sarscov2 - [ gff3_gz, maf_gz ] - unzipped") { + config './nextflow.config' when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt" } process { """ @@ -124,11 +111,12 @@ nextflow_process { } - test("test_cat_unzipped_zipped") { - config './nextflow_unzipped_zipped.config' + test("sarscov2 - [ fasta, sizes ] - zipped") { + config './nextflow.config' + when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt.gz" } process { """ @@ -144,24 +132,19 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() - } + { assert snapshot(process.out).match() } ) } } - test("test_cat_one_file_unzipped_zipped") { - config './nextflow_unzipped_zipped.config' + test("sarscov2 - fasta - zipped") { + config './nextflow.config' + when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt.gz" } process { """ @@ -176,15 +159,33 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() - } + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 - fasta - unzipped - stub") { + options "-stub" + + when { + process { + """ + input[0] = + [ + [ id:'test', single_end:true ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + ] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/cat/cat/tests/main.nf.test.snap b/modules/nf-core/cat/cat/tests/main.nf.test.snap index b7623ee65..5b4e4cc3d 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test.snap +++ b/modules/nf-core/cat/cat/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "test_cat_unzipped_unzipped": { + "sarscov2 - [ gff3_gz, maf_gz ] - unzipped": { "content": [ { "0": [ @@ -8,11 +8,15 @@ "id": "test", "single_end": true }, - "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" ] ], "1": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + [ + "CAT_CAT", + "pigz", + "2.8" + ] ], "file_out": [ [ @@ -20,21 +24,25 @@ "id": "test", "single_end": true }, - "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" ] ], - "versions": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2023-10-16T14:32:18.500464399" + "timestamp": "2025-12-10T09:08:31.479828" }, - "test_cat_zipped_unzipped": { + "sarscov2 - fasta - unzipped - stub": { "content": [ { "0": [ @@ -43,11 +51,15 @@ "id": "test", "single_end": true }, - "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + [ + "CAT_CAT", + "pigz", + "2.8" + ] ], "file_out": [ [ @@ -55,93 +67,217 @@ "id": "test", "single_end": true }, - "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2023-10-16T14:32:49.642741302" + "timestamp": "2025-12-10T16:16:28.118094" }, - "test_cat_zipped_zipped": { + "sarscov2 - [ fasta, sizes ] - zipped": { "content": [ - [ - "MT192765.1\tGenbank\ttranscript\t259\t29667\t.\t+\t.\tID=unknown_transcript_1;geneID=orf1ab;gene_name=orf1ab", - "MT192765.1\tGenbank\tgene\t259\t21548\t.\t+\t.\tParent=unknown_transcript_1", - "MT192765.1\tGenbank\tCDS\t259\t13461\t.\t+\t0\tParent=unknown_transcript_1;exception=\"ribosomal slippage\";gbkey=CDS;gene=orf1ab;note=\"pp1ab;translated=by -1 ribosomal frameshift\";product=\"orf1ab polyprotein\";protein_id=QIK50426.1", - "MT192765.1\tGenbank\tCDS\t13461\t21548\t.\t+\t0\tParent=unknown_transcript_1;exception=\"ribosomal slippage\";gbkey=CDS;gene=orf1ab;note=\"pp1ab;translated=by -1 ribosomal frameshift\";product=\"orf1ab polyprotein\";protein_id=QIK50426.1", - "MT192765.1\tGenbank\tCDS\t21556\t25377\t.\t+\t0\tParent=unknown_transcript_1;gbkey=CDS;gene=S;note=\"structural protein\";product=\"surface glycoprotein\";protein_id=QIK50427.1", - "MT192765.1\tGenbank\tgene\t21556\t25377\t.\t+\t.\tParent=unknown_transcript_1" - ], - 78, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T16:15:56.529595" + }, + "sarscov2 - genome - error: name conflict": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "file_out": [ + + ], + "versions_cat": [ + + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:46.802978" + "timestamp": "2025-12-10T16:14:54.496538" }, - "test_cat_name_conflict": { + "sarscov2 - [ fasta, sizes ] - unzipped": { "content": [ - [ - - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:29.45394" + "timestamp": "2025-12-10T11:26:29.942203" }, - "test_cat_one_file_unzipped_zipped": { + "sarscov2 - [ gff3_gz, maf_gz ] - zipped": { "content": [ - [ - ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", - "GTTTATACCTTCCCAGGTAACAAACCAACCAACTTTCGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAATCTGT", - "GTGGCTGTCACTCGGCTGCATGCTTAGTGCACTCACGCAGTATAATTAATAACTAATTACTGTCGTTGACAGGACACGAG", - "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", - "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", - "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" - ], - 374, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gff3.gz:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gff3.gz:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:52:02.774016" + "timestamp": "2025-12-10T11:26:45.679401" }, - "test_cat_unzipped_zipped": { + "sarscov2 - fasta - zipped": { "content": [ - [ - ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", - "GTTTATACCTTCCCAGGTAACAAACCAACCAACTTTCGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAATCTGT", - "GTGGCTGTCACTCGGCTGCATGCTTAGTGCACTCACGCAGTATAATTAATAACTAATTACTGTCGTTGACAGGACACGAG", - "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", - "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", - "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" - ], - 375, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,6e9fe4042a72f2345f644f239272b7e6" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,6e9fe4042a72f2345f644f239272b7e6" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:57.581523" + "timestamp": "2025-12-10T16:16:12.439911" } } \ No newline at end of file diff --git a/modules/nf-core/cat/cat/tests/nextflow.config b/modules/nf-core/cat/cat/tests/nextflow.config new file mode 100644 index 000000000..5bc9bf50e --- /dev/null +++ b/modules/nf-core/cat/cat/tests/nextflow.config @@ -0,0 +1,6 @@ + +process { + withName: CAT_CAT { + ext.prefix = "${params.cat_prefix}" + } +} diff --git a/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config b/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config deleted file mode 100644 index ec26b0fdc..000000000 --- a/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config +++ /dev/null @@ -1,6 +0,0 @@ - -process { - withName: CAT_CAT { - ext.prefix = 'cat.txt.gz' - } -} diff --git a/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config b/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config deleted file mode 100644 index fbc79783d..000000000 --- a/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config +++ /dev/null @@ -1,8 +0,0 @@ - -process { - - withName: CAT_CAT { - ext.prefix = 'cat.txt' - } - -} diff --git a/modules/nf-core/cat/cat/tests/tags.yml b/modules/nf-core/cat/cat/tests/tags.yml deleted file mode 100644 index 37b578f52..000000000 --- a/modules/nf-core/cat/cat/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -cat/cat: - - modules/nf-core/cat/cat/** diff --git a/modules/nf-core/cat/fastq/environment.yml b/modules/nf-core/cat/fastq/environment.yml new file mode 100644 index 000000000..9b926b1ff --- /dev/null +++ b/modules/nf-core/cat/fastq/environment.yml @@ -0,0 +1,12 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=9.5 + - conda-forge::grep=3.11 + - conda-forge::gzip=1.13 + - conda-forge::lbzip2=2.5 + - conda-forge::sed=4.8 + - conda-forge::tar=1.34 diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf new file mode 100644 index 000000000..e70af3d11 --- /dev/null +++ b/modules/nf-core/cat/fastq/main.nf @@ -0,0 +1,69 @@ +process CAT_FASTQ { + tag "${meta.id}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' + : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" + + input: + tuple val(meta), path(reads, stageAs: "input*/*") + + output: + tuple val(meta), path("*.merged.fastq.gz"), emit: reads + tuple val("${task.process}"), val("cat"), eval("cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//'"), emit: versions_cat, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + def readList = reads instanceof List ? reads.collect { item -> item.toString() } : [reads.toString()] + def compress = readList[0]?.endsWith('.gz') ? '' : '| gzip' + if (meta.single_end) { + if (readList.size >= 1) { + """ + cat ${readList.join(' ')} ${compress} > ${prefix}.merged.fastq.gz + """ + } else { + error("Could not find any FASTQ files to concatenate in the process input") + } + } + else { + if (readList.size >= 2) { + def read1 = [] + def read2 = [] + readList.eachWithIndex { v, ix -> (ix & 1 ? read2 : read1) << v } + """ + cat ${read1.join(' ')} ${compress} > ${prefix}_1.merged.fastq.gz + cat ${read2.join(' ')} ${compress} > ${prefix}_2.merged.fastq.gz + """ + } else { + error("Could not find any FASTQ file pairs to concatenate in the process input") + } + } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def readList = reads instanceof List ? reads.collect { item -> item.toString() } : [reads.toString()] + if (meta.single_end) { + if (readList.size >= 1) { + """ + echo '' | gzip > ${prefix}.merged.fastq.gz + """ + } else { + error("Could not find any FASTQ files to concatenate in the process input") + } + } + else { + if (readList.size >= 2) { + """ + echo '' | gzip > ${prefix}_1.merged.fastq.gz + echo '' | gzip > ${prefix}_2.merged.fastq.gz + """ + } else { + error("Could not find any FASTQ file pairs to concatenate in the process input") + } + } +} diff --git a/modules/nf-core/cat/fastq/meta.yml b/modules/nf-core/cat/fastq/meta.yml new file mode 100644 index 000000000..6fefd6e0e --- /dev/null +++ b/modules/nf-core/cat/fastq/meta.yml @@ -0,0 +1,67 @@ +name: cat_fastq +description: Concatenates fastq files. Supports both compressed (.gz) and uncompressed inputs; uncompressed files are automatically gzip-compressed during concatenation. +keywords: + - cat + - fastq + - concatenate + - compress +tools: + - cat: + description: | + The cat utility reads files sequentially, writing them to the standard output. + documentation: https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html + licence: ["GPL-3.0-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files to be concatenated. + Accepts both gzip-compressed (.fastq.gz) and uncompressed (.fastq) files. + ontologies: [] +output: + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.merged.fastq.gz": + type: file + description: Merged fastq file + pattern: "*.{merged.fastq.gz}" + ontologies: [] + versions_cat: + - - ${task.process}: + type: string + description: The process the versions were collected from + - cat: + type: string + description: The tool name + - cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - cat: + type: string + description: The tool name + - cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//': + type: eval + description: The expression to obtain the version of the tool + +authors: + - "@joseespinosa" + - "@drpatelh" +maintainers: + - "@joseespinosa" + - "@drpatelh" diff --git a/modules/nf-core/cat/fastq/tests/main.nf.test b/modules/nf-core/cat/fastq/tests/main.nf.test new file mode 100644 index 000000000..21052d90f --- /dev/null +++ b/modules/nf-core/cat/fastq/tests/main.nf.test @@ -0,0 +1,405 @@ +nextflow_process { + + name "Test Process CAT_FASTQ" + script "../main.nf" + process "CAT_FASTQ" + tag "modules" + tag "modules_nfcore" + tag "cat" + tag "cat/fastq" + tag "gunzip" + + test("test_cat_fastq_single_end") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_same_name") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end_same_name") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_uncompressed") { + + setup { + run("GUNZIP") { + script "../../../gunzip/main.nf" + process { + """ + input[0] = Channel.of( + [[ id:'r1' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + [[ id:'r2' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ) + """ + } + } + } + + when { + process { + """ + input[0] = GUNZIP.out.gunzip + .toSortedList { a, b -> a[0].id <=> b[0].id } + .map { items -> [[ id: 'test', single_end: true ], items.collect { it[1] }] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end_uncompressed") { + + setup { + run("GUNZIP") { + script "../../../gunzip/main.nf" + process { + """ + input[0] = Channel.of( + [[ id:'a' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + [[ id:'b' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)], + [[ id:'c' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true)], + [[ id:'d' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true)] + ) + """ + } + } + } + + when { + process { + """ + input[0] = GUNZIP.out.gunzip + .toSortedList { a, b -> a[0].id <=> b[0].id } + .map { items -> [[ id: 'test', single_end: false ], items.collect { it[1] }] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_single_file") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_same_name - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end_same_name - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_single_file - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_no_files") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_paired_end_no_files") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_single_end_no_files - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_paired_end_no_files - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } +} diff --git a/modules/nf-core/cat/fastq/tests/main.nf.test.snap b/modules/nf-core/cat/fastq/tests/main.nf.test.snap new file mode 100644 index 000000000..6375b2ab2 --- /dev/null +++ b/modules/nf-core/cat/fastq/tests/main.nf.test.snap @@ -0,0 +1,588 @@ +{ + "test_cat_fastq_paired_end_no_files - stub": { + "content": [ + " Could not find any FASTQ file pairs to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:51.248685461" + }, + "test_cat_fastq_single_end_single_file": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:42.84401526" + }, + "test_cat_fastq_paired_end_same_name": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:36.820489323" + }, + "test_cat_fastq_paired_end_same_name - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:32:06.262192935" + }, + "test_cat_fastq_single_end_uncompressed": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-09T10:03:24.344628" + }, + "test_cat_fastq_paired_end_uncompressed": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-09T10:03:37.568053" + }, + "test_cat_fastq_single_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:18.859169785" + }, + "test_cat_fastq_single_end_same_name": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:30.942615287" + }, + "test_cat_fastq_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:48.827990633" + }, + "test_cat_fastq_paired_end_no_files": { + "content": [ + " Could not find any FASTQ file pairs to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:40.806088747" + }, + "test_cat_fastq_single_end_no_files - stub": { + "content": [ + " Could not find any FASTQ files to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:45.852365218" + }, + "test_cat_fastq_single_end_same_name - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:32:00.586584379" + }, + "test_cat_fastq_paired_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:25.159365603" + }, + "test_cat_fastq_single_end_no_files": { + "content": [ + " Could not find any FASTQ files to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:35.695192409" + }, + "test_cat_fastq_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:31:54.850702874" + }, + "test_cat_fastq_single_end_single_file - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T14:32:11.746498148" + } +} \ No newline at end of file diff --git a/modules/nf-core/chromograph/environment.yml b/modules/nf-core/chromograph/environment.yml index 47881b1fb..cc931c767 100644 --- a/modules/nf-core/chromograph/environment.yml +++ b/modules/nf-core/chromograph/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/chromograph/main.nf b/modules/nf-core/chromograph/main.nf index e1374e483..f575a4cf6 100644 --- a/modules/nf-core/chromograph/main.nf +++ b/modules/nf-core/chromograph/main.nf @@ -1,11 +1,12 @@ process CHROMOGRAPH { - tag "$meta.id" + // $meta.id can be [] because autozyg is not required, so use all ids + tag "${[meta, meta2, meta3, meta4, meta5, meta6, meta7].collect { meta_map -> meta_map.id }.findAll().unique().join('_') ?: 'chromograph'}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/chromograph:1.3.1--pyhdfd78af_2': - 'biocontainers/chromograph:1.3.1--pyhdfd78af_2' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/chromograph:1.3.1--pyhdfd78af_2' + : 'biocontainers/chromograph:1.3.1--pyhdfd78af_2'}" input: tuple val(meta), path(autozyg) @@ -17,79 +18,54 @@ process CHROMOGRAPH { tuple val(meta7), path(sites) output: - tuple val(meta), path("${prefix}"), emit: plots - path "versions.yml" , emit: versions + tuple val(meta), path("*.png"), emit: plots, optional: true + tuple val("${task.process}"), val('chromograph'), eval("chromograph --version | sed 's/.* //'") , topic: versions , emit: versions_chromograph when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def autozyg_param = autozyg ? "--autozyg ${autozyg}" : '' - def coverage_param = coverage ? "--coverage ${coverage}" : '' - def exome_param = exome ? "--exom ${exome}" : '' - def fracsnp_param = fracsnp ? "--fracsnp ${fracsnp}" : '' - def ideogram_param = ideogram ? "--ideogram ${ideogram}" : '' - def regions_param = regions ? "--regions ${regions}" : '' - def sites_param = sites ? "--sites ${sites}" : '' + def args = task.ext.args ?: '' + def autozyg_param = autozyg ? "--autozyg ${autozyg}" : '' + def coverage_param = coverage ? "--coverage ${coverage}" : '' + def exome_param = exome ? "--exom ${exome}" : '' + def fracsnp_param = fracsnp ? "--fracsnp ${fracsnp}" : '' + def ideogram_param = ideogram ? "--ideogram ${ideogram}" : '' + def regions_param = regions ? "--regions ${regions}" : '' + def sites_param = sites ? "--sites ${sites}" : '' - if (autozyg) { - prefix = task.ext.prefix ?: "${meta.id}" - } else if (coverage) { - prefix = task.ext.prefix ?: "${meta2.id}" - } else if (exome) { - prefix = task.ext.prefix ?: "${meta3.id}" - } else if (fracsnp) { - prefix = task.ext.prefix ?: "${meta4.id}" - } else if (ideogram) { - prefix = task.ext.prefix ?: "${meta5.id}" - } else if (regions) { - prefix = task.ext.prefix ?: "${meta6.id}" - } else { - prefix = task.ext.prefix ?: "${meta7.id}" - } """ chromograph \\ - $args \\ - $autozyg_param \\ - $coverage_param \\ - $exome_param \\ - $fracsnp_param \\ - $ideogram_param \\ - $regions_param \\ - $sites_param \\ - --outd ${prefix} + ${args} \\ + ${autozyg_param} \\ + ${coverage_param} \\ + ${exome_param} \\ + ${fracsnp_param} \\ + ${ideogram_param} \\ + ${regions_param} \\ + ${sites_param} \\ + --outd . - cat <<-END_VERSIONS > versions.yml - "${task.process}": - chromograph: \$(echo \$(chromograph --version 2>&1) | sed 's/chromograph //' ) - END_VERSIONS """ stub: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' + euploidy = args.contains('-e') || args.contains('--euploid') - if (autozyg) { - prefix = task.ext.prefix ?: "${meta.id}" - } else if (coverage) { - prefix = task.ext.prefix ?: "${meta2.id}" - } else if (exome) { - prefix = task.ext.prefix ?: "${meta3.id}" - } else if (fracsnp) { - prefix = task.ext.prefix ?: "${meta4.id}" - } else if (ideogram) { - prefix = task.ext.prefix ?: "${meta5.id}" - } else if (regions) { - prefix = task.ext.prefix ?: "${meta6.id}" - } else { - prefix = task.ext.prefix ?: "${meta7.id}" - } """ - mkdir ${prefix} + ${touchCmd(euploidy, autozyg)} + ${touchCmd(euploidy, coverage)} + ${touchCmd(euploidy, exome)} + ${touchCmd(euploidy, fracsnp)} + ${touchCmd(euploidy, ideogram)} + ${touchCmd(euploidy, regions)} + ${touchCmd(euploidy, sites)} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - chromograph: \$(echo \$(chromograph --version 2>&1) | sed 's/chromograph //' ) - END_VERSIONS """ } + +// Helper function to generate touch commands +def touchCmd(euploidy, input_file) { + def chrs = euploidy ? (1..22) + ['X', 'Y', 'M'] : [1] + input_file ? chrs.collect { chr -> "touch ${input_file}_chr${chr}.png" }.join(' ') : '' +} diff --git a/modules/nf-core/chromograph/meta.yml b/modules/nf-core/chromograph/meta.yml index 4a986dbbb..b9899f0e0 100644 --- a/modules/nf-core/chromograph/meta.yml +++ b/modules/nf-core/chromograph/meta.yml @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json name: "chromograph" description: Chromograph is a python package to create PNG images from genetics data such as BED and WIG files. @@ -24,6 +24,7 @@ input: - autozyg: type: file description: Bed file containing the regions of autozygosity + ontologies: [] - - meta2: type: map description: | @@ -32,6 +33,7 @@ input: - coverage: type: file description: Wig file containing the coverage information + ontologies: [] - - meta3: type: map description: | @@ -40,6 +42,7 @@ input: - exome: type: file description: Bed file containing the coverage for exome. + ontologies: [] - - meta4: type: map description: | @@ -48,6 +51,7 @@ input: - fracsnp: type: file description: Wig file containing the fraction of homozygous SNPs + ontologies: [] - - meta5: type: map description: | @@ -58,6 +62,7 @@ input: description: | Bed file containing information necessary for ideogram plots. Format ['chrom', 'start', 'end', 'name', 'gStain'] + ontologies: [] - - meta6: type: map description: | @@ -66,6 +71,7 @@ input: - regions: type: file description: Bed file containing UPD regions + ontologies: [] - - meta7: type: map description: | @@ -74,22 +80,41 @@ input: - sites: type: file description: Bed file containing UPD sites + ontologies: [] output: - - plots: - - meta: + plots: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - ${prefix}: + - "*.png": type: file - description: Directory containing the plots in png format - pattern: "*.png" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + description: Plot(s) in PNG format + ontologies: [] + versions_chromograph: + - - ${task.process}: + type: string + description: The process the versions were collected from + - chromograph: + type: string + description: The tool name + - chromograph --version | sed 's/.* //': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - chromograph: + type: string + description: The tool name + - chromograph --version | sed 's/.* //': + type: eval + description: The expression to obtain the version of the tool + authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/chromograph/tests/main.nf.test b/modules/nf-core/chromograph/tests/main.nf.test index 8643afe3a..050c470cb 100644 --- a/modules/nf-core/chromograph/tests/main.nf.test +++ b/modules/nf-core/chromograph/tests/main.nf.test @@ -6,33 +6,152 @@ nextflow_process { tag "modules" tag "modules_nfcore" tag "chromograph" + config "./nextflow.config" - test("test_chromograph_sites") { + test("test_chromograph_sites_wig") { + when { + params { + module_args = '' + } + process { + """ + input[0] = [[],[]] + input[1] = Channel.of( + 'fixedStep chrom=chr3 start=400601 step=100', + '11', + '22', + '33') + .collectFile(name: 'wig_input.wig', newLine: true) + .map { file -> [ [ id: file.name ], file ] } + input[2] = [[],[]] + input[3] = [[],[]] + input[4] = [[],[]] + input[5] = [[],[]] + input[6] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/updsites.bed', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_chromograph_sites_wig_euploid") { + when { + params { + module_args = '--euploid' + } + process { + """ + input[0] = [[],[]] + input[1] = Channel.of( + 'fixedStep chrom=chr3 start=400601 step=100', + '11', + '22', + '33') + .collectFile(name: 'wig_input.wig', newLine: true) + .map { file -> [ [ id: file.name ], file ] } + input[2] = [[],[]] + input[3] = [[],[]] + input[4] = [[],[]] + input[5] = [[],[]] + input[6] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/updsites.bed', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_chromograph_sites_wig_stub") { + + options "-stub" when { + params { + module_args = '' + } process { """ - input[0] = [[:],[]] - input[1] = [[:],[]] - input[2] = [[:],[]] - input[3] = [[:],[]] - input[4] = [[:],[]] - input[5] = [[:],[]] + input[0] = [[],[]] + input[1] = Channel.of( + 'fixedStep chrom=chr3 start=400601 step=100', + '11', + '22', + '33') + .collectFile(name: 'wig_input.wig', newLine: true) + .map { file -> [ [ id: file.name ], file ] } + input[2] = [[],[]] + input[3] = [[],[]] + input[4] = [[],[]] + input[5] = [[],[]] input[6] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/updsites.bed', checkIfExists: true) - ] + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/updsites.bed', checkIfExists: true) + ] """ } } then { assertAll( - {assert process.success}, - {assert process.out.plots.get(0).get(1) ==~ ".*/test"} + { assert process.success }, + { assert snapshot(process.out).match() } ) } } + test("test_chromograph_sites_wig_euploid_stub") { + + options "-stub" + + when { + params { + module_args = '--euploid' + } + process { + """ + input[0] = [[],[]] + input[1] = Channel.of( + 'fixedStep chrom=chr3 start=400601 step=100', + '11', + '22', + '33') + .collectFile(name: 'wig_input.wig', newLine: true) + .map { file -> [ [ id: file.name ], file ] } + input[2] = [[],[]] + input[3] = [[],[]] + input[4] = [[],[]] + input[5] = [[],[]] + input[6] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/updsites.bed', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } } diff --git a/modules/nf-core/chromograph/tests/main.nf.test.snap b/modules/nf-core/chromograph/tests/main.nf.test.snap new file mode 100644 index 000000000..1bf107b8a --- /dev/null +++ b/modules/nf-core/chromograph/tests/main.nf.test.snap @@ -0,0 +1,382 @@ +{ + "test_chromograph_sites_wig": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "updsites_21.png:md5,819946a2718817268668ee73f5062351", + "wig_input_chr3.png:md5,954482b960865332f37d386da5c9fb75" + ] + ] + ], + "1": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ], + "plots": [ + [ + [ + + ], + [ + "updsites_21.png:md5,819946a2718817268668ee73f5062351", + "wig_input_chr3.png:md5,954482b960865332f37d386da5c9fb75" + ] + ] + ], + "versions_chromograph": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-01-28T11:38:25.707495" + }, + "test_chromograph_sites_wig_euploid": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "updsites_1.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_10.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_11.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_12.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_13.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_14.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_15.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_16.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_17.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_18.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_19.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_2.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_20.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_21.png:md5,819946a2718817268668ee73f5062351", + "updsites_22.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_3.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_4.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_5.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_6.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_7.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_8.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_9.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_M.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_X.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_Y.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr1.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr10.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr11.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr12.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr13.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr14.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr15.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr16.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr17.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr18.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr19.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr2.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr20.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr21.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr22.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr3.png:md5,954482b960865332f37d386da5c9fb75", + "wig_input_chr4.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr5.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr6.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr7.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr8.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr9.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrM.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrX.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrY.png:md5,33d95212be5bf91fbea53500bcbba19c" + ] + ] + ], + "1": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ], + "plots": [ + [ + [ + + ], + [ + "updsites_1.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_10.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_11.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_12.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_13.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_14.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_15.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_16.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_17.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_18.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_19.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_2.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_20.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_21.png:md5,819946a2718817268668ee73f5062351", + "updsites_22.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_3.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_4.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_5.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_6.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_7.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_8.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_9.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_M.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_X.png:md5,33d95212be5bf91fbea53500bcbba19c", + "updsites_Y.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr1.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr10.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr11.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr12.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr13.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr14.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr15.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr16.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr17.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr18.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr19.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr2.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr20.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr21.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr22.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr3.png:md5,954482b960865332f37d386da5c9fb75", + "wig_input_chr4.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr5.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr6.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr7.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr8.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chr9.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrM.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrX.png:md5,33d95212be5bf91fbea53500bcbba19c", + "wig_input_chrY.png:md5,33d95212be5bf91fbea53500bcbba19c" + ] + ] + ], + "versions_chromograph": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-01-28T11:38:34.365039" + }, + "test_chromograph_sites_wig_stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "updsites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ], + "plots": [ + [ + [ + + ], + [ + "updsites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_chromograph": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-01-28T11:38:41.365186" + }, + "test_chromograph_sites_wig_euploid_stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "updsites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ], + "plots": [ + [ + [ + + ], + [ + "updsites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "updsites.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "wig_input.wig_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_chromograph": [ + [ + "CHROMOGRAPH", + "chromograph", + "1.3.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-01-28T11:38:48.971868" + } +} \ No newline at end of file diff --git a/modules/nf-core/chromograph/tests/nextflow.config b/modules/nf-core/chromograph/tests/nextflow.config new file mode 100644 index 000000000..a0db35bc9 --- /dev/null +++ b/modules/nf-core/chromograph/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: CHROMOGRAPH { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/chromograph/tests/tags.yml b/modules/nf-core/chromograph/tests/tags.yml deleted file mode 100644 index e60ad9db2..000000000 --- a/modules/nf-core/chromograph/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -chromograph: - - "modules/nf-core/chromograph/**" diff --git a/modules/nf-core/cnvnator/cnvnator/cnvnator-cnvnator.diff b/modules/nf-core/cnvnator/cnvnator/cnvnator-cnvnator.diff deleted file mode 100644 index f06d7f6c1..000000000 --- a/modules/nf-core/cnvnator/cnvnator/cnvnator-cnvnator.diff +++ /dev/null @@ -1,50 +0,0 @@ -Changes in module 'nf-core/cnvnator/cnvnator' ---- modules/nf-core/cnvnator/cnvnator/main.nf -+++ modules/nf-core/cnvnator/cnvnator/main.nf -@@ -12,11 +12,12 @@ - tuple val(meta2), path(root) - tuple val(meta3), path(fasta) - tuple val(meta4), path(fai) -+ val step - - output: -- tuple val(output_meta), path("${prefix}.root"), emit: root -- tuple val(output_meta), path("${prefix}.tab") , emit: tab, optional: true -- path "versions.yml" , emit: versions -+ tuple val(output_meta), path("${output_meta.id}_${step}.root"), emit: root -+ tuple val(output_meta), path("*.tab") , emit: tab, optional: true -+ path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when -@@ -32,7 +33,11 @@ - reference = '' - } - calls_cmd = args.contains("-call") ? "> ${prefix}.tab" : '' -+ mv_cmd = "mv ${prefix}.root ${prefix}_${step}.root" -+ steps = ["his", "stat", "partition", "call"] -+ cp_cmd = steps.contains(step) ? "cp ${root} ${prefix}.root" :"" - """ -+ $cp_cmd - cnvnator \\ - -root ${prefix}.root \\ - $args \\ -@@ -40,6 +45,7 @@ - $input_cmd \\ - $calls_cmd - -+ $mv_cmd - cat <<-END_VERSIONS > versions.yml - "${task.process}": - CNVnator: \$(echo \$(cnvnator 2>&1 | sed -n '3p' | sed 's/CNVnator v//')) -@@ -52,7 +58,7 @@ - output_meta = bam ? meta : meta2 - def calls_cmd = args.contains("-call") ? "touch ${prefix}.tab" : '' - """ -- touch ${prefix}.root -+ touch ${prefix}_${step}.root - $calls_cmd - - cat <<-END_VERSIONS > versions.yml - -************************************************************ diff --git a/modules/nf-core/cnvnator/cnvnator/environment.yml b/modules/nf-core/cnvnator/cnvnator/environment.yml index 9cd8ebf35..6f421c9cc 100644 --- a/modules/nf-core/cnvnator/cnvnator/environment.yml +++ b/modules/nf-core/cnvnator/cnvnator/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/cnvnator/cnvnator/main.nf b/modules/nf-core/cnvnator/cnvnator/main.nf index 66427cd12..b7362cba0 100644 --- a/modules/nf-core/cnvnator/cnvnator/main.nf +++ b/modules/nf-core/cnvnator/cnvnator/main.nf @@ -4,20 +4,20 @@ process CNVNATOR_CNVNATOR { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/cnvnator:0.4.1--py310h2dce045_7': - 'biocontainers/cnvnator:0.4.1--py310h2dce045_7' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a5/a54de0a286dcc6f73972be37104995ba96e37ef404f9d2bff294a7e8be5b7a92/data': + 'community.wave.seqera.io/library/cnvnator:0.4.1--5a467cfadbbc668d' }" input: tuple val(meta), path(bam), path(bai) - tuple val(meta2), path(root) + tuple val(meta2), path(root, stageAs:'input/') tuple val(meta3), path(fasta) tuple val(meta4), path(fai) - val step + val step // Without this parameter Nextflow can't distinguish between different steps, and resume becomes unreliable across the workflow chain output: - tuple val(output_meta), path("${output_meta.id}_${step}.root"), emit: root - tuple val(output_meta), path("*.tab") , emit: tab, optional: true - path "versions.yml" , emit: versions + tuple val(output_meta), path("${prefix}.root"), emit: root, optional: true + tuple val(output_meta), path("${prefix}.tab") , emit: tab, optional: true + tuple val("${task.process}"), val('cnvnator'), eval("cnvnator 2>&1 | sed -n '3s/CNVnator v//p'"), topic: versions, emit: versions_cnvnator when: task.ext.when == null || task.ext.when @@ -26,44 +26,30 @@ process CNVNATOR_CNVNATOR { def args = task.ext.args ?: '' def input_cmd = bam ? "-tree ${bam}" : '' output_meta = bam ? meta : meta2 - prefix = task.ext.prefix ?: bam ? "${meta.id}" : "${meta2.id}" + prefix = task.ext.prefix ?: "${output_meta.id}" if (fasta) { reference = fasta.isDirectory() ? "-d ${fasta}" : "-fasta ${fasta}" } else { reference = '' } - calls_cmd = args.contains("-call") ? "> ${prefix}.tab" : '' - mv_cmd = "mv ${prefix}.root ${prefix}_${step}.root" - steps = ["his", "stat", "partition", "call"] - cp_cmd = steps.contains(step) ? "cp ${root} ${prefix}.root" :"" + def calls_cmd = args.contains("-call") ? "> ${prefix}.tab" : '' + cp_cmd = root ? "cp input/* ${prefix}.root" :"" """ - $cp_cmd + ${cp_cmd} cnvnator \\ -root ${prefix}.root \\ - $args \\ - $reference \\ - $input_cmd \\ - $calls_cmd - - $mv_cmd - cat <<-END_VERSIONS > versions.yml - "${task.process}": - CNVnator: \$(echo \$(cnvnator 2>&1 | sed -n '3p' | sed 's/CNVnator v//')) - END_VERSIONS + ${args} \\ + ${reference} \\ + ${input_cmd} \\ + ${calls_cmd} """ stub: def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: bam ? "${meta.id}" : "${meta2.id}" output_meta = bam ? meta : meta2 - def calls_cmd = args.contains("-call") ? "touch ${prefix}.tab" : '' + prefix = task.ext.prefix ?: "${output_meta.id}" + def touch_cmd = args.contains("-call") ? "touch ${prefix}.tab" : "touch ${prefix}.root" """ - touch ${prefix}_${step}.root - $calls_cmd - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - CNVnator: \$(echo \$(cnvnator 2>&1 | sed -n '3p' | sed 's/CNVnator v//')) - END_VERSIONS + ${touch_cmd} """ } diff --git a/modules/nf-core/cnvnator/cnvnator/meta.yml b/modules/nf-core/cnvnator/cnvnator/meta.yml index 7ad6b4068..c347493e0 100644 --- a/modules/nf-core/cnvnator/cnvnator/meta.yml +++ b/modules/nf-core/cnvnator/cnvnator/meta.yml @@ -1,6 +1,6 @@ name: "cnvnator_cnvnator" -description: CNVnator is a command line tool for CNV/CNA analysis from depth-of-coverage - by mapped reads. +description: CNVnator is a command line tool for CNV/CNA analysis from + depth-of-coverage by mapped reads. keywords: - cnvnator - cnv @@ -11,7 +11,8 @@ tools: homepage: "https://github.com/abyzovlab/CNVnator" documentation: "https://github.com/abyzovlab/CNVnator/blob/master/README.md" tool_dev_url: "https://github.com/abyzovlab/CNVnator" - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:cnvnator input: - - meta: @@ -23,10 +24,12 @@ input: type: file description: Sorted BAM/CRAM/SAM file pattern: "*.bam" + ontologies: [] - bai: type: file description: Sorted BAM/CRAM/SAM file pattern: "*.bam" + ontologies: [] - - meta2: type: map description: | @@ -36,6 +39,7 @@ input: type: file description: ROOT file pattern: "*.root" + ontologies: [] - - meta3: type: map description: | @@ -45,6 +49,7 @@ input: type: file description: Path to a directory containing fasta files or a fasta file pattern: "*.fa" + ontologies: [] - - meta4: type: map description: | @@ -54,9 +59,13 @@ input: type: file description: Path to a fasta file index pattern: "*.fai" + ontologies: [] + - step: + type: string + description: One of "his", "rd", "call", "stat", and "partition" output: - - root: - - output_meta: + root: + - - output_meta: type: map description: | Groovy Map containing sample information @@ -65,8 +74,9 @@ output: type: file description: A ROOT file pattern: "*.root" - - tab: - - output_meta: + ontologies: [] + tab: + - - output_meta: type: map description: | Groovy Map containing sample information @@ -75,11 +85,29 @@ output: type: file description: A tab file containing cnvnator calls pattern: "*.tab" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 + versions_cnvnator: + - - ${task.process}: + type: string + description: The name of the process + - cnvnator: + type: string + description: The name of the tool + - cnvnator 2>&1 | sed -n '3s/CNVnator v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - cnvnator: + type: string + description: The name of the tool + - cnvnator 2>&1 | sed -n '3s/CNVnator v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test new file mode 100644 index 000000000..fc086ef97 --- /dev/null +++ b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test @@ -0,0 +1,133 @@ +nextflow_process { + + name "Test Process CNVNATOR_CNVNATOR" + config "./nextflow.config" + script "../main.nf" + process "CNVNATOR_CNVNATOR" + + tag "modules" + tag "modules_nfcore" + tag "cnvnator" + tag "cnvnator/cnvnator" + + setup { + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_RD") { + script "../main.nf" + process { + """ + input[0] = [ + [id:'test',single_end:false],// meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.bam.bai', checkIfExists:true) + ] + input[1] = [[:],[]] + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "rd" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_HIST") { + script "../main.nf" + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_RD.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "his" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_STAT") { + script "../main.nf" + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_HIST.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "stat" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_PARTITION") { + script "../main.nf" + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_STAT.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "partition" + """ + } + } + } + + test("test_cnvnator") { + when { + params { + cnvnator_rd_args = '-chrom chr22' + cnvnator_hist_args = '-his 1000' + cnvnator_stat_args = '-stat 1000' + cnvnator_partition_args = '-partition 1000' + cnvnator_args = '-call 1000' + } + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_PARTITION.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "call" + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.tab, + process.out.findAll { key, val -> key.startsWith("versions") }, + process.out.root.collect{ file(it[1]).name } + ).match()} + ) + } + } + + + test("test_cnvnator -- stub") { + options '-stub' + when { + params { + cnvnator_rd_args = '-chrom chr22' + cnvnator_hist_args = '-his 1000' + cnvnator_stat_args = '-stat 1000' + cnvnator_partition_args = '-partition 1000' + cnvnator_args = '-call 1000' + } + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_PARTITION.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "call" + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test.snap b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test.snap new file mode 100644 index 000000000..07ebd04fb --- /dev/null +++ b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test.snap @@ -0,0 +1,90 @@ +{ + "test_cnvnator": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.tab:md5,56246f1dab5e62cd7902963562f889fd" + ] + ], + { + "versions_cnvnator": [ + [ + "CNVNATOR_CNVNATOR", + "cnvnator", + "0.4.1" + ] + ] + }, + [ + "test.root" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-06T10:36:02.494664" + }, + "test_cnvnator -- stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "CNVNATOR_CNVNATOR", + "cnvnator", + "0.4.1" + ] + ], + "root": [ + + ], + "tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_cnvnator": [ + [ + "CNVNATOR_CNVNATOR", + "cnvnator", + "0.4.1" + ] + ] + }, + { + "versions_cnvnator": [ + [ + "CNVNATOR_CNVNATOR", + "cnvnator", + "0.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-06T13:37:25.433539" + } +} \ No newline at end of file diff --git a/modules/nf-core/cnvnator/cnvnator/tests/nextflow.config b/modules/nf-core/cnvnator/cnvnator/tests/nextflow.config new file mode 100644 index 000000000..9a9f9a920 --- /dev/null +++ b/modules/nf-core/cnvnator/cnvnator/tests/nextflow.config @@ -0,0 +1,21 @@ +process { + withName: "CNVNATOR_RD" { + ext.args = {params.cnvnator_rd_args} + } + + withName: "CNVNATOR_HIST" { + ext.args = {params.cnvnator_hist_args} + } + + withName: "CNVNATOR_STAT" { + ext.args = {params.cnvnator_stat_args} + } + + withName: "CNVNATOR_PARTITION" { + ext.args = {params.cnvnator_partition_args} + } + + withName: "CNVNATOR_CNVNATOR" { + ext.args = {params.cnvnator_args} + } +} diff --git a/modules/nf-core/cnvnator/convert2vcf/environment.yml b/modules/nf-core/cnvnator/convert2vcf/environment.yml index 9cd8ebf35..6f421c9cc 100644 --- a/modules/nf-core/cnvnator/convert2vcf/environment.yml +++ b/modules/nf-core/cnvnator/convert2vcf/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/cnvnator/convert2vcf/main.nf b/modules/nf-core/cnvnator/convert2vcf/main.nf index 87dd031a3..0d52b80fb 100644 --- a/modules/nf-core/cnvnator/convert2vcf/main.nf +++ b/modules/nf-core/cnvnator/convert2vcf/main.nf @@ -4,15 +4,15 @@ process CNVNATOR_CONVERT2VCF { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/cnvnator:0.4.1--py310h2dce045_7': - 'biocontainers/cnvnator:0.4.1--py310h2dce045_7' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a5/a54de0a286dcc6f73972be37104995ba96e37ef404f9d2bff294a7e8be5b7a92/data': + 'community.wave.seqera.io/library/cnvnator:0.4.1--5a467cfadbbc668d' }" input: tuple val(meta), path(calls) output: tuple val(meta), path("*.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('cnvnator'), eval("cnvnator 2>&1 | sed -n '3s/CNVnator v//p'"), topic: versions, emit: versions_cnvnator when: task.ext.when == null || task.ext.when @@ -25,22 +25,14 @@ process CNVNATOR_CONVERT2VCF { ${calls} \\ $args \\ > ${prefix}.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - CNVnator : \$(echo \$(cnvnator 2>&1 | sed -n '3p' | sed 's/CNVnator v//')) - END_VERSIONS """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf + echo ${args} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - CNVnator : \$(echo \$(cnvnator 2>&1 | sed -n '3p' | sed 's/CNVnator v//')) - END_VERSIONS + touch ${prefix}.vcf """ } diff --git a/modules/nf-core/cnvnator/convert2vcf/meta.yml b/modules/nf-core/cnvnator/convert2vcf/meta.yml index 3d686c2f1..57960b81f 100644 --- a/modules/nf-core/cnvnator/convert2vcf/meta.yml +++ b/modules/nf-core/cnvnator/convert2vcf/meta.yml @@ -23,9 +23,11 @@ input: type: file description: A tab file containing CNVnator calls pattern: "*.tab" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -34,11 +36,30 @@ output: type: file description: CNVnator calls in vcf format pattern: "*.vcf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_cnvnator: + - - ${task.process}: + type: string + description: The name of the process + - cnvnator: + type: string + description: The name of the tool + - cnvnator 2>&1 | sed -n '3s/CNVnator v//p': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - cnvnator: + type: string + description: The name of the tool + - cnvnator 2>&1 | sed -n '3s/CNVnator v//p': + type: eval + description: The expression to obtain the version of the tool + authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test new file mode 100644 index 000000000..c1d239682 --- /dev/null +++ b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test @@ -0,0 +1,141 @@ +nextflow_process { + + name "Test Process CNVNATOR_CONVERT2VCF" + config "./nextflow.config" + script "../main.nf" + process "CNVNATOR_CONVERT2VCF" + + tag "modules" + tag "modules_nfcore" + tag "cnvnator" + tag "cnvnator/cnvnator" + tag "cnvnator/convert2vcf" + + setup { + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_RD") { + script "../../cnvnator/main.nf" + + process { + """ + input[0] = [ + [id:'test',single_end:false],// meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists:true) + ] + input[1] = [[:],[]] + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "rd" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_HIST") { + script "../../cnvnator/main.nf" + + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_RD.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "his" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_STAT") { + script "../../cnvnator/main.nf" + + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_HIST.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "stat" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_PARTITION") { + script "../../cnvnator/main.nf" + + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_STAT.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "partition" + """ + } + } + + run("CNVNATOR_CNVNATOR", alias: "CNVNATOR_CALL") { + script "../../cnvnator/main.nf" + + process { + """ + input[0] = [[:],[],[]] + input[1] = CNVNATOR_PARTITION.out.root + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = "call" + """ + } + } + } + + test("test_cnvnator_convert2vcf") { + + when { + params { + cnvnator_rd_args = '-chrom chr22' + cnvnator_hist_args = '-his 1000' + cnvnator_stat_args = '-stat 1000' + cnvnator_partition_args = '-partition 1000' + cnvnator_args = '-call 1000' + } + process { + """ + input[0] = CNVNATOR_CALL.out.tab + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") }, + path(process.out.vcf[0][1]).vcf.variantsMD5 + ).match() } + ) + } + } + + + test("test_cnvnator_convert2vcf -- stub") { + options '-stub' + when { + params { + cnvnator_rd_args = '-chrom chr22' + cnvnator_hist_args = '-his 1000' + cnvnator_stat_args = '-stat 1000' + cnvnator_partition_args = '-partition 1000' + cnvnator_args = '-call 1000' + } + process { + """ + input[0] = CNVNATOR_CALL.out.tab + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap new file mode 100644 index 000000000..d51b4befb --- /dev/null +++ b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap @@ -0,0 +1,64 @@ +{ + "test_cnvnator_convert2vcf": { + "content": [ + { + "versions_cnvnator": [ + [ + "CNVNATOR_CONVERT2VCF", + "cnvnator", + "0.4.1" + ] + ] + }, + "b47837c71432a5ffc854c7936b5966d0" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T13:53:33.545892" + }, + "test_cnvnator_convert2vcf -- stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "CNVNATOR_CONVERT2VCF", + "cnvnator", + "0.4.1" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_cnvnator": [ + [ + "CNVNATOR_CONVERT2VCF", + "cnvnator", + "0.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-06T13:38:10.965597" + } +} \ No newline at end of file diff --git a/modules/nf-core/cnvnator/convert2vcf/tests/nextflow.config b/modules/nf-core/cnvnator/convert2vcf/tests/nextflow.config new file mode 100644 index 000000000..9a9f9a920 --- /dev/null +++ b/modules/nf-core/cnvnator/convert2vcf/tests/nextflow.config @@ -0,0 +1,21 @@ +process { + withName: "CNVNATOR_RD" { + ext.args = {params.cnvnator_rd_args} + } + + withName: "CNVNATOR_HIST" { + ext.args = {params.cnvnator_hist_args} + } + + withName: "CNVNATOR_STAT" { + ext.args = {params.cnvnator_stat_args} + } + + withName: "CNVNATOR_PARTITION" { + ext.args = {params.cnvnator_partition_args} + } + + withName: "CNVNATOR_CNVNATOR" { + ext.args = {params.cnvnator_args} + } +} diff --git a/modules/nf-core/deepvariant/rundeepvariant/deepvariant-rundeepvariant.diff b/modules/nf-core/deepvariant/rundeepvariant/deepvariant-rundeepvariant.diff new file mode 100644 index 000000000..46290df51 --- /dev/null +++ b/modules/nf-core/deepvariant/rundeepvariant/deepvariant-rundeepvariant.diff @@ -0,0 +1,24 @@ +Changes in component 'nf-core/deepvariant/rundeepvariant' +'modules/nf-core/deepvariant/rundeepvariant/meta.yml' is unchanged +Changes in 'deepvariant/rundeepvariant/main.nf': +--- modules/nf-core/deepvariant/rundeepvariant/main.nf ++++ modules/nf-core/deepvariant/rundeepvariant/main.nf +@@ -46,7 +46,12 @@ + ${regions} \\ + ${par_regions} \\ + --intermediate_results_dir=tmp \\ +- --num_shards=${task.cpus} ++ --num_shards=${task.cpus} 2>&1 | tee deepvariant.log ++ ++ if grep -qi "queue\.Empty" deepvariant.log; then ++ echo "ERROR: Fatal error detected in tool log" >&2 ++ exit 1 ++ fi + """ + + stub: + +'modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap' is unchanged +'modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config' is unchanged +'modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test' is unchanged +************************************************************ diff --git a/modules/nf-core/deepvariant/rundeepvariant/main.nf b/modules/nf-core/deepvariant/rundeepvariant/main.nf index 41338f28c..9a19b1e1d 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/main.nf +++ b/modules/nf-core/deepvariant/rundeepvariant/main.nf @@ -6,7 +6,7 @@ process DEEPVARIANT_RUNDEEPVARIANT { // https://github.com/bioconda/bioconda-recipes/pull/45214#issuecomment-1890937836 // BUG https://github.com/nf-core/modules/issues/1754 // BUG https://github.com/bioconda/bioconda-recipes/issues/30310 - container "docker.io/google/deepvariant:1.8.0" + container "docker.io/google/deepvariant:1.9.0" input: tuple val(meta), path(input), path(index), path(intervals) @@ -16,11 +16,12 @@ process DEEPVARIANT_RUNDEEPVARIANT { tuple val(meta5), path(par_bed) output: - tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf - tuple val(meta), path("${prefix}.vcf.gz.tbi") , emit: vcf_tbi - tuple val(meta), path("${prefix}.g.vcf.gz") , emit: gvcf - tuple val(meta), path("${prefix}.g.vcf.gz.tbi"), emit: gvcf_tbi - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf + tuple val(meta), path("${prefix}.vcf.gz.tbi") , emit: vcf_tbi + tuple val(meta), path("${prefix}.g.vcf.gz") , emit: gvcf + tuple val(meta), path("${prefix}.g.vcf.gz.tbi") , emit: gvcf_tbi + tuple val(meta), path("${prefix}.visual_report.html"), emit: report, optional: true + tuple val("${task.process}"), val('deepvariant'), eval("/opt/deepvariant/bin/run_deepvariant --version | sed 's/^.*version //'"), topic: versions, emit: versions_deepvariant when: task.ext.when == null || task.ext.when @@ -45,12 +46,12 @@ process DEEPVARIANT_RUNDEEPVARIANT { ${regions} \\ ${par_regions} \\ --intermediate_results_dir=tmp \\ - --num_shards=${task.cpus} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - deepvariant: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) - END_VERSIONS + --num_shards=${task.cpus} 2>&1 | tee deepvariant.log + + if grep -qi "queue\\.Empty\\|BrokenPipeError" deepvariant.log; then + echo "ERROR: Fatal error detected in tool log" >&2 + exit 1 + fi """ stub: @@ -60,14 +61,8 @@ process DEEPVARIANT_RUNDEEPVARIANT { } prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf.gz - touch ${prefix}.vcf.gz.tbi - touch ${prefix}.g.vcf.gz - touch ${prefix}.g.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - deepvariant: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) - END_VERSIONS - """ + echo "stub" | gzip > ${prefix}.vcf.gz + echo "stub" | gzip > ${prefix}.vcf.gz.tbi + echo "stub" | gzip > ${prefix}.g.vcf.gz + echo "stub" | gzip > ${prefix}.g.vcf.gz.tbi """ } diff --git a/modules/nf-core/deepvariant/rundeepvariant/meta.yml b/modules/nf-core/deepvariant/rundeepvariant/meta.yml index 29b45ff91..3e4e97efb 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/meta.yml +++ b/modules/nf-core/deepvariant/rundeepvariant/meta.yml @@ -1,14 +1,14 @@ name: deepvariant_rundeepvariant -description: DeepVariant is an analysis pipeline that uses a deep neural network to - call genetic variants from next-generation DNA sequencing data +description: DeepVariant is an analysis pipeline that uses a deep neural network + to call genetic variants from next-generation DNA sequencing data keywords: - variant calling - machine learning - neural network tools: - deepvariant: - description: DeepVariant is an analysis pipeline that uses a deep neural network - to call genetic variants from next-generation DNA sequencing data + description: DeepVariant is an analysis pipeline that uses a deep neural + network to call genetic variants from next-generation DNA sequencing data homepage: https://github.com/google/deepvariant documentation: https://github.com/google/deepvariant tool_dev_url: https://github.com/google/deepvariant @@ -25,13 +25,16 @@ input: type: file description: BAM/CRAM file pattern: "*.bam/cram" + ontologies: [] - index: type: file description: Index of BAM/CRAM file pattern: "*.bai/crai" + ontologies: [] - intervals: type: file description: file containing intervals + ontologies: [] - - meta2: type: map description: | @@ -41,6 +44,7 @@ input: type: file description: The reference fasta file pattern: "*.fasta" + ontologies: [] - - meta3: type: map description: | @@ -50,6 +54,7 @@ input: type: file description: Index of reference fasta file pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -59,6 +64,7 @@ input: type: file description: GZI index of reference fasta file pattern: "*.gzi" + ontologies: [] - - meta5: type: map description: | @@ -68,9 +74,10 @@ input: type: file description: BED file containing PAR regions pattern: "*.bed" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -79,8 +86,10 @@ output: type: file description: Compressed VCF file pattern: "*.vcf.gz" - - vcf_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + vcf_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -89,8 +98,9 @@ output: type: file description: Tabix index file of compressed VCF pattern: "*.vcf.gz.tbi" - - gvcf: - - meta: + ontologies: [] + gvcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -99,8 +109,10 @@ output: type: file description: Compressed GVCF file pattern: "*.g.vcf.gz" - - gvcf_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + gvcf_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -109,11 +121,42 @@ output: type: file description: Tabix index file of compressed GVCF pattern: "*.g.vcf.gz.tbi" - - versions: - - versions.yml: + ontologies: [] + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.visual_report.html: type: file - description: File containing software versions - pattern: "versions.yml" + description: Visual report in HTML format + pattern: "*.html" + optional: true + ontologies: [] + versions_deepvariant: + - - ${task.process}: + type: string + description: The process the versions were collected from + - deepvariant: + type: string + description: The tool name + - /opt/deepvariant/bin/run_deepvariant --version | sed 's/^.*version //': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - deepvariant: + type: string + description: The tool name + - /opt/deepvariant/bin/run_deepvariant --version | sed 's/^.*version //': + type: eval + description: The expression to obtain the version of the tool + authors: - "@abhi18av" - "@ramprasadn" diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test index 0790fb813..b22ca383f 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test @@ -8,11 +8,14 @@ nextflow_process { tag "deepvariant" tag "modules" tag "modules_nfcore" + config "./nextflow.config" test("homo_sapiens - [bam, bai] - fasta - fai") { - when { - config "./nextflow.config" + when { + params { + module_args = '--regions=\"chr22:0-40001\" --model_type=WGS' + } process { """ input[0] = [ @@ -48,9 +51,11 @@ nextflow_process { } test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai") { - config "./nextflow-intervals.config" when { + params { + module_args = '--model_type=WGS' + } process { """ input[0] = [ @@ -86,9 +91,11 @@ nextflow_process { } test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed") { - config "./nextflow-non-autosomal-calling.config" - tag "test" + when { + params { + module_args = '--model_type=WGS --haploid_contigs chr22' + } process { """ input[0] = [ @@ -125,9 +132,96 @@ nextflow_process { } test("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai") { + + when { + params { + module_args = '--regions=\"chr22:0-40001\" --model_type=WGS' + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + [] + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true) + ] + input[3] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [bam, bai] - fasta - fai - stub") { + + options "-stub" + when { - config "./nextflow.config" + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + [] + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai - stub") { + + options "-stub" + + when { + params { + module_args = '' + } process { """ input[0] = [ diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap index 8e836336d..4ed36cb84 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap @@ -8,7 +8,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "1": [ @@ -17,7 +17,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], "2": [ @@ -26,7 +26,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "3": [ @@ -35,11 +35,18 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] ], "4": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ], "gvcf": [ [ @@ -47,7 +54,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "gvcf_tbi": [ @@ -56,8 +63,11 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -65,7 +75,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "vcf_tbi": [ @@ -74,19 +84,23 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], - "versions": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-14T08:16:22.036932742" + "timestamp": "2026-01-30T10:26:37.893603098" }, "homo_sapiens - [bam, bai] - fasta - fai": { "content": [ @@ -97,7 +111,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "1": [ @@ -106,7 +120,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], "2": [ @@ -115,7 +129,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "3": [ @@ -124,11 +138,18 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] ], "4": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ], "gvcf": [ [ @@ -136,7 +157,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "gvcf_tbi": [ @@ -145,8 +166,11 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -154,7 +178,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "vcf_tbi": [ @@ -163,19 +187,23 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], - "versions": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-14T08:13:35.621497498" + "timestamp": "2026-01-30T10:23:01.002396661" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai": { "content": [ @@ -186,7 +214,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "1": [ @@ -195,7 +223,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], "2": [ @@ -204,7 +232,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "3": [ @@ -213,11 +241,18 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] ], "4": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ], "gvcf": [ [ @@ -225,7 +260,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,6251a87945e530ca61a989d7187d89dc" + "test_out.g.vcf.gz:md5,89b2e47883a65bb9cae8f173e782bb17" ] ], "gvcf_tbi": [ @@ -234,8 +269,11 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,32ca0d6713b96ed4ce07c79421bb04a9" + "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -243,7 +281,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,cf14200d683c17a6e433bb076d487fee" + "test_out.vcf.gz:md5,707212230030c8c3efbe5c2e0428da03" ] ], "vcf_tbi": [ @@ -252,19 +290,23 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,e9bcd1d1f5280e0d76ed8fd31f27bd59" + "test_out.vcf.gz.tbi:md5,248648ca03f5fda904ebbef8821e0e37" ] ], - "versions": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-14T08:14:32.23781232" + "timestamp": "2026-01-30T10:24:41.218929693" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed": { "content": [ @@ -275,7 +317,213 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,b79936a7bf53fa4ee7e5866664e37d56" + "test_out.vcf.gz:md5,b3d1a03998c435d8c37be7c9c868f3c0" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz.tbi:md5,d57a16c0fda381a7bf659789d889a9d4" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz:md5,61833a909ae1bc176b47a5afc9fdc517" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz.tbi:md5,673ce95e6701a5e7d58ea2ab93440b27" + ] + ], + "4": [ + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz:md5,61833a909ae1bc176b47a5afc9fdc517" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz.tbi:md5,673ce95e6701a5e7d58ea2ab93440b27" + ] + ], + "report": [ + + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz:md5,b3d1a03998c435d8c37be7c9c868f3c0" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz.tbi:md5,d57a16c0fda381a7bf659789d889a9d4" + ] + ], + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-30T10:25:39.678376571" + }, + "homo_sapiens - [bam, bai] - fasta - fai - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "4": [ + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "report": [ + + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-30T10:27:08.029325062" + }, + "homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_out.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" ] ], "1": [ @@ -284,7 +532,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,22f9f4c6c8c1faa8b129eddf32b445b8" + "test_out.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" ] ], "2": [ @@ -293,7 +541,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,c82ce85ed16dcabe411995c52aaffd85" + "test_out.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" ] ], "3": [ @@ -302,11 +550,18 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,6420a456b0507c70c8423293395c29bc" + "test_out.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" ] ], "4": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + + ], + "5": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ], "gvcf": [ [ @@ -314,7 +569,7 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,c82ce85ed16dcabe411995c52aaffd85" + "test_out.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" ] ], "gvcf_tbi": [ @@ -323,8 +578,11 @@ "id": "test", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,6420a456b0507c70c8423293395c29bc" + "test_out.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" ] + ], + "report": [ + ], "vcf": [ [ @@ -332,7 +590,7 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,b79936a7bf53fa4ee7e5866664e37d56" + "test_out.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" ] ], "vcf_tbi": [ @@ -341,18 +599,22 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz.tbi:md5,22f9f4c6c8c1faa8b129eddf32b445b8" + "test_out.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" ] ], - "versions": [ - "versions.yml:md5,cd692ea876a00da762fd4608c9f40f01" + "versions_deepvariant": [ + [ + "DEEPVARIANT_RUNDEEPVARIANT", + "deepvariant", + "1.9.0" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-14T08:15:29.680851997" + "timestamp": "2026-01-30T10:27:35.653099478" } } \ No newline at end of file diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config deleted file mode 100644 index 78d8d5982..000000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - - withName: DEEPVARIANT_RUNDEEPVARIANT { - ext.args = '--model_type=WGS ' - ext.prefix = { "${meta.id}_out" } - } - -} diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config deleted file mode 100644 index 6d265292a..000000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - - withName: DEEPVARIANT_RUNDEEPVARIANT { - ext.args = '--model_type=WGS --haploid_contigs chr22' - ext.prefix = { "${meta.id}_out" } - } - -} diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config index 77e355cae..9693059b8 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config @@ -1,8 +1,6 @@ process { - withName: DEEPVARIANT_RUNDEEPVARIANT { - ext.args = ' --regions=\"chr22:0-40001\" --model_type=WGS ' - ext.prefix = { "${meta.id}_out" } - } - + ext.args = params.module_args + ext.prefix = { "${meta.id}_out" } + } } diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml b/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml deleted file mode 100644 index 958b8e414..000000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -deepvariant/rundeepvariant: - - modules/nf-core/deepvariant/rundeepvariant/** diff --git a/modules/nf-core/eklipse/main.nf b/modules/nf-core/eklipse/main.nf deleted file mode 100644 index 98c577895..000000000 --- a/modules/nf-core/eklipse/main.nf +++ /dev/null @@ -1,59 +0,0 @@ - -process EKLIPSE { - tag "$meta.id" - label 'process_single' - - // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/eklipse:1.8--hdfd78af_1': - 'biocontainers/eklipse:1.8--hdfd78af_1' }" - - input: - tuple val(meta), path(bam), path(bai) - path ref_gb - - output: - tuple val(meta), path("*deletions.csv") , emit: deletions - tuple val(meta), path("*genes.csv") , emit: genes - tuple val(meta), path("*.png") , emit: circos - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def ref_gb = ref_gb ? "$ref_gb" : "/usr/local/bin/data/NC_012920.1.gb" - def VERSION = "1.8" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. - """ - echo "$bam\t${prefix}" > infile.txt - eKLIPse.py \\ - -in infile.txt \\ - $args \\ - -ref $ref_gb - mv eKLIPse_*/eKLIPse_deletions.csv eKLIPse_${prefix}_deletions.csv - mv eKLIPse_*/eKLIPse_genes.csv eKLIPse_${prefix}_genes.csv - mv eKLIPse_*/eKLIPse_${prefix}.png eKLIPse_${prefix}.png - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - eklipse: $VERSION - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.8" - """ - touch eKLIPse_${prefix}_deletions.csv - touch eKLIPse_${prefix}_genes.csv - touch eKLIPse_${prefix}.png - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - eklipse: $VERSION - END_VERSIONS - """ -} diff --git a/modules/nf-core/eklipse/meta.yml b/modules/nf-core/eklipse/meta.yml deleted file mode 100644 index cf3191959..000000000 --- a/modules/nf-core/eklipse/meta.yml +++ /dev/null @@ -1,78 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json -name: "eklipse" -description: tool for detection and quantification of large mtDNA rearrangements. -keywords: - - eklipse - - mitochondria - - mtDNA - - circos - - deletion - - SV -tools: - - "eklipse": - description: "tool for detection and quantification of large mtDNA rearrangements." - homepage: "https://github.com/dooguypapua/eKLIPse/tree/master" - documentation: "https://github.com/dooguypapua/eKLIPse/tree/master" - tool_dev_url: "https://github.com/dooguypapua/eKLIPse/tree/master" - doi: "10.1038/s41436-018-0350-8" - licence: ["GNU General Public v3 or later (GPL v3+)"] - identifier: "" -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: MT BAM/SAM file - pattern: "*.{bam,sam}" - - bai: - type: file - description: MT BAM/SAM index file - pattern: "*.{bai,sai}" - - - ref_gb: - type: file - description: mtDNA reference genome in Genbank format, optional if empty NC_012920.1.gb - will be used - pattern: "*.{gb}" -output: - - deletions: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*deletions.csv": - type: file - description: csv file with deletion information - pattern: "*deletions.csv" - - genes: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*genes.csv": - type: file - description: csv file with gene information - pattern: "*genes.csv" - - circos: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.png": - type: file - description: png file with circos plot of mt - pattern: "*.{png}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@Lucpen" -maintainers: - - "@Lucpen" diff --git a/modules/nf-core/eklipse/tests/main.nf.test b/modules/nf-core/eklipse/tests/main.nf.test deleted file mode 100644 index fb0be6d43..000000000 --- a/modules/nf-core/eklipse/tests/main.nf.test +++ /dev/null @@ -1,36 +0,0 @@ -nextflow_process { - - name "Test Process EKLIPSE" - script "../main.nf" - process "EKLIPSE" - tag "modules" - tag "modules_nfcore" - tag "eklipse" - - test("homo_sapiens [bam]") { - - when { - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test_illumina_mt.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test_illumina_mt.bam.bai', checkIfExists: true) - ] - input[1] = [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.NC_012920_1.gb', checkIfExists: true) ] - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(file(process.out.deletions[0][1]), - file(process.out.genes[0][1]), - file(process.out.circos[0][1]), - file(process.out.versions[0])).match() - } - ) - } - } -} diff --git a/modules/nf-core/eklipse/tests/main.nf.test.snap b/modules/nf-core/eklipse/tests/main.nf.test.snap deleted file mode 100644 index 5969a1da0..000000000 --- a/modules/nf-core/eklipse/tests/main.nf.test.snap +++ /dev/null @@ -1,11 +0,0 @@ -{ - "homo_sapiens [bam]": { - "content": [ - "eKLIPse_test_deletions.csv:md5,8bcfdb8f3e8a63dcd211c2a53b6ca0a7", - "eKLIPse_test_genes.csv:md5,ec1a1f31d018ca66a46d8a2d17bc8d18", - "eKLIPse_test.png:md5,d1ea2a548bc4f8d321b1128a61ea8b0a", - "versions.yml:md5,8e6ebaa9abf72ced91c1f56acd10f131" - ], - "timestamp": "2024-02-11T14:55:25.205208435" - } -} \ No newline at end of file diff --git a/modules/nf-core/eklipse/tests/tags.yml b/modules/nf-core/eklipse/tests/tags.yml deleted file mode 100644 index eb91ee81f..000000000 --- a/modules/nf-core/eklipse/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -eklipse: - - modules/nf-core/eklipse/** diff --git a/modules/nf-core/ensemblvep/filtervep/main.nf b/modules/nf-core/ensemblvep/filtervep/main.nf deleted file mode 100644 index 69245df0e..000000000 --- a/modules/nf-core/ensemblvep/filtervep/main.nf +++ /dev/null @@ -1,49 +0,0 @@ -process ENSEMBLVEP_FILTERVEP { - tag "$meta.id" - label 'process_single' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:113.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:113.0--pl5321h2a3209d_0' }" - - input: - tuple val(meta), path(input) - path (feature_file) - - output: - tuple val(meta), path("*.${extension}"), emit: output - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - extension = task.ext.suffix ?: "vcf" - """ - filter_vep \\ - $args \\ - --input_file $input \\ - --output_file ${prefix}.${extension} \\ - --only_matched - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ensemblvep: \$( echo \$(vep --help 2>&1) | sed 's/^.*Versions:.*ensembl-vep : //;s/ .*\$//') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - extension = task.ext.suffix ?: "vcf" - """ - touch ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ensemblvep: \$( echo \$(vep --help 2>&1) | sed 's/^.*Versions:.*ensembl-vep : //;s/ .*\$//') - END_VERSIONS - """ -} diff --git a/modules/nf-core/ensemblvep/filtervep/meta.yml b/modules/nf-core/ensemblvep/filtervep/meta.yml deleted file mode 100644 index a73e3b7a7..000000000 --- a/modules/nf-core/ensemblvep/filtervep/meta.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: ensemblvep_filtervep -description: Filter variants based on Ensembl Variant Effect Predictor (VEP) annotations. -keywords: - - annotation - - vcf - - tab - - filter -tools: - - ensemblvep: - description: | - VEP determines the effect of your variants (SNPs, insertions, deletions, CNVs - or structural variants) on genes, transcripts, and protein sequence, as well as regulatory regions. - homepage: https://www.ensembl.org/info/docs/tools/vep/index.html - documentation: https://www.ensembl.org/info/docs/tools/vep/script/index.html - licence: ["Apache-2.0"] - identifier: "" -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - input: - type: file - description: VCF/TAB file annotated with vep - pattern: "*.{vcf,tab,tsv,txt}" - - - feature_file: - type: file - description: File containing features on separate lines. To be used with --filter - option. -output: - - output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - "*.${extension}": - type: file - description: VCF/TAB file - pattern: "*.{vcf,tab,txt,tsv}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@ramprasadn" -maintainers: - - "@ramprasadn" diff --git a/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test b/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test deleted file mode 100644 index 7147792f7..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test +++ /dev/null @@ -1,136 +0,0 @@ -nextflow_process { - - name "Test Process ENSEMBLVEP_FILTERVEP" - script "../main.nf" - process "ENSEMBLVEP_FILTERVEP" - config "./nextflow.config" - - tag "modules" - tag "modules_nfcore" - tag "ensemblvep" - tag "ensemblvep/vep" - tag "ensemblvep/filtervep" - tag "ensemblvep/download" - - // Test for filtering VCF file - test("test_ensemblvep_filtervep_vcf") { - config "./vcf.config" - - setup { - run("ENSEMBLVEP_DOWNLOAD") { - script "../../download/main.nf" - - process { - """ - input[0] = Channel.of([ - [id:"113_WBcel235"], - params.vep_genome, - params.vep_species, - params.vep_cache_version - ]) - """ - } - } - run("ENSEMBLVEP_VEP") { - script "../../vep/main.nf" - - process { - """ - input[0] = Channel.of([ - [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), - [] - ]) - input[1] = params.vep_genome - input[2] = params.vep_species - input[3] = params.vep_cache_version - input[4] = ENSEMBLVEP_DOWNLOAD.out.cache.map{ meta, cache -> [cache] } - input[5] = Channel.value([ - [id:"fasta"], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[6] = [] - """ - } - } - } - - when { - process { - """ - input[0] = ENSEMBLVEP_VEP.out.vcf - input[1] = [] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out.versions).match() }, - { assert path(process.out.output.get(0).get(1)).readLines().first().contains("##fileformat=VCFv4.2") } - ) - } - } - - // Test for filtering TAB file - test("test_ensemblvep_filtervep_tab_gz") { - config "./tab.gz.config" - - setup { - run("ENSEMBLVEP_DOWNLOAD") { - script "../../download/main.nf" - - process { - """ - input[0] = Channel.of([ - [id:"113_WBcel235"], - params.vep_genome, - params.vep_species, - params.vep_cache_version - ]) - """ - } - } - run("ENSEMBLVEP_VEP") { - script "../../vep/main.nf" - - process { - """ - input[0] = Channel.of([ - [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), - [] - ]) - input[1] = params.vep_genome - input[2] = params.vep_species - input[3] = params.vep_cache_version - input[4] = ENSEMBLVEP_DOWNLOAD.out.cache.map{ meta, cache -> [cache] } - input[5] = Channel.value([ - [id:"fasta"], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[6] = [] - """ - } - } - } - - when { - process { - """ - input[0] = ENSEMBLVEP_VEP.out.tab - input[1] = [] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out.versions).match() }, - { assert path(process.out.output.get(0).get(1)).readLines().first().contains("## ENSEMBL VARIANT EFFECT PREDICTOR v113.0") } - ) - } - } -} diff --git a/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test.snap b/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test.snap deleted file mode 100644 index 065d747ba..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/main.nf.test.snap +++ /dev/null @@ -1,26 +0,0 @@ -{ - "test_ensemblvep_filtervep_vcf": { - "content": [ - [ - "versions.yml:md5,1e8906572b04dd21d8c6973efac773c6" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-21T09:10:47.874831491" - }, - "test_ensemblvep_filtervep_tab_gz": { - "content": [ - [ - "versions.yml:md5,1e8906572b04dd21d8c6973efac773c6" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-21T09:11:18.765461163" - } -} \ No newline at end of file diff --git a/modules/nf-core/ensemblvep/filtervep/tests/nextflow.config b/modules/nf-core/ensemblvep/filtervep/tests/nextflow.config deleted file mode 100644 index 40b3a3bd6..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/nextflow.config +++ /dev/null @@ -1,10 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ -params { - vep_cache_version = "113" - vep_genome = "WBcel235" - vep_species = "caenorhabditis_elegans" -} diff --git a/modules/nf-core/ensemblvep/filtervep/tests/tab.gz.config b/modules/nf-core/ensemblvep/filtervep/tests/tab.gz.config deleted file mode 100644 index cdad2d94d..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/tab.gz.config +++ /dev/null @@ -1,24 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -process { - - publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - - withName: ENSEMBLVEP_DOWNLOAD { - ext.args = '--AUTO c --CONVERT --NO_BIOPERL --NO_HTSLIB --NO_TEST --NO_UPDATE' - } - - withName: ENSEMBLVEP_VEP { - ext.args = '--tab' - ext.prefix = { "${meta.id}_vep" } - } - - withName: ENSEMBLVEP_FILTERVEP { - ext.args = '--filter "Feature_type is Transcript"' - ext.suffix = "tab" - } -} diff --git a/modules/nf-core/ensemblvep/filtervep/tests/tags.yml b/modules/nf-core/ensemblvep/filtervep/tests/tags.yml deleted file mode 100644 index b43bf40d6..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -ensemblvep/filtervep: - - "modules/nf-core/ensemblvep/filtervep/**" diff --git a/modules/nf-core/ensemblvep/filtervep/tests/vcf.config b/modules/nf-core/ensemblvep/filtervep/tests/vcf.config deleted file mode 100644 index ee2aef574..000000000 --- a/modules/nf-core/ensemblvep/filtervep/tests/vcf.config +++ /dev/null @@ -1,23 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -process { - - publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - - withName: ENSEMBLVEP_DOWNLOAD { - ext.args = '--AUTO c --CONVERT --NO_BIOPERL --NO_HTSLIB --NO_TEST --NO_UPDATE' - } - - withName: ENSEMBLVEP_VEP { - ext.args = '--vcf' - ext.prefix = { "${meta.id}_vep" } - } - - withName: ENSEMBLVEP_FILTERVEP { - ext.args = '--filter "Feature_type is Transcript"' - } -} diff --git a/modules/nf-core/ensemblvep/vep/ensemblvep-vep.diff b/modules/nf-core/ensemblvep/vep/ensemblvep-vep.diff index c5a7d13d7..017250d91 100644 --- a/modules/nf-core/ensemblvep/vep/ensemblvep-vep.diff +++ b/modules/nf-core/ensemblvep/vep/ensemblvep-vep.diff @@ -1,16 +1,35 @@ -Changes in module 'nf-core/ensemblvep/vep' +Changes in component 'nf-core/ensemblvep/vep' 'modules/nf-core/ensemblvep/vep/meta.yml' is unchanged Changes in 'ensemblvep/vep/main.nf': --- modules/nf-core/ensemblvep/vep/main.nf +++ modules/nf-core/ensemblvep/vep/main.nf -@@ -20,7 +20,7 @@ - tuple val(meta), path("*.vcf.gz") , optional:true, emit: vcf - tuple val(meta), path("*.tab.gz") , optional:true, emit: tab - tuple val(meta), path("*.json.gz") , optional:true, emit: json -- path "*.summary.html" , emit: report -+ path "*.summary.html" , optional:true, emit: report - path "versions.yml" , emit: versions +@@ -4,8 +4,8 @@ - when: + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container +- ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/3d/3da6e21cbf9803529421d7e136d1ebec5ff71ec50e0d996eda2ce11ec2c19bf9/data' +- : 'community.wave.seqera.io/library/ensembl-vep_perl-math-cdf:1e13f65f931a6954'}" ++ ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/da/da2ef7e58823df3fc9d6c0a9927e219435329a52173f871a6fa2b5302679f7b2/data' ++ : 'community.wave.seqera.io/library/ensembl-vep_perl-list-moreutils_perl-math-cdf:3c62f15be110ccc2'}" + + input: + tuple val(meta), path(vcf), path(custom_extra_files) + +Changes in 'ensemblvep/vep/environment.yml': +--- modules/nf-core/ensemblvep/vep/environment.yml ++++ modules/nf-core/ensemblvep/vep/environment.yml +@@ -4,5 +4,6 @@ + - conda-forge + - bioconda + dependencies: +- - bioconda::ensembl-vep=115.2 ++ - bioconda::ensembl-vep=110.1 ++ - bioconda::perl-list-moreutils=0.430 + - bioconda::perl-math-cdf=0.1 +'modules/nf-core/ensemblvep/vep/tests/tab.gz.config' is unchanged +'modules/nf-core/ensemblvep/vep/tests/vcf.config' is unchanged +'modules/nf-core/ensemblvep/vep/tests/main.nf.test.snap' is unchanged +'modules/nf-core/ensemblvep/vep/tests/nextflow.config' is unchanged +'modules/nf-core/ensemblvep/vep/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/ensemblvep/vep/environment.yml b/modules/nf-core/ensemblvep/vep/environment.yml new file mode 100644 index 000000000..3662a9ac5 --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/environment.yml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::ensembl-vep=110.1 + - bioconda::perl-list-moreutils=0.430 + - bioconda::perl-math-cdf=0.1 diff --git a/modules/nf-core/ensemblvep/vep/main.nf b/modules/nf-core/ensemblvep/vep/main.nf index 4886b05e6..4ec78eab4 100644 --- a/modules/nf-core/ensemblvep/vep/main.nf +++ b/modules/nf-core/ensemblvep/vep/main.nf @@ -1,71 +1,67 @@ process ENSEMBLVEP_VEP { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' - conda "bioconda::ensembl-vep=110.0" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ensembl-vep:110.0--pl5321h2a3209d_0' : - 'biocontainers/ensembl-vep:110.0--pl5321h2a3209d_0' }" + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/da/da2ef7e58823df3fc9d6c0a9927e219435329a52173f871a6fa2b5302679f7b2/data' + : 'community.wave.seqera.io/library/ensembl-vep_perl-list-moreutils_perl-math-cdf:3c62f15be110ccc2'}" input: tuple val(meta), path(vcf), path(custom_extra_files) - val genome - val species - val cache_version - path cache + val genome + val species + val cache_version + path cache tuple val(meta2), path(fasta) - path extra_files + path extra_files output: - tuple val(meta), path("*.vcf.gz") , optional:true, emit: vcf - tuple val(meta), path("*.tab.gz") , optional:true, emit: tab - tuple val(meta), path("*.json.gz") , optional:true, emit: json - path "*.summary.html" , optional:true, emit: report - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.vcf.gz"), emit: vcf, optional: true + tuple val(meta), path("${prefix}.vcf.gz.tbi"), emit: tbi, optional: true + tuple val(meta), path("${prefix}.tab.gz"), emit: tab, optional: true + tuple val(meta), path("${prefix}.json.gz"), emit: json, optional: true + tuple val(meta), val("${task.process}"), val('ensemblvep'), path("*.html"), topic: multiqc_files, emit: report, optional: true + tuple val("${task.process}"), val('ensemblvep'), eval("vep --help | sed -n '/ensembl-vep/s/.*: //p'"), topic: versions, emit: versions_ensemblvep + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'"), topic: versions, emit: versions_tabix + tuple val("${task.process}"), val('perl-math-cdf'), eval("perl -MMath::CDF -e 'print \\\$Math::CDF::VERSION'"), topic: versions, emit: versions_perlmathcdf when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def file_extension = args.contains("--vcf") ? 'vcf' : args.contains("--json")? 'json' : args.contains("--tab")? 'tab' : 'vcf' + def args2 = task.ext.args2 ?: '' + def file_extension = args.contains("--vcf") ? 'vcf' : args.contains("--json") ? 'json' : args.contains("--tab") ? 'tab' : 'vcf' def compress_cmd = args.contains("--compress_output") ? '' : '--compress_output bgzip' - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" def dir_cache = cache ? "\${PWD}/${cache}" : "/.vep" - def reference = fasta ? "--fasta $fasta" : "" + def reference = fasta ? "--fasta ${fasta}" : "" + def create_index = file_extension == "vcf" ? "tabix ${args2} ${prefix}.${file_extension}.gz" : "" """ vep \\ - -i $vcf \\ + -i ${vcf} \\ -o ${prefix}.${file_extension}.gz \\ - $args \\ - $compress_cmd \\ - $reference \\ - --assembly $genome \\ - --species $species \\ + ${args} \\ + ${compress_cmd} \\ + ${reference} \\ + --assembly ${genome} \\ + --species ${species} \\ --cache \\ - --cache_version $cache_version \\ - --dir_cache $dir_cache \\ - --fork $task.cpus \\ - --stats_file ${prefix}.summary.html \\ + --cache_version ${cache_version} \\ + --dir_cache ${dir_cache} \\ + --fork ${task.cpus} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ensemblvep: \$( echo \$(vep --help 2>&1) | sed 's/^.*Versions:.*ensembl-vep : //;s/ .*\$//') - END_VERSIONS + ${create_index} """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" + def file_extension = args.contains("--vcf") ? 'vcf' : args.contains("--json") ? 'json' : args.contains("--tab") ? 'tab' : 'vcf' + def create_index = file_extension == "vcf" ? "touch ${prefix}.${file_extension}.gz.tbi" : "" """ - touch ${prefix}.vcf.gz - touch ${prefix}.tab.gz - touch ${prefix}.json.gz - touch ${prefix}.summary.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ensemblvep: \$( echo \$(vep --help 2>&1) | sed 's/^.*Versions:.*ensembl-vep : //;s/ .*\$//') - END_VERSIONS + echo "" | gzip > ${prefix}.${file_extension}.gz + ${create_index} + touch ${prefix}_summary.html """ } diff --git a/modules/nf-core/ensemblvep/vep/meta.yml b/modules/nf-core/ensemblvep/vep/meta.yml index 7783847dc..48f025495 100644 --- a/modules/nf-core/ensemblvep/vep/meta.yml +++ b/modules/nf-core/ensemblvep/vep/meta.yml @@ -1,5 +1,6 @@ -name: ENSEMBLVEP_VEP -description: Ensembl Variant Effect Predictor (VEP). The output-file-format is controlled through `task.ext.args`. +name: ensemblvep_vep +description: Ensembl Variant Effect Predictor (VEP). The output-file-format is + controlled through `task.ext.args`. keywords: - annotation - vcf @@ -12,22 +13,26 @@ tools: or structural variants) on genes, transcripts, and protein sequence, as well as regulatory regions. homepage: https://www.ensembl.org/info/docs/tools/vep/index.html documentation: https://www.ensembl.org/info/docs/tools/vep/script/index.html - licence: ["Apache-2.0"] + licence: + - "Apache-2.0" + identifier: "" input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - vcf: - type: file - description: | - vcf to annotate - - custom_extra_files: - type: file - description: | - extra sample-specific files to be used with the `--custom` flag to be configured with ext.args - (optional) + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: | + vcf to annotate + ontologies: [] + - custom_extra_files: + type: file + description: | + extra sample-specific files to be used with the `--custom` flag to be configured with ext.args + (optional) + ontologies: [] - genome: type: string description: | @@ -44,45 +49,167 @@ input: type: file description: | path to VEP cache (optional) - - meta2: - type: map - description: | - Groovy Map containing fasta reference information - e.g. [ id:'test' ] - - fasta: - type: file - description: | - reference FASTA file (optional) - pattern: "*.{fasta,fa}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing fasta reference information + e.g. [ id:'test' ] + - fasta: + type: file + description: | + reference FASTA file (optional) + pattern: "*.{fasta,fa}" + ontologies: [] - extra_files: type: file description: | path to file(s) needed for plugins (optional) + ontologies: [] output: - - vcf: - type: file - description: | - annotated vcf (optional) - pattern: "*.ann.vcf.gz" - - tab: - type: file - description: | - tab file with annotated variants (optional) - pattern: "*.ann.tab.gz" - - json: - type: file - description: | - json file with annotated variants (optional) - pattern: "*.ann.json.gz" - - report: - type: file - description: VEP report file - pattern: "*.html" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + vcf: + - - meta: + type: map + description: | + Map with sample information + - ${prefix}.vcf.gz: + type: file + description: | + annotated vcf (optional) + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + tbi: + - - meta: + type: map + description: | + Map with sample information + - ${prefix}.vcf.gz.tbi: + type: file + description: | + annotated vcf index (optional) + pattern: "*.vcf.gz.tbi" + ontologies: [] + tab: + - - meta: + type: map + description: | + Map with sample information + - ${prefix}.tab.gz: + type: file + description: | + tab file with annotated variants (optional) + pattern: "*.ann.tab.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + json: + - - meta: + type: map + description: | + Map with sample information + - ${prefix}.json.gz: + type: file + description: | + json file with annotated variants (optional) + pattern: "*.ann.json.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + report: + - - meta: + type: map + description: | + Map with sample information + - ${task.process}: + type: string + description: The process + - ensemblvep: + type: string + description: The tool name + - "*.html": + type: file + description: VEP report file + pattern: "*.html" + ontologies: [] + versions_ensemblvep: + - - ${task.process}: + type: string + description: The process + - ensemblvep: + type: string + description: The tool name + - "vep --help | sed -n '/ensembl-vep/s/.*: //p'": + type: eval + description: The command used to generate the version of the tool + versions_tabix: + - - ${task.process}: + type: string + description: The process + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + versions_perlmathcdf: + - - ${task.process}: + type: string + description: The process + - perl-math-cdf: + type: string + description: The tool name + - perl -MMath::CDF -e 'print \\$Math::CDF::VERSION': + type: eval + description: The expression to obtain the version of the tool +topics: + multiqc_files: + - - meta: + type: string + description: | + Map with sample information + - ${task.process}: + type: string + description: The process + - ensemblvep: + type: string + description: The tool name + - "*.html": + type: file + description: VEP report file + pattern: "*.html" + ontologies: [] + versions: + - - ${task.process}: + type: string + description: The process + - ensemblvep: + type: string + description: The tool name + - "vep --help | sed -n '/ensembl-vep/s/.*: //p'": + type: eval + description: The command used to generate the version of the tool + - - ${task.process}: + type: string + description: The process + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The process + - perl-math-cdf: + type: string + description: The tool name + - perl -MMath::CDF -e 'print \\$Math::CDF::VERSION': + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" - "@matthdsm" - "@nvnieuwk" +maintainers: + - "@maxulysse" + - "@matthdsm" + - "@nvnieuwk" diff --git a/modules/nf-core/ensemblvep/vep/tests/main.nf.test b/modules/nf-core/ensemblvep/vep/tests/main.nf.test new file mode 100644 index 000000000..374f840cf --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/tests/main.nf.test @@ -0,0 +1,89 @@ +nextflow_process { + + name "Test Process ENSEMBLVEP_VEP" + script "../main.nf" + process "ENSEMBLVEP_VEP" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "ensemblvep" + tag "ensemblvep/vep" + + test("test_ensemblvep_vep_fasta_vcf - stub (not really but linting complains otherwise)") { + config "./vcf.config" + + when { + process { + """ + vep_cache = Channel.of(file('s3://annotation-cache/vep_cache/115_WBcel235/')).collect() + + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ]) + input[1] = params.vep_genome + input[2] = params.vep_species + input[3] = params.vep_cache_version + input[4] = vep_cache + input[5] = Channel.value([ + [id:"fasta"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[6] = [] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.vcf[0][1]).name + ",variantsMD5:" + path(process.out.vcf[0][1]).vcf.variantsMD5, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + + } + + test("test_ensemblvep_vep_fasta_tab_gz") { + config "./tab.gz.config" + + when { + process { + """ + vep_cache = Channel.of(file('s3://annotation-cache/vep_cache/115_WBcel235/')).collect() + + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ]) + input[1] = params.vep_genome + input[2] = params.vep_species + input[3] = params.vep_cache_version + input[4] = vep_cache + input[5] = Channel.value([ + [id:"fasta"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[6] = [] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.tab[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() }, + { assert path(process.out.tab[0][1]).linesGzip.contains("## ENSEMBL VARIANT EFFECT PREDICTOR v115.2") } + ) + } + } +} diff --git a/modules/nf-core/ensemblvep/vep/tests/main.nf.test.snap b/modules/nf-core/ensemblvep/vep/tests/main.nf.test.snap new file mode 100644 index 000000000..96c18d9cd --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/tests/main.nf.test.snap @@ -0,0 +1,69 @@ +{ + "test_ensemblvep_vep_fasta_tab_gz": { + "content": [ + "test.tab.gz", + { + "versions_ensemblvep": [ + [ + "ENSEMBLVEP_VEP", + "ensemblvep", + "115.2" + ] + ], + "versions_perlmathcdf": [ + [ + "ENSEMBLVEP_VEP", + "perl-math-cdf", + "0.1" + ] + ], + "versions_tabix": [ + [ + "ENSEMBLVEP_VEP", + "tabix", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-06T12:47:57.03116265" + }, + "test_ensemblvep_vep_fasta_vcf - stub (not really but linting complains otherwise)": { + "content": [ + "test.vcf.gz,variantsMD5:d41d8cd98f00b204e9800998ecf8427e", + "test.vcf.gz.tbi", + { + "versions_ensemblvep": [ + [ + "ENSEMBLVEP_VEP", + "ensemblvep", + "115.2" + ] + ], + "versions_perlmathcdf": [ + [ + "ENSEMBLVEP_VEP", + "perl-math-cdf", + "0.1" + ] + ], + "versions_tabix": [ + [ + "ENSEMBLVEP_VEP", + "tabix", + "1.21" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-06T12:47:34.421995264" + } +} \ No newline at end of file diff --git a/modules/nf-core/ensemblvep/vep/tests/nextflow.config b/modules/nf-core/ensemblvep/vep/tests/nextflow.config new file mode 100644 index 000000000..8e68fe24a --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/tests/nextflow.config @@ -0,0 +1,5 @@ +params { + vep_cache_version = "115" + vep_genome = "WBcel235" + vep_species = "caenorhabditis_elegans" +} diff --git a/modules/nf-core/ensemblvep/vep/tests/tab.gz.config b/modules/nf-core/ensemblvep/vep/tests/tab.gz.config new file mode 100644 index 000000000..40eb03e59 --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/tests/tab.gz.config @@ -0,0 +1,5 @@ +process { + withName: ENSEMBLVEP_VEP { + ext.args = '--tab --compress_output bgzip' + } +} diff --git a/modules/nf-core/ensemblvep/vep/tests/vcf.config b/modules/nf-core/ensemblvep/vep/tests/vcf.config new file mode 100644 index 000000000..ad8955a37 --- /dev/null +++ b/modules/nf-core/ensemblvep/vep/tests/vcf.config @@ -0,0 +1,5 @@ +process { + withName: ENSEMBLVEP_VEP { + ext.args = '--vcf' + } +} diff --git a/modules/nf-core/expansionhunter/environment.yml b/modules/nf-core/expansionhunter/environment.yml index 07db4374d..97f251f51 100644 --- a/modules/nf-core/expansionhunter/environment.yml +++ b/modules/nf-core/expansionhunter/environment.yml @@ -1,7 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - bioconda::expansionhunter=5.0.0 - - bioconda::htslib=1.18 diff --git a/modules/nf-core/expansionhunter/main.nf b/modules/nf-core/expansionhunter/main.nf index dbcb175fc..f389a04a4 100644 --- a/modules/nf-core/expansionhunter/main.nf +++ b/modules/nf-core/expansionhunter/main.nf @@ -4,8 +4,8 @@ process EXPANSIONHUNTER { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/expansionhunter:5.0.0--hf366f20_0' : - 'biocontainers/expansionhunter:5.0.0--hf366f20_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/14/14e1d96665f934a98e569fc5a6fa237f98d3753eee2b6f60d0aea8ff9d44f406/data' : + 'community.wave.seqera.io/library/expansionhunter:5.0.0--389ada7e191a4fba' }" input: tuple val(meta), path(bam), path(bai) @@ -17,7 +17,8 @@ process EXPANSIONHUNTER { tuple val(meta), path("*.vcf.gz") , emit: vcf tuple val(meta), path("*.json.gz") , emit: json tuple val(meta), path("*_realigned.bam") , emit: bam - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('expansionhunter'), eval("ExpansionHunter --version | head -1 | sed -n 's/^.*ExpansionHunter v//; s/]//p'"), topic: versions, emit: versions_expansionhunter + tuple val("${task.process}"), val('bgzip'), eval("bgzip --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_bgzip when: task.ext.when == null || task.ext.when @@ -38,11 +39,6 @@ process EXPANSIONHUNTER { bgzip --threads ${task.cpus} ${args2} ${prefix}.vcf bgzip --threads ${task.cpus} ${args2} ${prefix}.json - cat <<-END_VERSIONS > versions.yml - "${task.process}": - expansionhunter: \$( echo \$(ExpansionHunter --version 2>&1) | head -1 | sed 's/^.*ExpansionHunter v//') - bgzip: \$(echo \$(bgzip -h 2>&1) | sed 's/^.*Version: //;s/Usage:.*//') - END_VERSIONS """ stub: @@ -52,10 +48,5 @@ process EXPANSIONHUNTER { echo "" | gzip > ${prefix}.json.gz touch ${prefix}_realigned.bam - cat <<-END_VERSIONS > versions.yml - "${task.process}": - expansionhunter: \$( echo \$(ExpansionHunter --version 2>&1) | head -1 | sed 's/^.*ExpansionHunter v//') - bgzip: \$(echo \$(bgzip -h 2>&1) | sed 's/^.*Version: //;s/Usage:.*//') - END_VERSIONS """ } diff --git a/modules/nf-core/expansionhunter/meta.yml b/modules/nf-core/expansionhunter/meta.yml index 4d55fe260..c6b070739 100644 --- a/modules/nf-core/expansionhunter/meta.yml +++ b/modules/nf-core/expansionhunter/meta.yml @@ -25,10 +25,12 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - bai: type: file description: Index of BAM/CRAM file pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -38,6 +40,7 @@ input: type: file description: Reference genome pattern: "*.{fna,fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -47,6 +50,7 @@ input: type: file description: Reference genome index pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -56,9 +60,11 @@ input: type: file description: JSON file with repeat expansion sites to genotype pattern: "*.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -67,8 +73,10 @@ output: type: file description: VCF with repeat expansions pattern: "*.vcf.gz" - - json: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + json: + - - meta: type: map description: | Groovy Map containing sample information @@ -77,8 +85,10 @@ output: type: file description: JSON with repeat expansions pattern: "*.json.gz" - - bam: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -87,11 +97,47 @@ output: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_expansionhunter: + - - ${task.process}: + type: string + description: The process the versions were collected from + - expansionhunter: + type: string + description: The tool name + - ExpansionHunter --version | head -1 | sed -n 's/^.*ExpansionHunter v//; s/]//p': + type: eval + description: The expression to obtain the version of the tool + versions_bgzip: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bgzip: + type: string + description: The tool name + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - expansionhunter: + type: string + description: The tool name + - ExpansionHunter --version | head -1 | sed -n 's/^.*ExpansionHunter v//; s/]//p': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The process the versions were collected from + - bgzip: + type: string + description: The tool name + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@jemten" maintainers: diff --git a/modules/nf-core/expansionhunter/tests/main.nf.test.snap b/modules/nf-core/expansionhunter/tests/main.nf.test.snap index a4e09f4c3..04b55ca14 100644 --- a/modules/nf-core/expansionhunter/tests/main.nf.test.snap +++ b/modules/nf-core/expansionhunter/tests/main.nf.test.snap @@ -23,18 +23,29 @@ { "id": "test" }, - "test_realigned.bam:md5,b37a72c0b97b45e63636a9758f3144d7" + "test_realigned.bam:md5,3f9de11932f2548f8259c063ac37ab94" ] ], "3": [ - "versions.yml:md5,056b525f67ba23c361f0c65f47256dca" + [ + "EXPANSIONHUNTER", + "expansionhunter", + "5.0.0" + ] + ], + "4": [ + [ + "EXPANSIONHUNTER", + "bgzip", + "1.22.1" + ] ], "bam": [ [ { "id": "test" }, - "test_realigned.bam:md5,b37a72c0b97b45e63636a9758f3144d7" + "test_realigned.bam:md5,3f9de11932f2548f8259c063ac37ab94" ] ], "json": [ @@ -53,16 +64,27 @@ "test.vcf.gz:md5,cfd4a1d35c0e469b99eb6aaa6d22de76" ] ], - "versions": [ - "versions.yml:md5,056b525f67ba23c361f0c65f47256dca" + "versions_bgzip": [ + [ + "EXPANSIONHUNTER", + "bgzip", + "1.22.1" + ] + ], + "versions_expansionhunter": [ + [ + "EXPANSIONHUNTER", + "expansionhunter", + "5.0.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.03.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-03T12:20:15.18545069" + "timestamp": "2026-02-04T13:49:22.036774" }, "stub": { "content": [ @@ -92,7 +114,18 @@ ] ], "3": [ - "versions.yml:md5,056b525f67ba23c361f0c65f47256dca" + [ + "EXPANSIONHUNTER", + "expansionhunter", + "5.0.0" + ] + ], + "4": [ + [ + "EXPANSIONHUNTER", + "bgzip", + "1.22.1" + ] ], "bam": [ [ @@ -118,15 +151,26 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,056b525f67ba23c361f0c65f47256dca" + "versions_bgzip": [ + [ + "EXPANSIONHUNTER", + "bgzip", + "1.22.1" + ] + ], + "versions_expansionhunter": [ + [ + "EXPANSIONHUNTER", + "expansionhunter", + "5.0.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.03.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-03T12:20:28.430115" + "timestamp": "2026-02-04T13:53:07.012233" } } \ No newline at end of file diff --git a/modules/nf-core/expansionhunter/tests/tags.yml b/modules/nf-core/expansionhunter/tests/tags.yml deleted file mode 100644 index 032663519..000000000 --- a/modules/nf-core/expansionhunter/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -expansionhunter: - - "modules/nf-core/expansionhunter/**" diff --git a/modules/nf-core/fastp/environment.yml b/modules/nf-core/fastp/environment.yml index 26d4aca5d..0c36eed25 100644 --- a/modules/nf-core/fastp/environment.yml +++ b/modules/nf-core/fastp/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::fastp=0.23.4 + # renovate: datasource=conda depName=bioconda/fastp + - bioconda::fastp=1.0.1 diff --git a/modules/nf-core/fastp/main.nf b/modules/nf-core/fastp/main.nf index e1b9f5656..e13509ca2 100644 --- a/modules/nf-core/fastp/main.nf +++ b/modules/nf-core/fastp/main.nf @@ -4,12 +4,11 @@ process FASTP { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/fastp:0.23.4--h5f740d0_0' : - 'biocontainers/fastp:0.23.4--h5f740d0_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/527b18847a97451091dba07a886b24f17f742a861f9f6c9a6bfb79d4f1f3bf9d/data' : + 'community.wave.seqera.io/library/fastp:1.0.1--c8b87fe62dcc103c' }" input: - tuple val(meta), path(reads) - path adapter_fasta + tuple val(meta), path(reads), path(adapter_fasta) val discard_trimmed_pass val save_trimmed_fail val save_merged @@ -21,7 +20,7 @@ process FASTP { tuple val(meta), path('*.log') , emit: log tuple val(meta), path('*.fail.fastq.gz') , optional:true, emit: reads_fail tuple val(meta), path('*.merged.fastq.gz'), optional:true, emit: reads_merged - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('fastp'), eval('fastp --version 2>&1 | sed -e "s/fastp //g"'), emit: versions_fastp, topic: versions when: task.ext.when == null || task.ext.when @@ -30,9 +29,9 @@ process FASTP { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def adapter_list = adapter_fasta ? "--adapter_fasta ${adapter_fasta}" : "" - def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--failed_out ${prefix}.paired.fail.fastq.gz --unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.fastq.gz" : '' - def out_fq1 = discard_trimmed_pass ?: ( meta.single_end ? "--out1 ${prefix}.fastp.fastq.gz" : "--out1 ${prefix}_1.fastp.fastq.gz" ) - def out_fq2 = discard_trimmed_pass ?: "--out2 ${prefix}_2.fastp.fastq.gz" + def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--failed_out ${prefix}.paired.fail.fastq.gz --unpaired1 ${prefix}_R1.fail.fastq.gz --unpaired2 ${prefix}_R2.fail.fastq.gz" : '' + def out_fq1 = discard_trimmed_pass ?: ( meta.single_end ? "--out1 ${prefix}.fastp.fastq.gz" : "--out1 ${prefix}_R1.fastp.fastq.gz" ) + def out_fq2 = discard_trimmed_pass ?: "--out2 ${prefix}_R2.fastp.fastq.gz" // Added soft-links to original fastqs for consistent naming in MultiQC // Use single ended for interleaved. Add --interleaved_in in config. if ( task.ext.args?.contains('--interleaved_in') ) { @@ -48,13 +47,8 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) \\ + 2>| >(tee ${prefix}.fastp.log >&2) \\ | gzip -c > ${prefix}.fastp.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS """ } else if (meta.single_end) { """ @@ -69,21 +63,16 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS + 2>| >(tee ${prefix}.fastp.log >&2) """ } else { def merge_fastq = save_merged ? "-m --merged_out ${prefix}.merged.fastq.gz" : '' """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -sf ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -sf ${reads[1]} ${prefix}_2.fastq.gz + [ ! -f ${prefix}_R1.fastq.gz ] && ln -sf ${reads[0]} ${prefix}_R1.fastq.gz + [ ! -f ${prefix}_R2.fastq.gz ] && ln -sf ${reads[1]} ${prefix}_R2.fastq.gz fastp \\ - --in1 ${prefix}_1.fastq.gz \\ - --in2 ${prefix}_2.fastq.gz \\ + --in1 ${prefix}_R1.fastq.gz \\ + --in2 ${prefix}_R2.fastq.gz \\ $out_fq1 \\ $out_fq2 \\ --json ${prefix}.fastp.json \\ @@ -94,21 +83,16 @@ process FASTP { --thread $task.cpus \\ --detect_adapter_for_pe \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS + 2>| >(tee ${prefix}.fastp.log >&2) """ } stub: def prefix = task.ext.prefix ?: "${meta.id}" def is_single_output = task.ext.args?.contains('--interleaved_in') || meta.single_end - def touch_reads = (discard_trimmed_pass) ? "" : (is_single_output) ? "echo '' | gzip > ${prefix}.fastp.fastq.gz" : "echo '' | gzip > ${prefix}_1.fastp.fastq.gz ; echo '' | gzip > ${prefix}_2.fastp.fastq.gz" + def touch_reads = (discard_trimmed_pass) ? "" : (is_single_output) ? "echo '' | gzip > ${prefix}.fastp.fastq.gz" : "echo '' | gzip > ${prefix}_R1.fastp.fastq.gz ; echo '' | gzip > ${prefix}_R2.fastp.fastq.gz" def touch_merged = (!is_single_output && save_merged) ? "echo '' | gzip > ${prefix}.merged.fastq.gz" : "" - def touch_fail_fastq = (!save_trimmed_fail) ? "" : meta.single_end ? "echo '' | gzip > ${prefix}.fail.fastq.gz" : "echo '' | gzip > ${prefix}.paired.fail.fastq.gz ; echo '' | gzip > ${prefix}_1.fail.fastq.gz ; echo '' | gzip > ${prefix}_2.fail.fastq.gz" + def touch_fail_fastq = (!save_trimmed_fail) ? "" : meta.single_end ? "echo '' | gzip > ${prefix}.fail.fastq.gz" : "echo '' | gzip > ${prefix}.paired.fail.fastq.gz ; echo '' | gzip > ${prefix}_R1.fail.fastq.gz ; echo '' | gzip > ${prefix}_R2.fail.fastq.gz" """ $touch_reads $touch_fail_fastq @@ -116,10 +100,5 @@ process FASTP { touch "${prefix}.fastp.json" touch "${prefix}.fastp.html" touch "${prefix}.fastp.log" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS """ } diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml index 159404d08..a67be395b 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -24,24 +24,27 @@ input: List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. If you wish to run interleaved paired-end data, supply as single-end data but with `--interleaved_in` in your `modules.conf`'s `ext.args` for the module. - - - adapter_fasta: + ontologies: [] + - adapter_fasta: type: file description: File in FASTA format containing possible adapters to remove. pattern: "*.{fasta,fna,fas,fa}" - - - discard_trimmed_pass: - type: boolean - description: Specify true to not write any reads that pass trimming thresholds. - | This can be used to use fastp for the output report only. - - - save_trimmed_fail: - type: boolean - description: Specify true to save files that failed to pass trimming thresholds - ending in `*.fail.fastq.gz` - - - save_merged: - type: boolean - description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` + ontologies: [] + - discard_trimmed_pass: + type: boolean + description: | + Specify true to not write any reads that pass trimming thresholds. + This can be used to use fastp for the output report only. + - save_trimmed_fail: + type: boolean + description: Specify true to save files that failed to pass trimming thresholds + ending in `*.fail.fastq.gz` + - save_merged: + type: boolean + description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` output: - - reads: - - meta: + reads: + - - meta: type: map description: | Groovy Map containing sample information @@ -50,8 +53,11 @@ output: type: file description: The trimmed/modified/unmerged fastq reads pattern: "*fastp.fastq.gz" - - json: - - meta: + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format + json: + - - meta: type: map description: | Groovy Map containing sample information @@ -60,8 +66,10 @@ output: type: file description: Results in JSON format pattern: "*.json" - - html: - - meta: + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + html: + - - meta: type: map description: | Groovy Map containing sample information @@ -70,8 +78,9 @@ output: type: file description: Results in HTML format pattern: "*.html" - - log: - - meta: + ontologies: [] + log: + - - meta: type: map description: | Groovy Map containing sample information @@ -80,8 +89,9 @@ output: type: file description: fastq log file pattern: "*.log" - - reads_fail: - - meta: + ontologies: [] + reads_fail: + - - meta: type: map description: | Groovy Map containing sample information @@ -90,8 +100,11 @@ output: type: file description: Reads the failed the preprocessing pattern: "*fail.fastq.gz" - - reads_merged: - - meta: + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format + reads_merged: + - - meta: type: map description: | Groovy Map containing sample information @@ -100,14 +113,32 @@ output: type: file description: Reads that were successfully merged pattern: "*.{merged.fastq.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_fastp: + - - "${task.process}": + type: string + description: The name of the process + - fastp: + type: string + description: The name of the tool + - 'fastp --version 2>&1 | sed -e "s/fastp //g"': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - "${task.process}": + type: string + description: The name of the process + - fastp: + type: string + description: The name of the tool + - 'fastp --version 2>&1 | sed -e "s/fastp //g"': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@kevinmenden" + - "@eit-maxlcummins" maintainers: - "@drpatelh" - "@kevinmenden" diff --git a/modules/nf-core/fastp/tests/main.nf.test b/modules/nf-core/fastp/tests/main.nf.test index 30dbb8aab..b79015781 100644 --- a/modules/nf-core/fastp/tests/main.nf.test +++ b/modules/nf-core/fastp/tests/main.nf.test @@ -13,14 +13,19 @@ nextflow_process { process { """ + adapter_fasta = [] // empty list for no adapter file! + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -31,11 +36,11 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() + } ) } } @@ -46,20 +51,22 @@ nextflow_process { process { """ - adapter_fasta = [] - save_trimmed_pass = true - save_trimmed_fail = false - save_merged = false + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -70,11 +77,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -85,14 +91,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -106,8 +117,7 @@ nextflow_process { { assert process.out.reads_merged == [] }, { assert snapshot( process.out.reads, - process.out.json, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -118,14 +128,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -136,11 +151,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -151,15 +165,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -173,8 +194,7 @@ nextflow_process { process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.json, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -184,15 +204,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -203,11 +230,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("total reads: 75") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() }, + process.out.findAll { key, val -> key.startsWith('versions') }).match() }, ) } } @@ -217,15 +243,22 @@ nextflow_process { when { process { """ + adapter_fasta = file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) + input[1] = false input[2] = false - input[3] = false - input[4] = true + input[3] = true """ } } @@ -236,11 +269,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("
    ") }, { assert path(process.out.log.get(0).get(1)).getText().contains("total bases: 13683") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -250,14 +282,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -268,14 +306,13 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads, process.out.reads_fail, process.out.reads_fail, process.out.reads_merged, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -285,15 +322,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -304,14 +348,13 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads, process.out.reads_fail, process.out.reads_fail, process.out.reads_merged, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -324,14 +367,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -352,20 +400,20 @@ nextflow_process { process { """ - adapter_fasta = [] - save_trimmed_pass = true - save_trimmed_fail = false - save_merged = false + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -386,14 +434,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -414,14 +467,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -442,15 +500,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -470,15 +533,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -498,15 +566,22 @@ nextflow_process { when { process { """ + adapter_fasta = file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -526,14 +601,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -553,15 +633,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -573,4 +658,4 @@ nextflow_process { ) } } -} \ No newline at end of file +} diff --git a/modules/nf-core/fastp/tests/main.nf.test.snap b/modules/nf-core/fastp/tests/main.nf.test.snap index 54be7e45f..567723589 100644 --- a/modules/nf-core/fastp/tests/main.nf.test.snap +++ b/modules/nf-core/fastp/tests/main.nf.test.snap @@ -39,7 +39,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -77,28 +81,23 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:31:10.841098" + "timestamp": "2026-01-22T13:00:52.14535813" }, "test_fastp_paired_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,1e0f8e27e71728e2b63fc64086be95cd" - ] - ], [ [ { @@ -106,8 +105,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", - "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + "test_R1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_R2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" ] ] ], @@ -117,27 +116,24 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:28.665779" + "timestamp": "2026-01-23T09:46:26.421773402" }, "test_fastp_paired_end_merged_adapterlist": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,5914ca3f21ce162123a824e33e8564f6" - ] - ], [ [ { @@ -145,8 +141,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", - "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + "test_R1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_R2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" ] ] ], @@ -162,27 +158,24 @@ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" ] ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:18.210375" + "timestamp": "2026-01-23T09:46:59.832295907" }, "test_fastp_single_end_qc_only": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,5cc5f01e449309e0e689ed6f51a2294a" - ] - ], [ ], @@ -201,15 +194,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:27.380974" + "timestamp": "2026-01-23T09:47:06.486959565" }, "test_fastp_paired_end_trim_fail": { "content": [ @@ -220,8 +219,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", - "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" + "test_R1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", + "test_R2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" ] ] ], @@ -233,32 +232,29 @@ }, [ "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366", - "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", - "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" + "test_R1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", + "test_R2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" ] ] ], [ ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,4c3268ddb50ea5b33125984776aa3519" + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] - ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:58.749589" + "timestamp": "2026-01-23T09:46:46.736511024" }, "fastp - stub test_fastp_interleaved": { "content": [ @@ -306,7 +302,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -350,16 +350,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:50:00.270029" + "timestamp": "2026-01-22T13:00:16.097071654" }, "test_fastp_single_end - stub": { "content": [ @@ -407,7 +411,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -451,16 +459,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:49:42.502789" + "timestamp": "2026-01-22T13:00:03.317192706" }, "test_fastp_paired_end_merged_adapterlist - stub": { "content": [ @@ -472,8 +484,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -517,7 +529,11 @@ ] ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -553,8 +569,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -570,16 +586,20 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:54:53.458252" + "timestamp": "2026-01-22T13:00:44.851708205" }, "test_fastp_paired_end_merged - stub": { "content": [ @@ -591,8 +611,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -636,7 +656,11 @@ ] ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -672,8 +696,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -689,28 +713,23 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:50:27.689379" + "timestamp": "2026-01-22T13:00:37.581047713" }, "test_fastp_paired_end_merged": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,b712fd68ed0322f4bec49ff2a5237fcc" - ] - ], [ [ { @@ -718,8 +737,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", - "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + "test_R1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_R2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" ] ] ], @@ -735,15 +754,21 @@ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" ] ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:08.68476" + "timestamp": "2026-01-23T09:46:53.190202914" }, "test_fastp_paired_end - stub": { "content": [ @@ -755,8 +780,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -794,7 +819,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -830,8 +859,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -841,28 +870,23 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:49:51.679221" + "timestamp": "2026-01-22T13:00:09.585957282" }, "test_fastp_single_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,c852d7a6dba5819e4ac8d9673bedcacc" - ] - ], [ [ { @@ -878,15 +902,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:18.834322" + "timestamp": "2026-01-23T09:46:19.624824985" }, "test_fastp_single_end_trim_fail - stub": { "content": [ @@ -940,7 +970,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -990,16 +1024,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:05:36.898142" + "timestamp": "2026-01-22T13:00:22.800659826" }, "test_fastp_paired_end_trim_fail - stub": { "content": [ @@ -1011,8 +1049,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1051,8 +1089,8 @@ }, [ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1060,7 +1098,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -1096,8 +1138,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1109,24 +1151,28 @@ }, [ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:05:49.212847" + "timestamp": "2026-01-22T13:00:30.271734068" }, "fastp test_fastp_interleaved": { "content": [ @@ -1139,36 +1185,24 @@ "test.fastp.fastq.gz:md5,217d62dc13a23e92513a1bd8e1bcea39" ] ], - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,b24e0624df5cc0b11cd5ba21b726fb22" + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] - ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:38.910832" + "timestamp": "2026-01-23T09:46:33.4628687" }, "test_fastp_single_end_trim_fail": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,9a7ee180f000e8d00c7fb67f06293eb5" - ] - ], [ [ { @@ -1190,27 +1224,24 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:48.22378" + "timestamp": "2026-01-23T09:46:39.895973372" }, "test_fastp_paired_end_qc_only": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,623064a45912dac6f2b64e3f2e9901df" - ] - ], [ ], @@ -1229,15 +1260,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:36.334938" + "timestamp": "2026-01-23T09:47:13.015833707" }, "test_fastp_paired_end_qc_only - stub": { "content": [ @@ -1279,7 +1316,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -1317,15 +1358,19 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:31:27.096468" + "timestamp": "2026-01-22T13:00:59.670106791" } } \ No newline at end of file diff --git a/modules/nf-core/fastp/tests/tags.yml b/modules/nf-core/fastp/tests/tags.yml deleted file mode 100644 index c1afcce75..000000000 --- a/modules/nf-core/fastp/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -fastp: - - modules/nf-core/fastp/** diff --git a/modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt b/modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt new file mode 100644 index 000000000..7770ccd5f --- /dev/null +++ b/modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt @@ -0,0 +1,822 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-64: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/fastqc-0.12.1-hdfd78af_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjdk-25.0.2-ha668962_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.1-hb9d3cd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 +md5: a9f577daf3de00bca7c3c76c0ecbd1de +depends: +- __glibc >=2.17,<3.0.a0 +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28948 +timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda +sha256: d88aa7ae766cf584e180996e92fef2aa7d8e0a0a5ab1d4d49c32390c1b5fff31 +md5: dcdc58c15961dbf17a0621312b01f5cb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: LGPL-2.1-or-later +license_family: GPL +size: 584660 +timestamp: 1768327524772 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 +md5: d2ffd7602c02f2b316fd921d39876885 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 260182 +timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc +md5: 4492fd26db29495f0ba23f146cd5638d +depends: +- __unix +license: ISC +size: 147413 +timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda +sha256: 06525fa0c4e4f56e771a3b986d0fdf0f0fc5a3270830ee47e127a5105bde1b9a +md5: bb6c4808bfa69d6f7f6b07e5846ced37 +depends: +- __glibc >=2.17,<3.0.a0 +- fontconfig >=2.15.0,<3.0a0 +- fonts-conda-ecosystem +- icu >=78.1,<79.0a0 +- libexpat >=2.7.3,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libglib >=2.86.3,<3.0a0 +- libpng >=1.6.53,<1.7.0a0 +- libstdcxx >=14 +- libxcb >=1.17.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- pixman >=0.46.4,<1.0a0 +- xorg-libice >=1.1.2,<2.0a0 +- xorg-libsm >=1.2.6,<2.0a0 +- xorg-libx11 >=1.8.12,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxrender >=0.9.12,<0.10.0a0 +license: LGPL-2.1-only or MPL-1.1 +size: 989514 +timestamp: 1766415934926 +- conda: https://conda.anaconda.org/bioconda/noarch/fastqc-0.12.1-hdfd78af_0.tar.bz2 +sha256: 7cc26225d590540ae95cd24940ff42f2da7479dd4cd22ae9ab9298665d06790c +md5: c9f6a4b12229f7331f79c9a00dd6e240 +depends: +- font-ttf-dejavu-sans-mono +- fontconfig +- openjdk >=8.0.144 +- perl +license: GPL >=3 +size: 11664291 +timestamp: 1677946722445 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda +sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c +md5: 867127763fbe935bab59815b6e0b7b5c +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +license: MIT +license_family: MIT +size: 270705 +timestamp: 1771382710863 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 +sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 +md5: fee5683a3f04bd15cbd8318b096a27ab +depends: +- fonts-conda-forge +license: BSD-3-Clause +license_family: BSD +size: 3667 +timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda +sha256: aac402a8298f0c0cc528664249170372ef6b37ac39fdc92b40601a6aed1e32ff +md5: 3bf7b9fd5a7136126e0234db4b87c8b6 +depends: +- libgcc-ng >=12 +license: MIT +license_family: MIT +size: 77248 +timestamp: 1712692454246 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda +sha256: 25ba37da5c39697a77fce2c9a15e48cf0a84f1464ad2aafbe53d8357a9f6cc8c +md5: 2cd94587f3a401ae05e03a6caf09539d +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: LGPL-2.0-or-later +license_family: LGPL +size: 99596 +timestamp: 1755102025473 +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda +sha256: 477f2c553f72165020d3c56740ba354be916c2f0b76fd9f535e83d698277d5ec +md5: 14470902326beee192e33719a2e8bb7f +depends: +- __glibc >=2.17,<3.0.a0 +- cairo >=1.18.4,<2.0a0 +- graphite2 >=1.3.14,<2.0a0 +- icu >=78.3,<79.0a0 +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.2 +- libfreetype6 >=2.14.2 +- libgcc >=14 +- libglib >=2.86.4,<3.0a0 +- libstdcxx >=14 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 2384060 +timestamp: 1774276284520 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda +sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a +md5: c80d8a3b84358cb967fa81e7075fbc8a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: MIT +license_family: MIT +size: 12723451 +timestamp: 1773822285671 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda +sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 +md5: b38117a3c920364aff79f870c984b4a3 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: LGPL-2.1-or-later +size: 134088 +timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda +sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 +md5: fb53fb07ce46a575c5d004bbc96032c2 +depends: +- __glibc >=2.17,<3.0.a0 +- keyutils >=1.6.3,<2.0a0 +- libedit >=3.1.20250104,<3.2.0a0 +- libedit >=3.1.20250104,<4.0a0 +- libgcc >=14 +- libstdcxx >=14 +- openssl >=3.5.5,<4.0a0 +license: MIT +license_family: MIT +size: 1386730 +timestamp: 1769769569681 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda +sha256: 836ec4b895352110335b9fdcfa83a8dcdbe6c5fb7c06c4929130600caea91c0a +md5: 6f2e2c8f58160147c4d1c6f4c14cbac4 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 249959 +timestamp: 1768184673131 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +sha256: f84cb54782f7e9cea95e810ea8fef186e0652d0fa73d3009914fa2c1262594e1 +md5: a752488c68f2e7c456bcbd8f16eec275 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 261513 +timestamp: 1773113328888 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda +sha256: 205c4f19550f3647832ec44e35e6d93c8c206782bdd620c1d7cf66237580ff9c +md5: 49c553b47ff679a6a1e9fc80b9c5a2d4 +depends: +- __glibc >=2.17,<3.0.a0 +- krb5 >=1.22.2,<1.23.0a0 +- libgcc >=14 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +license: Apache-2.0 +license_family: Apache +size: 4518030 +timestamp: 1770902209173 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 +md5: 6c77a605a7a689d17d4819c0f8ac9a00 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 73490 +timestamp: 1761979956660 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda +sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 +md5: c277e0a4d549b03ac1e9d6cbbe3d017b +depends: +- ncurses +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- ncurses >=6.5,<7.0a0 +license: BSD-2-Clause +license_family: BSD +size: 134676 +timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda +sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 +md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- expat 2.7.4.* +license: MIT +license_family: MIT +size: 76798 +timestamp: 1771259418166 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 +md5: a360c33a5abe61c07959e449fa1453eb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 58592 +timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 +md5: e289f3d17880e44b633ba911d57a321b +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8049 +timestamp: 1774298163029 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d +md5: fb16b4b69e3f1dcfe79d80db8fd0c55d +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 384575 +timestamp: 1774298162622 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda +sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 +md5: 0aa00f03f9e39fb9876085dee11a85d4 +depends: +- __glibc >=2.17,<3.0.a0 +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_18 +- libgomp 15.2.0 he0feb66_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1041788 +timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda +sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 +md5: d5e96b1ed75ca01906b3d2469b4ce493 +depends: +- libgcc 15.2.0 he0feb66_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27526 +timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda +sha256: a27e44168a1240b15659888ce0d9b938ed4bdb49e9ea68a7c1ff27bcea8b55ce +md5: bb26456332b07f68bf3b7622ed71c0da +depends: +- __glibc >=2.17,<3.0.a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- libiconv >=1.18,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- pcre2 >=10.47,<10.48.0a0 +constrains: +- glib 2.86.4 *_1 +license: LGPL-2.1-or-later +size: 4398701 +timestamp: 1771863239578 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda +sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 +md5: 239c5e9546c38a1e884d69effcf4c882 +depends: +- __glibc >=2.17,<3.0.a0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 603262 +timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda +sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f +md5: 915f5995e94f60e9a4826e0b0920ee88 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: LGPL-2.1-only +size: 790176 +timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda +sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 +md5: 8397539e3a0bbd1695584fb4f927485a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 633710 +timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda +sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb +md5: c7c83eecbb72d88b940c249af56c8b17 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- xz 5.8.2.* +license: 0BSD +size: 113207 +timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda +sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c +md5: 5f13ffc7d30ffec87864e678df9957b4 +depends: +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libzlib >=1.3.1,<2.0a0 +license: zlib-acknowledgement +size: 317669 +timestamp: 1770691470744 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda +sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e +md5: 1b08cd684f34175e4514474793d44bcb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc 15.2.0 he0feb66_18 +constrains: +- libstdcxx-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5852330 +timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 +md5: cd5a90476766d53e901500df9215e927 +depends: +- __glibc >=2.17,<3.0.a0 +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 435273 +timestamp: 1762022005702 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda +sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee +md5: db409b7c1720428638e7c0d509d3e1b5 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 40311 +timestamp: 1766271528534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b +md5: aea31d2e5b1091feca96fcfe945c3cf9 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 429011 +timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa +md5: 92ed62436b625154323d40d5f2f11dd7 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 395888 +timestamp: 1727278577118 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda +sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c +md5: 5aa797f8787fe7a17d1b0821485b5adc +depends: +- libgcc-ng >=12 +license: LGPL-2.1-or-later +size: 100393 +timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 +md5: d87ff7921124eccd67248aa483c23fec +depends: +- __glibc >=2.17,<3.0.a0 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 63629 +timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda +sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 +md5: 47e340acb35de30501a76c7c799c41d7 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: X11 AND BSD-3-Clause +size: 891641 +timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjdk-25.0.2-ha668962_0.conda +sha256: 3825a4c84676a8a5cc23b397a2911e4efa4a805daf2af764153bd904e142ec41 +md5: a41092b0177362dbe5eb2a18501e86c0 +depends: +- xorg-libx11 +- xorg-libxext +- xorg-libxi +- xorg-libxrender +- xorg-libxtst +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- xorg-libxrender >=0.9.12,<0.10.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- giflib >=5.2.2,<5.3.0a0 +- xorg-libxrandr >=1.5.5,<2.0a0 +- harfbuzz >=12.3.2 +- fontconfig >=2.17.1,<3.0a0 +- fonts-conda-ecosystem +- xorg-libxtst >=1.2.5,<2.0a0 +- xorg-libxi >=1.8.2,<2.0a0 +- lcms2 >=2.18,<3.0a0 +- alsa-lib >=1.2.15.3,<1.3.0a0 +- libpng >=1.6.55,<1.7.0a0 +- xorg-libxt >=1.3.1,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- xorg-libxext >=1.3.7,<2.0a0 +- xorg-libx11 >=1.8.13,<2.0a0 +- libcups >=2.3.3,<2.4.0a0 +license: GPL-2.0-or-later WITH Classpath-exception-2.0 +license_family: GPL +size: 122465031 +timestamp: 1771443671180 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda +sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c +md5: f61eb8cd60ff9057122a3d338b99c00f +depends: +- __glibc >=2.17,<3.0.a0 +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3164551 +timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda +sha256: 5e6f7d161356fefd981948bea5139c5aa0436767751a6930cb1ca801ebb113ff +md5: 7a3bff861a6583f1889021facefc08b1 +depends: +- __glibc >=2.17,<3.0.a0 +- bzip2 >=1.0.8,<2.0a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 1222481 +timestamp: 1763655398280 +- conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda +build_number: 7 +sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 +md5: f2cfec9406850991f4e3d960cc9e3321 +depends: +- libgcc-ng >=12 +- libxcrypt >=4.4.36 +license: GPL-1.0-or-later OR Artistic-1.0-Perl +size: 13344463 +timestamp: 1703310653947 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda +sha256: 43d37bc9ca3b257c5dd7bf76a8426addbdec381f6786ff441dc90b1a49143b6a +md5: c01af13bdc553d1a8fbfff6e8db075f0 +depends: +- libgcc >=14 +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +license: MIT +license_family: MIT +size: 450960 +timestamp: 1754665235234 +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +sha256: 4ce2e1ee31a6217998f78c31ce7dc0a3e0557d9238b51d49dd20c52d467a126d +md5: f2c23a77b25efcad57d377b34bd84941 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 593603 +timestamp: 1769710381284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 +md5: b3c17d95b5a10c6e64a21fa17573e70e +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: MIT +license_family: MIT +size: 8252 +timestamp: 1726802366959 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda +sha256: c12396aabb21244c212e488bbdc4abcdef0b7404b15761d9329f5a4a39113c4b +md5: fb901ff28063514abb6046c9ec2c4a45 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: MIT +license_family: MIT +size: 58628 +timestamp: 1734227592886 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda +sha256: 277841c43a39f738927145930ff963c5ce4c4dacf66637a3d95d802a64173250 +md5: 1c74ff8c35dcadf952a16f752ca5aa49 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- libuuid >=2.38.1,<3.0a0 +- xorg-libice >=1.1.2,<2.0a0 +license: MIT +license_family: MIT +size: 27590 +timestamp: 1741896361728 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda +sha256: 516d4060139dbb4de49a4dcdc6317a9353fb39ebd47789c14e6fe52de0deee42 +md5: 861fb6ccbc677bb9a9fb2468430b9c6a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libxcb >=1.17.0,<2.0a0 +license: MIT +license_family: MIT +size: 839652 +timestamp: 1770819209719 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b +md5: b2895afaf55bf96a8c8282a2e47a5de0 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 15321 +timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 +md5: 1dafce8548e38671bea82e3f5c6ce22f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 20591 +timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda +sha256: 79c60fc6acfd3d713d6340d3b4e296836a0f8c51602327b32794625826bd052f +md5: 34e54f03dfea3e7a2dcf1453a85f1085 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +license: MIT +license_family: MIT +size: 50326 +timestamp: 1769445253162 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda +sha256: 83c4c99d60b8784a611351220452a0a85b080668188dce5dfa394b723d7b64f4 +md5: ba231da7fccf9ea1e768caf5c7099b84 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +license: MIT +license_family: MIT +size: 20071 +timestamp: 1759282564045 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda +sha256: 1a724b47d98d7880f26da40e45f01728e7638e6ec69f35a3e11f92acd05f9e7a +md5: 17dcc85db3c7886650b8908b183d6876 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- xorg-libx11 >=1.8.10,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxfixes >=6.0.1,<7.0a0 +license: MIT +license_family: MIT +size: 47179 +timestamp: 1727799254088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda +sha256: 80ed047a5cb30632c3dc5804c7716131d767089f65877813d4ae855ee5c9d343 +md5: e192019153591938acf7322b6459d36e +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxrender >=0.9.12,<0.10.0a0 +license: MIT +license_family: MIT +size: 30456 +timestamp: 1769445263457 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda +sha256: 044c7b3153c224c6cedd4484dd91b389d2d7fd9c776ad0f4a34f099b3389f4a1 +md5: 96d57aba173e878a2089d5638016dc5e +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- xorg-libx11 >=1.8.10,<2.0a0 +license: MIT +license_family: MIT +size: 33005 +timestamp: 1734229037766 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.1-hb9d3cd8_0.conda +sha256: a8afba4a55b7b530eb5c8ad89737d60d60bc151a03fbef7a2182461256953f0e +md5: 279b0de5f6ba95457190a1c459a64e31 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- xorg-libice >=1.1.1,<2.0a0 +- xorg-libsm >=1.2.4,<2.0a0 +- xorg-libx11 >=1.8.10,<2.0a0 +license: MIT +license_family: MIT +size: 379686 +timestamp: 1731860547604 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda +sha256: 752fdaac5d58ed863bbf685bb6f98092fe1a488ea8ebb7ed7b606ccfce08637a +md5: 7bbe9a0cc0df0ac5f5a8ad6d6a11af2f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- xorg-libx11 >=1.8.10,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxi >=1.7.10,<2.0a0 +license: MIT +license_family: MIT +size: 32808 +timestamp: 1727964811275 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 +md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 +depends: +- __glibc >=2.17,<3.0.a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 601375 +timestamp: 1764777111296 diff --git a/modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt b/modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt new file mode 100644 index 000000000..cdc434cad --- /dev/null +++ b/modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt @@ -0,0 +1,769 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-aarch64: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/fastqc-0.12.1-hdfd78af_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/giflib-5.2.2-h31becfc_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.1-h1134a53_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjdk-25.0.2-h488f50d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/perl-5.32.1-7_h31becfc_perl5.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxt-1.3.1-h57736b2_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: a2527b1d81792a0ccd2c05850960df119c2b6d8f5fdec97f2db7d25dc23b1068 +md5: 468fd3bb9e1f671d36c2cbc677e56f1d +depends: +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28926 +timestamp: 1770939656741 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda +sha256: ea2233e2db9908c2e5f29d3ca420a546b4583253f4f70abb5494cdd676866d42 +md5: 4a98cbc4ade694520227402ff8880630 +depends: +- libgcc >=14 +license: LGPL-2.1-or-later +license_family: GPL +size: 615729 +timestamp: 1768327548407 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +sha256: b3495077889dde6bb370938e7db82be545c73e8589696ad0843a32221520ad4c +md5: 840d8fc0d7b3209be93080bc20e07f2d +depends: +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 192412 +timestamp: 1771350241232 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc +md5: 4492fd26db29495f0ba23f146cd5638d +depends: +- __unix +license: ISC +size: 147413 +timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda +sha256: 675db823f3d6fb6bf747fab3b0170ba99b269a07cf6df1e49fff2f9972be9cd1 +md5: 043c13ed3a18396994be9b4fab6572ad +depends: +- fontconfig >=2.15.0,<3.0a0 +- fonts-conda-ecosystem +- icu >=78.1,<79.0a0 +- libexpat >=2.7.3,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libglib >=2.86.3,<3.0a0 +- libpng >=1.6.53,<1.7.0a0 +- libstdcxx >=14 +- libxcb >=1.17.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- pixman >=0.46.4,<1.0a0 +- xorg-libice >=1.1.2,<2.0a0 +- xorg-libsm >=1.2.6,<2.0a0 +- xorg-libx11 >=1.8.12,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxrender >=0.9.12,<0.10.0a0 +license: LGPL-2.1-only or MPL-1.1 +size: 927045 +timestamp: 1766416003626 +- conda: https://conda.anaconda.org/bioconda/noarch/fastqc-0.12.1-hdfd78af_0.tar.bz2 +sha256: 7cc26225d590540ae95cd24940ff42f2da7479dd4cd22ae9ab9298665d06790c +md5: c9f6a4b12229f7331f79c9a00dd6e240 +depends: +- font-ttf-dejavu-sans-mono +- fontconfig +- openjdk >=8.0.144 +- perl +license: GPL >=3 +size: 11664291 +timestamp: 1677946722445 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda +sha256: 835aff8615dd8d8fff377679710ce81b8a2c47b6404e21a92fb349fda193a15c +md5: 0fed1ff55f4938a65907f3ecf62609db +depends: +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +license: MIT +license_family: MIT +size: 279044 +timestamp: 1771382728182 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 +sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 +md5: fee5683a3f04bd15cbd8318b096a27ab +depends: +- fonts-conda-forge +license: BSD-3-Clause +license_family: BSD +size: 3667 +timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/giflib-5.2.2-h31becfc_0.conda +sha256: a79dc3bd54c4fb1f249942ee2d5b601a76ecf9614774a4cff9af49adfa458db2 +md5: 2f809afaf0ba1ea4135dce158169efac +depends: +- libgcc-ng >=12 +license: MIT +license_family: MIT +size: 82124 +timestamp: 1712692444545 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda +sha256: c9b1781fe329e0b77c5addd741e58600f50bef39321cae75eba72f2f381374b7 +md5: 4aa540e9541cc9d6581ab23ff2043f13 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: LGPL-2.0-or-later +license_family: LGPL +size: 102400 +timestamp: 1755102000043 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.1-h1134a53_0.conda +sha256: e22f485fddaaea3ff4b6cae98e0197b9dccd2ed2770337ad6ff38a92afe04e59 +md5: 05d65a2cf410adc331c9ea61f59f1013 +depends: +- cairo >=1.18.4,<2.0a0 +- graphite2 >=1.3.14,<2.0a0 +- icu >=78.3,<79.0a0 +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.2 +- libfreetype6 >=2.14.2 +- libgcc >=14 +- libglib >=2.86.4,<3.0a0 +- libstdcxx >=14 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 2345732 +timestamp: 1774281448329 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda +sha256: 49ba6aed2c6b482bb0ba41078057555d29764299bc947b990708617712ef6406 +md5: 546da38c2fa9efacf203e2ad3f987c59 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: MIT +license_family: MIT +size: 12837286 +timestamp: 1773822650615 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda +sha256: 5ce830ca274b67de11a7075430a72020c1fb7d486161a82839be15c2b84e9988 +md5: e7df0aab10b9cbb73ab2a467ebfaf8c7 +depends: +- libgcc >=13 +license: LGPL-2.1-or-later +size: 129048 +timestamp: 1754906002667 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda +sha256: b53999d888dda53c506b264e8c02b5f5c8e022c781eda0718f007339e6bc90ba +md5: d9ca108bd680ea86a963104b6b3e95ca +depends: +- keyutils >=1.6.3,<2.0a0 +- libedit >=3.1.20250104,<3.2.0a0 +- libedit >=3.1.20250104,<4.0a0 +- libgcc >=14 +- libstdcxx >=14 +- openssl >=3.5.5,<4.0a0 +license: MIT +license_family: MIT +size: 1517436 +timestamp: 1769773395215 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda +sha256: 379ef5e91a587137391a6149755d0e929f1a007d2dcb211318ac670a46c8596f +md5: bb960f01525b5e001608afef9d47b79c +depends: +- libgcc >=14 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 293039 +timestamp: 1768184778398 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +sha256: 8957fd460c1c132c8031f65fd5f56ec3807fd71b7cab2c5e2b0937b13404ab36 +md5: d13423b06447113a90b5b1366d4da171 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 240444 +timestamp: 1773114901155 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda +sha256: 41b04f995c9f63af8c4065a35931e46cbc2fdd6b9bf7e4c19f90d53cbb2bc8e5 +md5: 67828c963b17db7dc989fe5d509ef04a +depends: +- krb5 >=1.22.2,<1.23.0a0 +- libgcc >=14 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +license: Apache-2.0 +license_family: Apache +size: 4553739 +timestamp: 1770903929794 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +sha256: 48814b73bd462da6eed2e697e30c060ae16af21e9fbed30d64feaf0aad9da392 +md5: a9138815598fe6b91a1d6782ca657b0c +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 71117 +timestamp: 1761979776756 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda +sha256: c0b27546aa3a23d47919226b3a1635fccdb4f24b94e72e206a751b33f46fd8d6 +md5: fb640d776fc92b682a14e001980825b1 +depends: +- ncurses +- libgcc >=13 +- ncurses >=6.5,<7.0a0 +license: BSD-2-Clause +license_family: BSD +size: 148125 +timestamp: 1738479808948 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda +sha256: 995ce3ad96d0f4b5ed6296b051a0d7b6377718f325bc0e792fbb96b0e369dad7 +md5: 57f3b3da02a50a1be2a6fe847515417d +depends: +- libgcc >=14 +constrains: +- expat 2.7.4.* +license: MIT +license_family: MIT +size: 76564 +timestamp: 1771259530958 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +sha256: 3df4c539449aabc3443bbe8c492c01d401eea894603087fca2917aa4e1c2dea9 +md5: 2f364feefb6a7c00423e80dcb12db62a +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 55952 +timestamp: 1769456078358 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +sha256: 752e4f66283d7deb4c6fd47d88df644d8daa2aaa825a54f3bf350a625190192a +md5: a229e22d4d8814a07702b0919d8e6701 +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8125 +timestamp: 1774301094057 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +sha256: 8e6b27fe4eec4c2fa7b7769a21973734c8dba1de80086fb0213e58375ac09f4c +md5: b99ed99e42dafb27889483b3098cace7 +depends: +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 422941 +timestamp: 1774301093473 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda +sha256: 43df385bedc1cab11993c4369e1f3b04b4ca5d0ea16cba6a0e7f18dbc129fcc9 +md5: 552567ea2b61e3a3035759b2fdb3f9a6 +depends: +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_18 +- libgomp 15.2.0 h8acb6b2_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 622900 +timestamp: 1771378128706 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda +sha256: 83bb0415f59634dccfa8335d4163d1f6db00a27b36666736f9842b650b92cf2f +md5: 4feebd0fbf61075a1a9c2e9b3936c257 +depends: +- libgcc 15.2.0 h8acb6b2_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27568 +timestamp: 1771378136019 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda +sha256: afc503dbd04a5bf2709aa9d8318a03a8c4edb389f661ff280c3494bfef4341ec +md5: 4ac4372fc4d7f20630a91314cdac8afd +depends: +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- libiconv >=1.18,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- pcre2 >=10.47,<10.48.0a0 +constrains: +- glib 2.86.4 *_1 +license: LGPL-2.1-or-later +size: 4512186 +timestamp: 1771863220969 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda +sha256: fc716f11a6a8525e27a5d332ef6a689210b0d2a4dd1133edc0f530659aa9faa6 +md5: 4faa39bf919939602e594253bd673958 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 588060 +timestamp: 1771378040807 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda +sha256: 1473451cd282b48d24515795a595801c9b65b567fe399d7e12d50b2d6cdb04d9 +md5: 5a86bf847b9b926f3a4f203339748d78 +depends: +- libgcc >=14 +license: LGPL-2.1-only +size: 791226 +timestamp: 1754910975665 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda +sha256: 84064c7c53a64291a585d7215fe95ec42df74203a5bf7615d33d49a3b0f08bb6 +md5: 5109d7f837a3dfdf5c60f60e311b041f +depends: +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 691818 +timestamp: 1762094728337 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda +sha256: 843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3 +md5: 96944e3c92386a12755b94619bae0b35 +depends: +- libgcc >=14 +constrains: +- xz 5.8.2.* +license: 0BSD +size: 125916 +timestamp: 1768754941722 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda +sha256: c7378c6b79de4d571d00ad1caf0a4c19d43c9c94077a761abb6ead44d891f907 +md5: be4088903b94ea297975689b3c3aeb27 +depends: +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: zlib-acknowledgement +size: 340156 +timestamp: 1770691477245 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda +sha256: 31fdb9ffafad106a213192d8319b9f810e05abca9c5436b60e507afb35a6bc40 +md5: f56573d05e3b735cb03efeb64a15f388 +depends: +- libgcc 15.2.0 h8acb6b2_18 +constrains: +- libstdcxx-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5541411 +timestamp: 1771378162499 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +sha256: 7ff79470db39e803e21b8185bc8f19c460666d5557b1378d1b1e857d929c6b39 +md5: 8c6fd84f9c87ac00636007c6131e457d +depends: +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 488407 +timestamp: 1762022048105 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda +sha256: c37a8e89b700646f3252608f8368e7eb8e2a44886b92776e57ad7601fc402a11 +md5: cf2861212053d05f27ec49c3784ff8bb +depends: +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 43453 +timestamp: 1766271546875 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +sha256: b03700a1f741554e8e5712f9b06dd67e76f5301292958cd3cb1ac8c6fdd9ed25 +md5: 24e92d0942c799db387f5c9d7b81f1af +depends: +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 359496 +timestamp: 1752160685488 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +sha256: 461cab3d5650ac6db73a367de5c8eca50363966e862dcf60181d693236b1ae7b +md5: cd14ee5cca2464a425b1dbfc24d90db2 +depends: +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 397493 +timestamp: 1727280745441 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda +sha256: 6b46c397644091b8a26a3048636d10b989b1bf266d4be5e9474bf763f828f41f +md5: b4df5d7d4b63579d081fd3a4cf99740e +depends: +- libgcc-ng >=12 +license: LGPL-2.1-or-later +size: 114269 +timestamp: 1702724369203 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +sha256: eb111e32e5a7313a5bf799c7fb2419051fa2fe7eff74769fac8d5a448b309f7f +md5: 502006882cf5461adced436e410046d1 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 69833 +timestamp: 1774072605429 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda +sha256: 91cfb655a68b0353b2833521dc919188db3d8a7f4c64bea2c6a7557b24747468 +md5: 182afabe009dc78d8b73100255ee6868 +depends: +- libgcc >=13 +license: X11 AND BSD-3-Clause +size: 926034 +timestamp: 1738196018799 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjdk-25.0.2-h488f50d_0.conda +sha256: 6fd2c872b275fa5d42a61a4b6dc28a819cde29f9048adb547363597432e0720e +md5: 27fdd5d67e235c20d23b2d66406497d3 +depends: +- xorg-libx11 +- xorg-libxext +- xorg-libxi +- xorg-libxrender +- xorg-libxtst +- libstdcxx >=14 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +- xorg-libxtst >=1.2.5,<2.0a0 +- libpng >=1.6.55,<1.7.0a0 +- alsa-lib >=1.2.15.3,<1.3.0a0 +- xorg-libx11 >=1.8.13,<2.0a0 +- xorg-libxi >=1.8.2,<2.0a0 +- xorg-libxrandr >=1.5.5,<2.0a0 +- lcms2 >=2.18,<3.0a0 +- xorg-libxrender >=0.9.12,<0.10.0a0 +- libcups >=2.3.3,<2.4.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- harfbuzz >=12.3.2 +- xorg-libxext >=1.3.7,<2.0a0 +- giflib >=5.2.2,<5.3.0a0 +- xorg-libxt >=1.3.1,<2.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- fontconfig >=2.17.1,<3.0a0 +- fonts-conda-ecosystem +license: GPL-2.0-or-later WITH Classpath-exception-2.0 +license_family: GPL +size: 106988620 +timestamp: 1771443741031 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda +sha256: 7f8048c0e75b2620254218d72b4ae7f14136f1981c5eb555ef61645a9344505f +md5: 25f5885f11e8b1f075bccf4a2da91c60 +depends: +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3692030 +timestamp: 1769557678657 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda +sha256: 04df2cee95feba440387f33f878e9f655521e69f4be33a0cd637f07d3d81f0f9 +md5: 1a30c42e32ca0ea216bd0bfe6f842f0b +depends: +- bzip2 >=1.0.8,<2.0a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 1166552 +timestamp: 1763655534263 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/perl-5.32.1-7_h31becfc_perl5.conda +build_number: 7 +sha256: d78296134263b5bf476cad838ded65451e7162db756f9997c5d06b08122572ed +md5: 17d019cb2a6c72073c344e98e40dfd61 +depends: +- libgcc-ng >=12 +- libxcrypt >=4.4.36 +license: GPL-1.0-or-later OR Artistic-1.0-Perl +size: 13338804 +timestamp: 1703310557094 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda +sha256: e6b0846a998f2263629cfeac7bca73565c35af13251969f45d385db537a514e4 +md5: 1587081d537bd4ae77d1c0635d465ba5 +depends: +- libgcc >=14 +- libstdcxx >=14 +- libgcc >=14 +license: MIT +license_family: MIT +size: 357913 +timestamp: 1754665583353 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +sha256: e9cbcbc94e151ada3d6dc365380aaaf591f65012c16d9a2abaea4b9b90adc402 +md5: ab7288cc39545556d1bc5e71ab2df9a9 +depends: +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 636733 +timestamp: 1769712412683 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +sha256: 977dfb0cb3935d748521dd80262fe7169ab82920afd38ed14b7fee2ea5ec01ba +md5: bb5a90c93e3bac3d5690acf76b4a6386 +depends: +- libgcc >=13 +license: MIT +license_family: MIT +size: 8342 +timestamp: 1726803319942 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda +sha256: a2ba1864403c7eb4194dacbfe2777acf3d596feae43aada8d1b478617ce45031 +md5: c8d8ec3e00cd0fd8a231789b91a7c5b7 +depends: +- libgcc >=13 +license: MIT +license_family: MIT +size: 60433 +timestamp: 1734229908988 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda +sha256: b86a819cd16f90c01d9d81892155126d01555a20dabd5f3091da59d6309afd0a +md5: 2d1409c50882819cb1af2de82e2b7208 +depends: +- libgcc >=13 +- libuuid >=2.38.1,<3.0a0 +- xorg-libice >=1.1.2,<2.0a0 +license: MIT +license_family: MIT +size: 28701 +timestamp: 1741897678254 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda +sha256: cf886160e2ff580d77f7eb8ec1a77c41c2c5b05343e329bc35f0ddf40b8d92ab +md5: 22dd10425ef181e80e130db50675d615 +depends: +- libgcc >=14 +- libxcb >=1.17.0,<2.0a0 +license: MIT +license_family: MIT +size: 869058 +timestamp: 1770819244991 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +sha256: e9f6e931feeb2f40e1fdbafe41d3b665f1ab6cb39c5880a1fcf9f79a3f3c84a5 +md5: 1c246e1105000c3660558459e2fd6d43 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 16317 +timestamp: 1762977521691 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +sha256: 128d72f36bcc8d2b4cdbec07507542e437c7d67f677b7d77b71ed9eeac7d6df1 +md5: bff06dcde4a707339d66d45d96ceb2e2 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 21039 +timestamp: 1762979038025 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda +sha256: db2188bc0d844d4e9747bac7f6c1d067e390bd769c5ad897c93f1df759dc5dba +md5: fb42b683034619915863d68dd9df03a3 +depends: +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +license: MIT +license_family: MIT +size: 52409 +timestamp: 1769446753771 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda +sha256: 8cb9c88e25c57e47419e98f04f9ef3154ad96b9f858c88c570c7b91216a64d0e +md5: e8b4056544341daf1d415eaeae7a040c +depends: +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +license: MIT +license_family: MIT +size: 20704 +timestamp: 1759284028146 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda +sha256: 7b587407ecb9ccd2bbaf0fb94c5dbdde4d015346df063e9502dc0ce2b682fb5e +md5: eeee3bdb31c6acde2b81ad1b8c287087 +depends: +- libgcc >=13 +- xorg-libx11 >=1.8.9,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxfixes >=6.0.1,<7.0a0 +license: MIT +license_family: MIT +size: 48197 +timestamp: 1727801059062 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda +sha256: 9f5196665a8d72f4f119c40dcc4bafeb0b540b102cc7b8b299c2abf599e7919f +md5: 1f64c613f0b8d67e9fb0e165d898fb6b +depends: +- libgcc >=14 +- xorg-libx11 >=1.8.12,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxrender >=0.9.12,<0.10.0a0 +license: MIT +license_family: MIT +size: 31122 +timestamp: 1769445286951 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda +sha256: ffd77ee860c9635a28cfda46163dcfe9224dc6248c62404c544ae6b564a0be1f +md5: ae2c2dd0e2d38d249887727db2af960e +depends: +- libgcc >=13 +- xorg-libx11 >=1.8.10,<2.0a0 +license: MIT +license_family: MIT +size: 33649 +timestamp: 1734229123157 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxt-1.3.1-h57736b2_0.conda +sha256: 7c109792b60720809a580612aba7f8eb2a0bd425b9fc078748a9d6ffc97cbfa8 +md5: a9e4852c8e0b68ee783e7240030b696f +depends: +- libgcc >=13 +- xorg-libice >=1.1.1,<2.0a0 +- xorg-libsm >=1.2.4,<2.0a0 +- xorg-libx11 >=1.8.9,<2.0a0 +license: MIT +license_family: MIT +size: 384752 +timestamp: 1731860572314 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda +sha256: 6eaffce5a34fc0a16a21ddeaefb597e792a263b1b0c387c1ce46b0a967d558e1 +md5: c05698071b5c8e0da82a282085845860 +depends: +- libgcc >=13 +- xorg-libx11 >=1.8.9,<2.0a0 +- xorg-libxext >=1.3.6,<2.0a0 +- xorg-libxi >=1.7.10,<2.0a0 +license: MIT +license_family: MIT +size: 33786 +timestamp: 1727964907993 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +sha256: 569990cf12e46f9df540275146da567d9c618c1e9c7a0bc9d9cfefadaed20b75 +md5: c3655f82dcea2aa179b291e7099c1fcc +depends: +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 614429 +timestamp: 1764777145593 diff --git a/modules/nf-core/fastqc/environment.yml b/modules/nf-core/fastqc/environment.yml index 691d4c763..f9f54ee9b 100644 --- a/modules/nf-core/fastqc/environment.yml +++ b/modules/nf-core/fastqc/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 033f4154a..10851264c 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -1,37 +1,40 @@ process FASTQC { tag "${meta.id}" - label 'process_medium' + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/fastqc:0.12.1--hdfd78af_0' : - 'biocontainers/fastqc:0.12.1--hdfd78af_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/fastqc:0.12.1--hdfd78af_0' + : 'quay.io/biocontainers/fastqc:0.12.1--hdfd78af_0'}" input: - tuple val(meta), path(reads) + tuple val(meta), path(reads, stageAs: '?/*') output: tuple val(meta), path("*.html"), emit: html - tuple val(meta), path("*.zip") , emit: zip - path "versions.yml" , emit: versions + tuple val(meta), path("*.zip"), emit: zip + tuple val("${task.process}"), val('fastqc'), eval('fastqc --version | sed "/FastQC v/!d; s/.*v//"'), emit: versions_fastqc, topic: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" // Make list of old name and new name pairs to use for renaming in the bash while loop - def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] } - def rename_to = old_new_pairs*.join(' ').join(' ') - def renamed_files = old_new_pairs.collect{ _old_name, new_name -> new_name }.join(' ') + def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[reads, "${prefix}.${reads.extension}"]] : reads.withIndex().collect { entry, index -> [entry, "${prefix}_${index + 1}.${entry.extension}"] } + def rename_to = old_new_pairs*.join(' ').join(' ') + def renamed_files = old_new_pairs.collect { _old_name, new_name -> new_name }.join(' ') // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) // https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 - // Dividing the task.memory by task.cpu allows to stick to requested amount of RAM in the label - def memory_in_mb = task.memory ? task.memory.toUnit('MB').toFloat() / task.cpus : null + // Dividing the task.memory by task.cpus allows to stick to requested amount of RAM in the label + def memory_in_mb = task.memory + ? (task.memory.toUnit('MB') / task.cpus).intValue() + : null // FastQC memory value allowed range (100 - 10000) def fastqc_memory = memory_in_mb > 10000 ? 10000 : (memory_in_mb < 100 ? 100 : memory_in_mb) + def fastqc_memory_arg = fastqc_memory ? "--memory ${fastqc_memory}" : '' """ printf "%s %s\\n" ${rename_to} | while read old_name new_name; do @@ -41,13 +44,8 @@ process FASTQC { fastqc \\ ${args} \\ --threads ${task.cpus} \\ - --memory ${fastqc_memory} \\ + ${fastqc_memory_arg} \\ ${renamed_files} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed '/FastQC v/!d; s/.*v//' ) - END_VERSIONS """ stub: @@ -55,10 +53,5 @@ process FASTQC { """ touch ${prefix}.html touch ${prefix}.zip - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed '/FastQC v/!d; s/.*v//' ) - END_VERSIONS """ } diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml index 2b2e62b8a..2f6cfef6d 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -29,9 +29,10 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: [] output: - - html: - - meta: + html: + - - meta: type: map description: | Groovy Map containing sample information @@ -40,8 +41,9 @@ output: type: file description: FastQC report pattern: "*_{fastqc.html}" - - zip: - - meta: + ontologies: [] + zip: + - - meta: type: map description: | Groovy Map containing sample information @@ -50,11 +52,29 @@ output: type: file description: FastQC report archive pattern: "*_{fastqc.zip}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_fastqc: + - - ${task.process}: + type: string + description: The process the versions were collected from + - fastqc: + type: string + description: The tool name + - fastqc --version | sed "/FastQC v/!d; s/.*v//": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - fastqc: + type: string + description: The tool name + - fastqc --version | sed "/FastQC v/!d; s/.*v//": + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@grst" @@ -65,3 +85,27 @@ maintainers: - "@grst" - "@ewels" - "@FelixKrueger" +containers: + docker: + linux/arm64: + name: community.wave.seqera.io/library/fastqc:0.12.1--e455e32f745abe68 + build_id: bd-e455e32f745abe68_1 + scan_id: sc-f102f736465af88c_1 + linux/amd64: + name: community.wave.seqera.io/library/fastqc:0.12.1--5cb1a2fa2f18c7c2 + build_id: bd-5cb1a2fa2f18c7c2_1 + scan_id: sc-0c0466326b6b77d2_1 + singularity: + linux/amd64: + name: oras://community.wave.seqera.io/library/fastqc:0.12.1--5c4bd442468d75dd + build_id: bd-5c4bd442468d75dd_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f2/f20b021476d1d87658820f971ebecc1e8cdbde0f338eb0d9cea2b0a8fc54a54b/data + linux/arm64: + name: oras://community.wave.seqera.io/library/fastqc:0.12.1--127a87fc06499035 + build_id: bd-127a87fc06499035_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/46/46daf2dad0169afd2ae047c3e50ed3776259f664bf07e5e06b045dc23449e994/data + conda: + linux/amd64: + lock_file: modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt + linux/arm64: + lock_file: modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt diff --git a/modules/nf-core/fastqc/tests/main.nf.test b/modules/nf-core/fastqc/tests/main.nf.test index e9d79a074..66c44da9b 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test +++ b/modules/nf-core/fastqc/tests/main.nf.test @@ -30,7 +30,7 @@ nextflow_process { { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } @@ -58,7 +58,7 @@ nextflow_process { { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } @@ -82,7 +82,7 @@ nextflow_process { { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } @@ -106,7 +106,7 @@ nextflow_process { { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } @@ -142,7 +142,7 @@ nextflow_process { { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } @@ -166,7 +166,7 @@ nextflow_process { { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" }, { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" }, { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } ) } } diff --git a/modules/nf-core/fastqc/tests/main.nf.test.snap b/modules/nf-core/fastqc/tests/main.nf.test.snap index d5db3092f..c8ee120f5 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test.snap +++ b/modules/nf-core/fastqc/tests/main.nf.test.snap @@ -1,15 +1,21 @@ { "sarscov2 custom_prefix": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:16.374038" + "timestamp": "2025-10-28T16:39:14.518503" }, "sarscov2 single-end [fastq] - stub": { "content": [ @@ -33,7 +39,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -44,8 +54,12 @@ "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -59,10 +73,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:24.993809" + "timestamp": "2025-10-28T16:39:19.309008" }, "sarscov2 custom_prefix - stub": { "content": [ @@ -86,7 +100,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -97,8 +115,12 @@ "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -112,58 +134,82 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:03:10.93942" + "timestamp": "2025-10-28T16:39:44.94888" }, "sarscov2 interleaved [fastq]": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:01:42.355718" + "timestamp": "2025-10-28T16:38:45.168496" }, "sarscov2 paired-end [bam]": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:01:53.276274" + "timestamp": "2025-10-28T16:38:53.268919" }, "sarscov2 multiple [fastq]": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:05.527626" + "timestamp": "2025-10-28T16:39:05.050305" }, "sarscov2 paired-end [fastq]": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:01:31.188871" + "timestamp": "2025-10-28T16:38:37.2373" }, "sarscov2 paired-end [fastq] - stub": { "content": [ @@ -187,7 +233,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -198,8 +248,12 @@ "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -213,10 +267,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:34.273566" + "timestamp": "2025-10-28T16:39:24.450398" }, "sarscov2 multiple [fastq] - stub": { "content": [ @@ -240,7 +294,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -251,8 +309,12 @@ "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -266,22 +328,28 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:03:02.304411" + "timestamp": "2025-10-28T16:39:39.758762" }, "sarscov2 single-end [fastq]": { "content": [ - [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:01:19.095607" + "timestamp": "2025-10-28T16:38:29.555068" }, "sarscov2 interleaved [fastq] - stub": { "content": [ @@ -305,7 +373,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -316,8 +388,12 @@ "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -331,10 +407,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:44.640184" + "timestamp": "2025-10-28T16:39:29.193136" }, "sarscov2 paired-end [bam] - stub": { "content": [ @@ -358,7 +434,11 @@ ] ], "2": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "html": [ [ @@ -369,8 +449,12 @@ "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + "versions_fastqc": [ + [ + "FASTQC", + "fastqc", + "0.12.1" + ] ], "zip": [ [ @@ -384,9 +468,9 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nf-test": "0.9.2", + "nextflow": "25.10.0" }, - "timestamp": "2024-07-22T11:02:53.550742" + "timestamp": "2025-10-28T16:39:34.144919" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/bedtointervallist/environment.yml b/modules/nf-core/gatk4/bedtointervallist/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/bedtointervallist/environment.yml +++ b/modules/nf-core/gatk4/bedtointervallist/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/bedtointervallist/main.nf b/modules/nf-core/gatk4/bedtointervallist/main.nf index 68863d677..60b10ed1c 100644 --- a/modules/nf-core/gatk4/bedtointervallist/main.nf +++ b/modules/nf-core/gatk4/bedtointervallist/main.nf @@ -1,11 +1,11 @@ process GATK4_BEDTOINTERVALLIST { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(bed) @@ -13,7 +13,7 @@ process GATK4_BEDTOINTERVALLIST { output: tuple val(meta), path('*.interval_list'), emit: interval_list - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -24,33 +24,24 @@ process GATK4_BEDTOINTERVALLIST { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ BedToIntervalList \\ - --INPUT $bed \\ + --INPUT ${bed} \\ --OUTPUT ${prefix}.interval_list \\ - --SEQUENCE_DICTIONARY $dict \\ + --SEQUENCE_DICTIONARY ${dict} \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.interval_list - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/bedtointervallist/meta.yml b/modules/nf-core/gatk4/bedtointervallist/meta.yml index 25348e162..a3e2f2347 100644 --- a/modules/nf-core/gatk4/bedtointervallist/meta.yml +++ b/modules/nf-core/gatk4/bedtointervallist/meta.yml @@ -26,6 +26,7 @@ input: type: file description: Input bed file pattern: "*.bed" + ontologies: [] - - meta2: type: map description: | @@ -35,25 +36,40 @@ input: type: file description: Sequence dictionary pattern: "*.dict" + ontologies: [] output: - - interval_list: - - meta: + interval_list: + - - meta: type: file description: gatk interval list file pattern: "*.interval_list" + ontologies: [] - "*.interval_list": type: file description: gatk interval list file pattern: "*.interval_list" - - _list: - type: file - description: gatk interval list file - pattern: "*.interval_list" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test index 2289f73fa..8d318e906 100644 --- a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test +++ b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test @@ -15,7 +15,7 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - [file(params.modules_testdata_base_path + + [file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] ] input[1] = [ [ id:'dict' ], // meta map @@ -27,12 +27,35 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } -} \ No newline at end of file + test("test_gatk4_bedtointervallist - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + [file(params.modules_testdata_base_path + + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] + ] + input[1] = [ [ id:'dict' ], // meta map + [file(params.modules_testdata_base_path + + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap index 48c322fd0..554425060 100644 --- a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap @@ -1,4 +1,45 @@ { + "test_gatk4_bedtointervallist - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GATK4_BEDTOINTERVALLIST", + "gatk4", + "4.6.2.0" + ] + ], + "interval_list": [ + [ + { + "id": "test" + }, + "test.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gatk4": [ + [ + "GATK4_BEDTOINTERVALLIST", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-22T09:52:55.698969373" + }, "test_gatk4_bedtointervallist": { "content": [ { @@ -11,7 +52,11 @@ ] ], "1": [ - "versions.yml:md5,29a18c36f27584eb5a5f2f5457088b3b" + [ + "GATK4_BEDTOINTERVALLIST", + "gatk4", + "4.6.2.0" + ] ], "interval_list": [ [ @@ -21,15 +66,19 @@ "test.interval_list:md5,e51101c9357fb2d59fd30e370eefa39c" ] ], - "versions": [ - "versions.yml:md5,29a18c36f27584eb5a5f2f5457088b3b" + "versions_gatk4": [ + [ + "GATK4_BEDTOINTERVALLIST", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-03-19T14:20:12.168775" + "timestamp": "2026-01-22T09:52:46.629308651" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/bedtointervallist/tests/tags.yml b/modules/nf-core/gatk4/bedtointervallist/tests/tags.yml deleted file mode 100644 index b4d54f129..000000000 --- a/modules/nf-core/gatk4/bedtointervallist/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/bedtointervallist: - - "modules/nf-core/gatk4/bedtointervallist/**" diff --git a/modules/nf-core/gatk4/calculatecontamination/environment.yml b/modules/nf-core/gatk4/calculatecontamination/environment.yml new file mode 100644 index 000000000..67e0eb860 --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/calculatecontamination/main.nf b/modules/nf-core/gatk4/calculatecontamination/main.nf new file mode 100644 index 000000000..2601a69d8 --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/main.nf @@ -0,0 +1,49 @@ +process GATK4_CALCULATECONTAMINATION { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" + + input: + tuple val(meta), path(pileup), path(matched) + + output: + tuple val(meta), path('*.contamination.table'), emit: contamination + tuple val(meta), path('*.segmentation.table'), emit: segmentation, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def matched_command = matched ? "--matched-normal ${matched}" : '' + + def avail_mem = 3072 + if (!task.memory) { + log.info('[GATK CalculateContamination] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() + } + """ + gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ + CalculateContamination \\ + --input ${pileup} \\ + --output ${prefix}.contamination.table \\ + ${matched_command} \\ + --tmp-dir . \\ + ${args} + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.contamination.table + touch ${prefix}.segmentation.table + """ +} diff --git a/modules/nf-core/gatk4/calculatecontamination/meta.yml b/modules/nf-core/gatk4/calculatecontamination/meta.yml new file mode 100644 index 000000000..f07240b56 --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/meta.yml @@ -0,0 +1,90 @@ +name: gatk4_calculatecontamination +description: | + Calculates the fraction of reads from cross-sample contamination based on summary tables from getpileupsummaries. Output to be used with filtermutectcalls. +keywords: + - gatk4 + - calculatecontamination + - cross-samplecontamination + - getpileupsummaries + - filtermutectcalls +tools: + - gatk4: + description: | + Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools + with a primary focus on variant discovery and genotyping. Its powerful processing engine + and high-performance computing features make it capable of taking on projects of any size. + homepage: https://gatk.broadinstitute.org/hc/en-us + documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s + doi: 10.1158/1538-7445.AM2017-3590 + licence: ["Apache-2.0"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - pileup: + type: file + description: File containing the pileups summary table of a tumor sample to + be used to calculate contamination. + pattern: "*.pileups.table" + ontologies: [] + - matched: + type: file + description: File containing the pileups summary table of a normal sample that + matches with the tumor sample specified in pileup argument. This is an optional + input. + pattern: "*.pileups.table" + ontologies: [] +output: + contamination: + - - meta: + type: file + description: File containing the contamination table. + pattern: "*.contamination.table" + ontologies: [] + - "*.contamination.table": + type: file + description: File containing the contamination table. + pattern: "*.contamination.table" + ontologies: [] + segmentation: + - - meta: + type: file + description: File containing the contamination table. + pattern: "*.contamination.table" + ontologies: [] + - "*.segmentation.table": + type: file + description: output table containing segmentation of tumor minor allele fractions + (optional) + pattern: "*.segmentation.table" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@GCJMackenzie" + - "@maxulysse" +maintainers: + - "@GCJMackenzie" + - "@maxulysse" diff --git a/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test b/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test new file mode 100644 index 000000000..6e4bb5ea9 --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test @@ -0,0 +1,107 @@ +nextflow_process { + + name "Test Process GATK4_CALCULATECONTAMINATION" + script "../main.nf" + process "GATK4_CALCULATECONTAMINATION" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/calculatecontamination" + + test("human - pileup-table") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test2.pileups.table', checkIfExists: true), + [] ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.contamination.get(0).get(1)).readLines()[0], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("human - pileup-table - matched-pair") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test2.pileups.table', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test.pileups.table', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.contamination.get(0).get(1)).readLines()[0], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("human - pileup-table - segmentation") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test2.pileups.table', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test.pileups.table', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.contamination.get(0).get(1)).readLines()[0], + file(process.out.segmentation.get(0).get(1)).readLines()[0], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("human - pileup-table - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/test2.pileups.table', checkIfExists: true), + [] ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test.snap b/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test.snap new file mode 100644 index 000000000..33077c56c --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/tests/main.nf.test.snap @@ -0,0 +1,117 @@ +{ + "human - pileup-table": { + "content": [ + "sample\tcontamination\terror", + { + "versions_gatk4": [ + [ + "GATK4_CALCULATECONTAMINATION", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T15:50:57.391538082" + }, + "human - pileup-table - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.contamination.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.segmentation.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "GATK4_CALCULATECONTAMINATION", + "gatk4", + "4.6.2.0" + ] + ], + "contamination": [ + [ + { + "id": "test" + }, + "test.contamination.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "segmentation": [ + [ + { + "id": "test" + }, + "test.segmentation.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gatk4": [ + [ + "GATK4_CALCULATECONTAMINATION", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T15:51:38.901543934" + }, + "human - pileup-table - matched-pair": { + "content": [ + "sample\tcontamination\terror", + { + "versions_gatk4": [ + [ + "GATK4_CALCULATECONTAMINATION", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T15:51:12.172307513" + }, + "human - pileup-table - segmentation": { + "content": [ + "sample\tcontamination\terror", + "#SAMPLE=tumour", + { + "versions_gatk4": [ + [ + "GATK4_CALCULATECONTAMINATION", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T15:51:27.280277084" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/calculatecontamination/tests/nextflow.config b/modules/nf-core/gatk4/calculatecontamination/tests/nextflow.config new file mode 100644 index 000000000..db836b7f8 --- /dev/null +++ b/modules/nf-core/gatk4/calculatecontamination/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: GATK4_CALCULATECONTAMINATION { + ext.args = { "--tumor-segmentation ${meta.id}.segmentation.table" } + } +} diff --git a/modules/nf-core/gatk4/collectreadcounts/environment.yml b/modules/nf-core/gatk4/collectreadcounts/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/collectreadcounts/environment.yml +++ b/modules/nf-core/gatk4/collectreadcounts/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/collectreadcounts/main.nf b/modules/nf-core/gatk4/collectreadcounts/main.nf index 2c545d224..4dbb80169 100644 --- a/modules/nf-core/gatk4/collectreadcounts/main.nf +++ b/modules/nf-core/gatk4/collectreadcounts/main.nf @@ -1,11 +1,11 @@ process GATK4_COLLECTREADCOUNTS { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(input), path(input_index), path(intervals) @@ -14,9 +14,9 @@ process GATK4_COLLECTREADCOUNTS { tuple val(meta4), path(dict) output: - tuple val(meta), path("*.hdf5"), optional: true, emit: hdf5 - tuple val(meta), path("*.tsv") , optional: true, emit: tsv - path "versions.yml" , emit: versions + tuple val(meta), path("*.hdf5"), emit: hdf5, optional: true + tuple val(meta), path("*.tsv"), emit: tsv, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -25,45 +25,40 @@ process GATK4_COLLECTREADCOUNTS { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--reference $fasta" : "" - def extension = args.contains("--format HDF5") ? "hdf5" : - args.contains("--format TSV") ? "tsv" : - "hdf5" + def reference = fasta ? "--reference ${fasta}" : "" + def extension = args.contains("--format HDF5") + ? "hdf5" + : args.contains("--format TSV") + ? "tsv" + : "hdf5" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK COLLECTREADCOUNTS] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK COLLECTREADCOUNTS] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ CollectReadCounts \\ - --input $input \\ - --intervals $intervals \\ - --output ${prefix}.$extension \\ - $reference \\ + --input ${input} \\ + --intervals ${intervals} \\ + --output ${prefix}.${extension} \\ + ${reference} \\ --tmp-dir . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--format HDF5") ? "hdf5" : - args.contains("--format TSV") ? "tsv" : - "hdf5" + def extension = args.contains("--format HDF5") + ? "hdf5" + : args.contains("--format TSV") + ? "tsv" + : "hdf5" """ touch ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/collectreadcounts/meta.yml b/modules/nf-core/gatk4/collectreadcounts/meta.yml index cf8c7731d..abd202997 100644 --- a/modules/nf-core/gatk4/collectreadcounts/meta.yml +++ b/modules/nf-core/gatk4/collectreadcounts/meta.yml @@ -29,14 +29,17 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - input_index: type: file description: BAM/CRAM/SAM index file pattern: "*.{bai,crai,sai}" + ontologies: [] - intervals: type: file description: A file containing the specified intervals pattern: "*.{bed,intervals}" + ontologies: [] - - meta2: type: map description: | @@ -46,6 +49,7 @@ input: type: file description: Optional - Reference FASTA pattern: "*.{fasta,fa}" + ontologies: [] - - meta3: type: map description: | @@ -55,6 +59,7 @@ input: type: file description: Optional - Index of the reference FASTA file pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -64,9 +69,10 @@ input: type: file description: Optional - Sequence dictionary of the reference FASTA file pattern: "*.dict" + ontologies: [] output: - - hdf5: - - meta: + hdf5: + - - meta: type: map description: | Groovy Map containing sample information @@ -75,8 +81,9 @@ output: type: file description: The read counts in hdf5 format pattern: "*.hdf5" - - tsv: - - meta: + ontologies: [] + tsv: + - - meta: type: map description: | Groovy Map containing sample information @@ -85,11 +92,29 @@ output: type: file description: The read counts in TSV format pattern: "*.tsv" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" maintainers: diff --git a/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test b/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test index 0832cf85a..963103ed6 100644 --- a/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test +++ b/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test @@ -19,26 +19,25 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), ] input[1] = [[],[]] input[2] = [[],[]] input[3] = [[],[]] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( file(process.out.hdf5[0][1]).name, process.out.tsv, - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } @@ -52,21 +51,20 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), ] input[1] = [[],[]] input[2] = [[],[]] input[3] = [[],[]] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } @@ -81,24 +79,22 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), ] input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true)] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - } diff --git a/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test.snap b/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test.snap index 28a3a6e15..d7d3357ba 100644 --- a/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/collectreadcounts/tests/main.nf.test.snap @@ -15,7 +15,11 @@ ] ], "2": [ - "versions.yml:md5,ebf23f4ab63948ba97df07035f8d2659" + [ + "GATK4_COLLECTREADCOUNTS", + "gatk4", + "4.6.2.0" + ] ], "hdf5": [ @@ -29,29 +33,42 @@ "test.tsv:md5,d9a32039b7a84f5bb74e8382e5427670" ] ], - "versions": [ - "versions.yml:md5,ebf23f4ab63948ba97df07035f8d2659" + "versions_gatk4": [ + [ + "GATK4_COLLECTREADCOUNTS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T12:58:19.610687" + "timestamp": "2026-01-21T15:57:24.675555145" }, "test-gatk4-collectreadcounts-hdf5": { "content": [ "test.hdf5", [ - ] + ], + { + "versions_gatk4": [ + [ + "GATK4_COLLECTREADCOUNTS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T13:02:48.607644" + "timestamp": "2026-01-21T15:56:53.979162756" }, "test-gatk4-collectreadcounts-tsv": { "content": [ @@ -69,7 +86,11 @@ ] ], "2": [ - "versions.yml:md5,ebf23f4ab63948ba97df07035f8d2659" + [ + "GATK4_COLLECTREADCOUNTS", + "gatk4", + "4.6.2.0" + ] ], "hdf5": [ @@ -83,15 +104,19 @@ "test.tsv:md5,8e45a6164916c303387f39f02ce45841" ] ], - "versions": [ - "versions.yml:md5,ebf23f4ab63948ba97df07035f8d2659" + "versions_gatk4": [ + [ + "GATK4_COLLECTREADCOUNTS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-08-26T12:58:07.500024" + "timestamp": "2026-01-21T15:57:08.386074318" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/createsequencedictionary/environment.yml b/modules/nf-core/gatk4/createsequencedictionary/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/environment.yml +++ b/modules/nf-core/gatk4/createsequencedictionary/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/createsequencedictionary/main.nf b/modules/nf-core/gatk4/createsequencedictionary/main.nf index c7f1d75b3..750e9c411 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/main.nf +++ b/modules/nf-core/gatk4/createsequencedictionary/main.nf @@ -1,18 +1,18 @@ process GATK4_CREATESEQUENCEDICTIONARY { - tag "$fasta" - label 'process_medium' + tag "${fasta}" + label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(fasta) output: - tuple val(meta), path('*.dict') , emit: dict - path "versions.yml" , emit: versions + tuple val(meta), path('*.dict'), emit: dict + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -22,31 +22,22 @@ process GATK4_CREATESEQUENCEDICTIONARY { def avail_mem = 6144 if (!task.memory) { - log.info '[GATK CreateSequenceDictionary] Available memory not known - defaulting to 6GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK CreateSequenceDictionary] Available memory not known - defaulting to 6GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ CreateSequenceDictionary \\ - --REFERENCE $fasta \\ - --URI $fasta \\ + --REFERENCE ${fasta} \\ + --URI ${fasta} \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: """ touch ${fasta.baseName}.dict - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/createsequencedictionary/meta.yml b/modules/nf-core/gatk4/createsequencedictionary/meta.yml index 7b5156bb3..5fdfcc20a 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/meta.yml +++ b/modules/nf-core/gatk4/createsequencedictionary/meta.yml @@ -26,21 +26,40 @@ input: type: file description: Input fasta file pattern: "*.{fasta,fa}" + ontologies: [] output: - - dict: - - meta: + dict: + - - meta: type: file description: gatk dictionary file pattern: "*.{dict}" + ontologies: [] - "*.dict": type: file description: gatk dictionary file pattern: "*.{dict}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test index a8a9c6d2e..076eb0d84 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test +++ b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test @@ -16,18 +16,17 @@ nextflow_process { """ input[0] = [ [ id:'test' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] + ] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } test("sarscov2 - fasta - stub") { @@ -39,18 +38,16 @@ nextflow_process { """ input[0] = [ [ id:'test' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] + ] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap index 16735f954..357cd58ee 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap @@ -11,7 +11,11 @@ ] ], "1": [ - "versions.yml:md5,e60dd34a71fc2029d81dc67ccb5d6be6" + [ + "GATK4_CREATESEQUENCEDICTIONARY", + "gatk4", + "4.6.2.0" + ] ], "dict": [ [ @@ -21,16 +25,20 @@ "genome.dict:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e60dd34a71fc2029d81dc67ccb5d6be6" + "versions_gatk4": [ + [ + "GATK4_CREATESEQUENCEDICTIONARY", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-16T10:16:16.34453" + "timestamp": "2026-01-21T16:01:50.146061464" }, "sarscov2 - fasta": { "content": [ @@ -44,7 +52,11 @@ ] ], "1": [ - "versions.yml:md5,e60dd34a71fc2029d81dc67ccb5d6be6" + [ + "GATK4_CREATESEQUENCEDICTIONARY", + "gatk4", + "4.6.2.0" + ] ], "dict": [ [ @@ -54,15 +66,19 @@ "genome.dict:md5,7362679f176e0f52add03c08f457f646" ] ], - "versions": [ - "versions.yml:md5,e60dd34a71fc2029d81dc67ccb5d6be6" + "versions_gatk4": [ + [ + "GATK4_CREATESEQUENCEDICTIONARY", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-05-16T13:58:25.822068" + "timestamp": "2026-01-21T16:01:38.694508582" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/createsequencedictionary/tests/tags.yml b/modules/nf-core/gatk4/createsequencedictionary/tests/tags.yml deleted file mode 100644 index 035c5e4c7..000000000 --- a/modules/nf-core/gatk4/createsequencedictionary/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/createsequencedictionary: - - "modules/nf-core/gatk4/createsequencedictionary/**" diff --git a/modules/nf-core/gatk4/denoisereadcounts/environment.yml b/modules/nf-core/gatk4/denoisereadcounts/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/denoisereadcounts/environment.yml +++ b/modules/nf-core/gatk4/denoisereadcounts/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/denoisereadcounts/main.nf b/modules/nf-core/gatk4/denoisereadcounts/main.nf index 878e85c6f..c86a6f45a 100644 --- a/modules/nf-core/gatk4/denoisereadcounts/main.nf +++ b/modules/nf-core/gatk4/denoisereadcounts/main.nf @@ -1,11 +1,11 @@ process GATK4_DENOISEREADCOUNTS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(counts) @@ -13,8 +13,8 @@ process GATK4_DENOISEREADCOUNTS { output: tuple val(meta), path("*_standardizedCR.tsv"), emit: standardized - tuple val(meta), path("*_denoisedCR.tsv") , emit: denoised - path "versions.yml" , emit: versions + tuple val(meta), path("*_denoisedCR.tsv"), emit: denoised + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -25,9 +25,10 @@ process GATK4_DENOISEREADCOUNTS { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK DenoiseReadCounts] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK DenoiseReadCounts] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ @@ -38,23 +39,12 @@ process GATK4_DENOISEREADCOUNTS { --count-panel-of-normals ${pon} \\ --standardized-copy-ratios ${prefix}_standardizedCR.tsv \\ --denoised-copy-ratios ${prefix}_denoisedCR.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: - def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}_standardizedCR.tsv touch ${prefix}_denoisedCR.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/denoisereadcounts/meta.yml b/modules/nf-core/gatk4/denoisereadcounts/meta.yml index 367321ba2..cac8142e0 100644 --- a/modules/nf-core/gatk4/denoisereadcounts/meta.yml +++ b/modules/nf-core/gatk4/denoisereadcounts/meta.yml @@ -26,6 +26,8 @@ input: type: file description: Read counts in hdf5 or tsv format. pattern: "*.{hdf5,tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV - - meta2: type: map description: | @@ -35,9 +37,10 @@ input: type: file description: Panel of normals file hdf5 or tsv format. pattern: "*.{hdf5}" + ontologies: [] output: - - standardized: - - meta: + standardized: + - - meta: type: map description: | Groovy Map containing sample information @@ -46,8 +49,10 @@ output: type: file description: Standardized copy ratios file. pattern: "*.{tsv}" - - denoised: - - meta: + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + denoised: + - - meta: type: map description: | Groovy Map containing sample information @@ -56,11 +61,29 @@ output: type: file description: Denoised copy ratios file pattern: "*.{tsv}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test b/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test index e5fef2a2a..9eba43aeb 100644 --- a/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test +++ b/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test @@ -19,9 +19,9 @@ nextflow_process { script "../../preprocessintervals/main.nf" process { """ - input[0] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)]) - input[1] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)]) - input[2] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true)]) + input[0] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)]) + input[1] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)]) + input[2] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true)]) input[3] = [[],[]] input[4] = [[],[]] """ @@ -32,13 +32,13 @@ nextflow_process { process { """ intervals = GATK4_PREPROCESSINTERVALS.out.interval_list.map {meta, list -> list} - input[0] = Channel.of( + input[0] = channel.of( [[ id:'test', single_end:false ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true)], ) .combine( intervals) - input[1] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)]) - input[2] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)]) - input[3] = Channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true)]) + input[1] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)]) + input[2] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)]) + input[3] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true)]) """ } } @@ -62,15 +62,14 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( process.out.standardized, process.out.denoised, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } - } } diff --git a/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test.snap b/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test.snap index f35eb283d..abdeb59b8 100644 --- a/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/denoisereadcounts/tests/main.nf.test.snap @@ -19,14 +19,20 @@ "test_denoisedCR.tsv:md5,f9e56b8e12b4dadc91a6d977fa79c6a8" ] ], - [ - "versions.yml:md5,140780e1af7318cc9259b8970bc70c81" - ] + { + "versions_gatk4": [ + [ + "GATK4_DENOISEREADCOUNTS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-16T12:34:12.568925" + "timestamp": "2026-02-05T15:25:28.341041619" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/denoisereadcounts/tests/tags.yml b/modules/nf-core/gatk4/denoisereadcounts/tests/tags.yml deleted file mode 100644 index 5f105a82a..000000000 --- a/modules/nf-core/gatk4/denoisereadcounts/tests/tags.yml +++ /dev/null @@ -1,6 +0,0 @@ -gatk4/denoisereadcounts: - - "modules/nf-core/gatk4/denoisereadcounts/**" - - "modules/nf-core/gatk4/createreadcountpanelofnormals/**" - - "modules/nf-core/gatk4/collectreadcounts/**" - - "modules/nf-core/gatk4/preprocessintervals/**" - - "modules/nf-core/gatk4/denoisereadcounts/**" diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/README.md b/modules/nf-core/gatk4/determinegermlinecontigploidy/README.md deleted file mode 100644 index c6a454565..000000000 --- a/modules/nf-core/gatk4/determinegermlinecontigploidy/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Conda is not supported at the moment - -The [bioconda](https://bioconda.github.io/recipes/gatk4/README.html) recipe is not fully working as expected, cf [github issue](https://github.com/broadinstitute/gatk/issues/7811) - -Hence, we are using the docker container provided by the authors of the tool: - -- [broadinstitute/gatk](https://hub.docker.com/r/broadinstitute/gatk) - -This image is mirrored on the [nf-core quay.io](https://quay.io/repository/nf-core/gatk) for convenience. diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/environment.yml b/modules/nf-core/gatk4/determinegermlinecontigploidy/environment.yml new file mode 100644 index 000000000..67e0eb860 --- /dev/null +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/main.nf b/modules/nf-core/gatk4/determinegermlinecontigploidy/main.nf index fc98e80e4..da9480b60 100644 --- a/modules/nf-core/gatk4/determinegermlinecontigploidy/main.nf +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/main.nf @@ -1,45 +1,44 @@ - process GATK4_DETERMINEGERMLINECONTIGPLOIDY { - tag "$meta.id" + tag "${meta.id}" label 'process_single' - //Conda is not supported at the moment: https://github.com/broadinstitute/gatk/issues/7811 - container "nf-core/gatk:4.5.0.0" //Biocontainers is missing a package + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(counts), path(bed), path(exclude_beds) tuple val(meta2), path(ploidy_model) - path(contig_ploidy_table) + path contig_ploidy_table output: tuple val(meta), path("${prefix}-calls"), emit: calls tuple val(meta), path("${prefix}-model"), emit: model, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_DETERMINEGERMLINECONTIGPLOIDY module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - def intervals = bed ? "--intervals ${bed}" : "" - def exclude = exclude_beds ? exclude_beds.collect(){"--exclude-intervals $it"}.join(" ") : "" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def intervals = bed ? "--intervals ${bed}" : "" + def exclude = exclude_beds ? exclude_beds.collect { bed_ -> "--exclude-intervals ${bed_}" }.join(" ") : "" def contig_ploidy = contig_ploidy_table ? "--contig-ploidy-priors ${contig_ploidy_table}" : "" - def model = ploidy_model ? "--model ${ploidy_model}" : "" - def input_list = counts.collect(){"--input $it"}.join(" ") + def model = ploidy_model ? "--model ${ploidy_model}" : "" + def input_list = counts.collect { count -> "--input ${count}" }.join(" ") def avail_mem = 3072 if (!task.memory) { - log.info '[GATK DetermineGermlineContigPloidy] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK DetermineGermlineContigPloidy] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ export THEANO_FLAGS="base_compiledir=\$PWD" + export PYTENSOR_FLAGS="base_compiledir=\$PWD" export OMP_NUM_THREADS=${task.cpus} export MKL_NUM_THREADS=${task.cpus} @@ -54,26 +53,12 @@ process GATK4_DETERMINEGERMLINECONTIGPLOIDY { ${model} \\ --tmp-dir . \\ ${args} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_DETERMINEGERMLINECONTIGPLOIDY module does not support Conda. Please use Docker / Singularity / Podman instead." - } prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}-calls touch ${prefix}-model - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/meta.yml b/modules/nf-core/gatk4/determinegermlinecontigploidy/meta.yml index 828628b28..0e0c1610d 100644 --- a/modules/nf-core/gatk4/determinegermlinecontigploidy/meta.yml +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/meta.yml @@ -27,16 +27,20 @@ input: type: file description: One or more count TSV files created with gatk/collectreadcounts pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV - bed: type: file description: Optional - A bed file containing the intervals to include in the process pattern: "*.bed" + ontologies: [] - exclude_beds: type: file description: Optional - One or more bed files containing intervals to exclude from the process pattern: "*.bed" + ontologies: [] - - meta2: type: map description: | @@ -48,13 +52,15 @@ input: Optional - A folder containing the ploidy model. When a model is supplied to tool will run in CASE mode. pattern: '*-model/' - - - contig_ploidy_table: - type: file - description: The contig ploidy priors table - pattern: "*.tsv" + - contig_ploidy_table: + type: file + description: The contig ploidy priors table + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV output: - - calls: - - meta: + calls: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,8 +69,8 @@ output: type: directory description: A folder containing the calls from the input files pattern: "*-calls/" - - model: - - meta: + model: + - - meta: type: map description: | Groovy Map containing sample information @@ -75,11 +81,27 @@ output: A folder containing the model from the input files. This will only be created in COHORT mode (when no model is supplied to the process). pattern: "*-model/" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" maintainers: diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test new file mode 100644 index 000000000..d89b1f22c --- /dev/null +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test @@ -0,0 +1,102 @@ +nextflow_process { + + name "Test Process GATK4_DETERMINEGERMLINECONTIGPLOIDY" + script "../main.nf" + config "./nextflow.config" + process "GATK4_DETERMINEGERMLINECONTIGPLOIDY" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/collectreadcounts" + tag "gatk4/determinegermlinecontigploidy" + + setup { + run("GATK4_COLLECTREADCOUNTS") { + script "../../collectreadcounts/main.nf" + process { + """ + bed = Channel.of(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.multi_intervals.bed', checkIfExists: true)) + + ch_input = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai", checkIfExists: true) + ], + [ + [ id:'test2', single_end:false ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam.bai", checkIfExists: true) + ], + ).combine(bed) + + ch_fasta = Channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]).collect() + ch_fai = Channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta.fai", checkIfExists: true)]).collect() + ch_dict = Channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.dict", checkIfExists: true)]).collect() + + input = [ch_input, ch_fasta, ch_fai, ch_dict] + """ + } + } + } + + test("homo sapiens - bam") { + + when { + process { + """ + contig_ploidy_table = file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/contig_ploidy_priors_table.tsv", checkIfExists: true) + bed = Channel.of(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.multi_intervals.bed', checkIfExists: true)) + + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'] , tsv ] }) + .groupTuple() + .combine(bed) + .map({ meta, counts, bed -> [ meta, counts, bed, [] ]}) + input[1] = [[],[]] + input[2] = contig_ploidy_table + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.calls[0][1]).list().sort().collect { path -> file(path).name }, + file(process.out.model[0][1]).list().sort().collect { path -> file(path).name }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("homo sapiens - bam - stub") { + + options "-stub" + + when { + process { + """ + contig_ploidy_table = file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/contig_ploidy_priors_table.tsv", checkIfExists: true) + bed = Channel.of(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.multi_intervals.bed', checkIfExists: true)) + + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'] , tsv ] }) + .groupTuple() + .combine(bed) + .map({ meta, counts, bed -> [ meta, counts, bed, [] ]}) + input[1] = [[],[]] + input[2] = contig_ploidy_table + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test.snap b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test.snap new file mode 100644 index 000000000..8c56e743a --- /dev/null +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/main.nf.test.snap @@ -0,0 +1,91 @@ +{ + "homo sapiens - bam": { + "content": [ + [ + "SAMPLE_0", + "SAMPLE_1" + ], + [ + "contig_ploidy_prior.tsv", + "gcnvkernel_version.json", + "interval_list.tsv", + "mu_mean_bias_j_interval__.tsv", + "mu_psi_j_log__.tsv", + "ploidy_config.json", + "std_mean_bias_j_interval__.tsv", + "std_psi_j_log__.tsv" + ], + { + "versions_gatk4": [ + [ + "GATK4_DETERMINEGERMLINECONTIGPLOIDY", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T15:27:49.742708767" + }, + "homo sapiens - bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test-calls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test-model:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "GATK4_DETERMINEGERMLINECONTIGPLOIDY", + "gatk4", + "4.6.2.0" + ] + ], + "calls": [ + [ + { + "id": "test" + }, + "test-calls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "model": [ + [ + { + "id": "test" + }, + "test-model:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gatk4": [ + [ + "GATK4_DETERMINEGERMLINECONTIGPLOIDY", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T15:27:58.764956454" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/nextflow.config b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/nextflow.config new file mode 100644 index 000000000..2767daca2 --- /dev/null +++ b/modules/nf-core/gatk4/determinegermlinecontigploidy/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + withName: GATK4_COLLECTREADCOUNTS { + ext.args = "--format TSV --interval-merging-rule OVERLAPPING_ONLY" + } + withName: GATK4_DETERMINEGERMLINECONTIGPLOIDY { + ext.args = "--interval-merging-rule OVERLAPPING_ONLY" + } +} diff --git a/modules/nf-core/gatk4/filtermutectcalls/environment.yml b/modules/nf-core/gatk4/filtermutectcalls/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/filtermutectcalls/environment.yml +++ b/modules/nf-core/gatk4/filtermutectcalls/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/filtermutectcalls/main.nf b/modules/nf-core/gatk4/filtermutectcalls/main.nf index 0532ec025..cd463b1b4 100644 --- a/modules/nf-core/gatk4/filtermutectcalls/main.nf +++ b/modules/nf-core/gatk4/filtermutectcalls/main.nf @@ -1,11 +1,11 @@ process GATK4_FILTERMUTECTCALLS { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(vcf), path(vcf_tbi), path(stats), path(orientationbias), path(segmentation), path(table), val(estimate) @@ -14,10 +14,10 @@ process GATK4_FILTERMUTECTCALLS { tuple val(meta4), path(dict) output: - tuple val(meta), path("*.vcf.gz") , emit: vcf - tuple val(meta), path("*.vcf.gz.tbi") , emit: tbi + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val(meta), path("*.vcf.gz.tbi"), emit: tbi tuple val(meta), path("*.filteringStats.tsv"), emit: stats - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -26,34 +26,30 @@ process GATK4_FILTERMUTECTCALLS { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def orientationbias_command = orientationbias ? orientationbias.collect{"--orientation-bias-artifact-priors $it"}.join(' ') : '' - def segmentation_command = segmentation ? segmentation.collect{"--tumor-segmentation $it"}.join(' ') : '' - def estimate_command = estimate ? " --contamination-estimate ${estimate} " : '' - def table_command = table ? table.collect{"--contamination-table $it"}.join(' ') : '' + def orientationbias_command = orientationbias ? orientationbias.collect { orientationbias_ -> "--orientation-bias-artifact-priors ${orientationbias_}" }.join(' ') : '' + def segmentation_command = segmentation ? segmentation.collect { segmentation_ -> "--tumor-segmentation ${segmentation_}" }.join(' ') : '' + def estimate_command = estimate ? " --contamination-estimate ${estimate} " : '' + def table_command = table ? table.collect { table_ -> "--contamination-table ${table_}" }.join(' ') : '' def avail_mem = 3072 if (!task.memory) { - log.info '[GATK FilterMutectCalls] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK FilterMutectCalls] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ FilterMutectCalls \\ - --variant $vcf \\ + --variant ${vcf} \\ --output ${prefix}.vcf.gz \\ - --reference $fasta \\ - $orientationbias_command \\ - $segmentation_command \\ - $estimate_command \\ - $table_command \\ + --reference ${fasta} \\ + ${orientationbias_command} \\ + ${segmentation_command} \\ + ${estimate_command} \\ + ${table_command} \\ --tmp-dir . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: @@ -62,10 +58,5 @@ process GATK4_FILTERMUTECTCALLS { echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi touch ${prefix}.vcf.gz.filteringStats.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/filtermutectcalls/meta.yml b/modules/nf-core/gatk4/filtermutectcalls/meta.yml index 9287277eb..eb3e9baf4 100644 --- a/modules/nf-core/gatk4/filtermutectcalls/meta.yml +++ b/modules/nf-core/gatk4/filtermutectcalls/meta.yml @@ -27,28 +27,36 @@ input: type: file description: compressed vcf file of mutect2calls pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - vcf_tbi: type: file description: Tabix index of vcf file pattern: "*vcf.gz.tbi" + ontologies: [] - stats: type: file description: Stats file that pairs with output vcf file pattern: "*vcf.gz.stats" + ontologies: [] - orientationbias: type: file description: files containing artifact priors for input vcf. Optional input. pattern: "*.artifact-prior.tar.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - segmentation: type: file description: tables containing segmentation information for input vcf. Optional input. pattern: "*.segmentation.table" + ontologies: [] - table: type: file description: table(s) containing contamination data for input vcf. Optional input, takes priority over estimate. pattern: "*.contamination.table" + ontologies: [] - estimate: type: float description: estimation of contamination value as a double. Optional input, @@ -62,6 +70,7 @@ input: type: file description: The reference fasta file pattern: "*.fasta" + ontologies: [] - - meta3: type: map description: | @@ -71,6 +80,7 @@ input: type: file description: Index of reference fasta file pattern: "*.fasta.fai" + ontologies: [] - - meta4: type: map description: | @@ -80,39 +90,67 @@ input: type: file description: GATK sequence dictionary pattern: "*.dict" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: file description: file containing filtered mutect2 calls. pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.vcf.gz": type: file description: file containing filtered mutect2 calls. pattern: "*.vcf.gz" - - tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: type: file - description: tbi file that pairs with vcf. - pattern: "*.vcf.gz.tbi" + description: file containing filtered mutect2 calls. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.vcf.gz.tbi": type: file description: tbi file that pairs with vcf. pattern: "*.vcf.gz.tbi" - - stats: - - meta: + ontologies: [] + stats: + - - meta: type: file - description: file containing statistics of the filtermutectcalls run. - pattern: "*.filteringStats.tsv" + description: file containing filtered mutect2 calls. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.filteringStats.tsv": type: file description: file containing statistics of the filtermutectcalls run. pattern: "*.filteringStats.tsv" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@GCJMackenzie" - "@maxulysse" diff --git a/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test b/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test index 83c3703fc..64007fc1a 100644 --- a/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test +++ b/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test @@ -42,10 +42,12 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions_base") }, - { assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2") }, - { assert path(process.out.tbi.get(0).get(1)).linesGzip.toString().contains("TBI")}, - { assert snapshot(file(process.out.stats.get(0).get(1)).readLines()[0]).match() } + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") }, + path(process.out.vcf[0][1]).vcf.variantsMD5, + path(process.out.tbi[0][1]).linesGzip.toString().contains("TBI"), + file(process.out.stats[0][1]).readLines()[0] + ).match() } ) } @@ -83,13 +85,14 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions_with-files") }, - { assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2") }, - { assert path(process.out.tbi.get(0).get(1)).linesGzip.toString().contains("TBI")}, - { assert snapshot(file(process.out.stats.get(0).get(1)).readLines()[0..5]).match() } + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") }, + path(process.out.vcf[0][1]).vcf.variantsMD5, + path(process.out.tbi[0][1]).linesGzip.toString().contains("TBI"), + file(process.out.stats[0][1]).readLines()[0..5] + ).match() } ) } - } test("human - vcf - use-val") { @@ -124,13 +127,14 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions_use-val") }, - { assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2") }, - { assert path(process.out.tbi.get(0).get(1)).linesGzip.toString().contains("TBI")}, - { assert snapshot(file(process.out.stats.get(0).get(1)).readLines()[0]).match() } + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") }, + path(process.out.vcf[0][1]).vcf.variantsMD5, + path(process.out.tbi[0][1]).linesGzip.toString().contains("TBI"), + file(process.out.stats[0][1]).readLines()[0] + ).match() } ) } - } test("human - vcf - stub") { @@ -170,7 +174,5 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test.snap b/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test.snap index 1c39e3b5d..dee66a039 100644 --- a/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/filtermutectcalls/tests/main.nf.test.snap @@ -1,25 +1,24 @@ { "human - vcf - use-val": { "content": [ + { + "versions_gatk4": [ + [ + "GATK4_FILTERMUTECTCALLS", + "gatk4", + "4.6.2.0" + ] + ] + }, + "4f8cfebe28e5fd097a7bfc2e556983d3", + true, "#Ln prior of deletion of length 10=-20.72326583694641" ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T12:46:03.887912" - }, - "versions_with-files": { - "content": [ - [ - "versions.yml:md5,1e86368bd682668a6777ccf2cfd90689" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-05-15T12:45:43.679571" + "timestamp": "2026-02-05T14:24:16.387135961" }, "human - vcf - stub": { "content": [ @@ -49,7 +48,11 @@ ] ], "3": [ - "versions.yml:md5,1e86368bd682668a6777ccf2cfd90689" + [ + "GATK4_FILTERMUTECTCALLS", + "gatk4", + "4.6.2.0" + ] ], "stats": [ [ @@ -75,43 +78,34 @@ "test.filtered.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,1e86368bd682668a6777ccf2cfd90689" + "versions_gatk4": [ + [ + "GATK4_FILTERMUTECTCALLS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T12:46:32.666273" - }, - "versions_use-val": { - "content": [ - [ - "versions.yml:md5,1e86368bd682668a6777ccf2cfd90689" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-05-15T12:46:03.876073" - }, - "versions_base": { - "content": [ - [ - "versions.yml:md5,1e86368bd682668a6777ccf2cfd90689" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-05-15T12:47:39.930795" + "timestamp": "2026-02-05T12:44:42.986778135" }, "human - vcf - with-files": { "content": [ + { + "versions_gatk4": [ + [ + "GATK4_FILTERMUTECTCALLS", + "gatk4", + "4.6.2.0" + ] + ] + }, + "54e439a79e4b6956a7f2c5b0730c9918", + true, [ "#Ln prior of deletion of length 10=-20.72326583694641", "#Ln prior of deletion of length 9=-20.72326583694641", @@ -122,19 +116,30 @@ ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T12:45:43.699286" + "timestamp": "2026-02-05T14:24:03.785317232" }, "human - vcf - base": { "content": [ + { + "versions_gatk4": [ + [ + "GATK4_FILTERMUTECTCALLS", + "gatk4", + "4.6.2.0" + ] + ] + }, + "5352aa0f3ea986008a2652eba7c0fdba", + true, "#Ln prior of deletion of length 10=-20.72326583694641" ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-15T12:47:39.949405" + "timestamp": "2026-02-05T14:22:02.165177275" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/filtermutectcalls/tests/tags.yml b/modules/nf-core/gatk4/filtermutectcalls/tests/tags.yml deleted file mode 100644 index 447310318..000000000 --- a/modules/nf-core/gatk4/filtermutectcalls/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/filtermutectcalls: - - "modules/nf-core/gatk4/filtermutectcalls/**" diff --git a/modules/nf-core/gatk4/germlinecnvcaller/README.md b/modules/nf-core/gatk4/germlinecnvcaller/README.md deleted file mode 100644 index c6a454565..000000000 --- a/modules/nf-core/gatk4/germlinecnvcaller/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Conda is not supported at the moment - -The [bioconda](https://bioconda.github.io/recipes/gatk4/README.html) recipe is not fully working as expected, cf [github issue](https://github.com/broadinstitute/gatk/issues/7811) - -Hence, we are using the docker container provided by the authors of the tool: - -- [broadinstitute/gatk](https://hub.docker.com/r/broadinstitute/gatk) - -This image is mirrored on the [nf-core quay.io](https://quay.io/repository/nf-core/gatk) for convenience. diff --git a/modules/nf-core/gatk4/germlinecnvcaller/environment.yml b/modules/nf-core/gatk4/germlinecnvcaller/environment.yml new file mode 100644 index 000000000..67e0eb860 --- /dev/null +++ b/modules/nf-core/gatk4/germlinecnvcaller/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/germlinecnvcaller/main.nf b/modules/nf-core/gatk4/germlinecnvcaller/main.nf index 90aa7e471..c7b68ab55 100644 --- a/modules/nf-core/gatk4/germlinecnvcaller/main.nf +++ b/modules/nf-core/gatk4/germlinecnvcaller/main.nf @@ -1,9 +1,11 @@ process GATK4_GERMLINECNVCALLER { - tag "$meta.id" + tag "${meta.id}" label 'process_single' - //Conda is not supported at the moment: https://github.com/broadinstitute/gatk/issues/7811 - container "nf-core/gatk:4.5.0.0" //Biocontainers is missing a package + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(tsv), path(intervals), path(ploidy), path(model) @@ -11,66 +13,50 @@ process GATK4_GERMLINECNVCALLER { output: tuple val(meta), path("*-cnv-model/*-calls"), emit: cohortcalls, optional: true tuple val(meta), path("*-cnv-model/*-model"), emit: cohortmodel, optional: true - tuple val(meta), path("*-cnv-calls/*-calls"), emit: casecalls , optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*-cnv-calls/*-calls"), emit: casecalls, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_GERMLINECNVCALLER module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def intervals_command = intervals ? "--intervals ${intervals}" : "" - def ploidy_command = ploidy ? "--contig-ploidy-calls ${ploidy}" : "" - def model_command = model ? "--model ${model}" : "" - def input_list = tsv.collect{"--input $it"}.join(' ') - def output_command = model ? "--output ${prefix}-cnv-calls" : "--output ${prefix}-cnv-model" + def intervals_command = intervals ? "--intervals ${intervals}" : "" + def ploidy_command = ploidy ? "--contig-ploidy-calls ${ploidy}" : "" + def model_command = model ? "--model ${model}" : "" + def input_list = tsv.collect { tsv_ -> "--input ${tsv_}" }.join(' ') + def output_command = model ? "--output ${prefix}-cnv-calls" : "--output ${prefix}-cnv-model" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK GermlineCNVCaller] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK GermlineCNVCaller] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ export THEANO_FLAGS="base_compiledir=\$PWD" + export PYTENSOR_FLAGS="base_compiledir=\$PWD" export OMP_NUM_THREADS=${task.cpus} export MKL_NUM_THREADS=${task.cpus} gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ GermlineCNVCaller \\ - $input_list \\ - $ploidy_command \\ - $output_command \\ - --output-prefix $prefix \\ - $args \\ - $intervals_command \\ - $model_command - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${input_list} \\ + ${ploidy_command} \\ + ${output_command} \\ + --output-prefix ${prefix} \\ + ${args} \\ + ${intervals_command} \\ + ${model_command} """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_GERMLINECNVCALLER module does not support Conda. Please use Docker / Singularity / Podman instead." - } def prefix = task.ext.prefix ?: "${meta.id}" """ mkdir -p ${prefix}-cnv-calls/${prefix}-calls mkdir -p ${prefix}-cnv-model/${prefix}-model mkdir -p ${prefix}-cnv-model/${prefix}-calls - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/germlinecnvcaller/meta.yml b/modules/nf-core/gatk4/germlinecnvcaller/meta.yml index a185d9d10..f820c629a 100644 --- a/modules/nf-core/gatk4/germlinecnvcaller/meta.yml +++ b/modules/nf-core/gatk4/germlinecnvcaller/meta.yml @@ -26,11 +26,14 @@ input: type: file description: One or more count TSV files created with gatk/collectreadcounts pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV - intervals: type: file description: Optional - A bed file containing the intervals to include in the process pattern: "*.bed" + ontologies: [] - ploidy: type: directory description: Directory containing ploidy calls produced by determinegermlinecontigploidy @@ -42,8 +45,8 @@ input: cohort mode pattern: "*-cnv-model/*-model" output: - - cohortcalls: - - meta: + cohortcalls: + - - meta: type: map description: | Groovy Map containing sample information @@ -53,8 +56,8 @@ output: description: Tar gzipped directory containing calls produced by germlinecnvcaller case mode pattern: "*-cnv-model/*-calls" - - cohortmodel: - - meta: + cohortmodel: + - - meta: type: map description: | Groovy Map containing sample information @@ -64,8 +67,8 @@ output: description: Optional - Tar gzipped directory containing the model produced by germlinecnvcaller cohort mode pattern: "*-cnv-model/*-model" - - casecalls: - - meta: + casecalls: + - - meta: type: map description: | Groovy Map containing sample information @@ -75,11 +78,27 @@ output: description: Tar gzipped directory containing calls produced by germlinecnvcaller case mode pattern: "*-cnv-calls/*-calls" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ryanjameskennedy" - "@ViktorHy" diff --git a/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test b/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test new file mode 100644 index 000000000..640a17d49 --- /dev/null +++ b/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test @@ -0,0 +1,125 @@ +nextflow_process { + + name "Test Process GATK4_GERMLINECNVCALLER" + script "../main.nf" + config "./nextflow.config" + process "GATK4_GERMLINECNVCALLER" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/collectreadcounts" + tag "gatk4/determinegermlinecontigploidy" + tag "gatk4/bedtointervallist" + tag "gatk4/germlinecnvcaller" + + setup { + run("GATK4_COLLECTREADCOUNTS") { + script "../../collectreadcounts/main.nf" + process { + """ + input[0] = channel.of( + [ + [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true) + ], + [ + [ id:'test2', single_end:false ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true) + ]) + input[1] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]) + input[2] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta.fai", checkIfExists:true)]) + input[3] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.dict", checkIfExists: true)]) + + """ + } + } + + run("GATK4_DETERMINEGERMLINECONTIGPLOIDY") { + script "../../determinegermlinecontigploidy/main.nf" + process { + """ + bed = channel.value(file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true)) + contig_ploidy_table = file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/contig_ploidy_priors_table.tsv", checkIfExists:true) + + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'], tsv ] }) + .groupTuple() + .combine(bed) + .map({ meta, counts, bed -> [ meta, counts, bed, [] ]}) + input[1] = [[],[]] + input[2] = contig_ploidy_table + """ + } + } + + run("GATK4_BEDTOINTERVALLIST") { + script "../../bedtointervallist/main.nf" + process { + """ + input[0] = channel.of([[ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true)]) + input[1] = channel.value([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.dict", checkIfExists: true)]) + """ + } + } + } + + test("homo sapiens - bam") { + when { + process { + """ + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'], tsv ] }) + .groupTuple() + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY.out.calls) + .combine(GATK4_BEDTOINTERVALLIST.out.interval_list) + .map{ meta, counts, meta2, calls, meta3, bed -> [ meta, counts, bed, calls, [] ]} + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.cohortcalls[0][1]).list().sort().collect { path -> file(path).name }, + file(process.out.cohortmodel[0][1]).list().sort().collect { path -> file(path).name }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("homo sapiens - bam - stub") { + + options "-stub" + + when { + process { + """ + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'], tsv ] }) + .groupTuple() + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY.out.calls) + .combine(GATK4_BEDTOINTERVALLIST.out.interval_list) + .map{ meta, counts, meta2, calls, meta3, bed -> [ meta, counts, bed, calls, [] ]} + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.cohortcalls[0][1]).list().sort().collect { path -> file(path).name }, + file(process.out.cohortmodel[0][1]).list().sort().collect { path -> file(path).name }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test.snap b/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test.snap new file mode 100644 index 000000000..aa736b8ed --- /dev/null +++ b/modules/nf-core/gatk4/germlinecnvcaller/tests/main.nf.test.snap @@ -0,0 +1,67 @@ +{ + "homo sapiens - bam": { + "content": [ + [ + "SAMPLE_0", + "SAMPLE_1", + "calling_config.json", + "denoising_config.json", + "gcnvkernel_version.json", + "interval_list.tsv" + ], + [ + "calling_config.json", + "denoising_config.json", + "gcnvkernel_version.json", + "interval_list.tsv", + "log_q_tau_tk.tsv", + "mu_W_tu.tsv", + "mu_ard_u_interval__.tsv", + "mu_log_mean_bias_t.tsv", + "mu_psi_t_log__.tsv", + "std_W_tu.tsv", + "std_ard_u_interval__.tsv", + "std_log_mean_bias_t.tsv", + "std_psi_t_log__.tsv" + ], + { + "versions_gatk4": [ + [ + "GATK4_GERMLINECNVCALLER", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T15:54:16.716891653" + }, + "homo sapiens - bam - stub": { + "content": [ + [ + + ], + [ + + ], + { + "versions_gatk4": [ + [ + "GATK4_GERMLINECNVCALLER", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T15:54:30.034729289" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/germlinecnvcaller/tests/nextflow.config b/modules/nf-core/gatk4/germlinecnvcaller/tests/nextflow.config new file mode 100644 index 000000000..d1b64bf4f --- /dev/null +++ b/modules/nf-core/gatk4/germlinecnvcaller/tests/nextflow.config @@ -0,0 +1,11 @@ +process { + withName: 'GATK4_COLLECTREADCOUNTS*' { + ext.args = "--format TSV --interval-merging-rule OVERLAPPING_ONLY" + } + withName: 'GATK4_DETERMINEGERMLINECONTIGPLOIDY' { + ext.args = "--interval-merging-rule OVERLAPPING_ONLY" + } + withName: 'GATK4_GERMLINECNVCALLER' { + ext.args = "--interval-merging-rule OVERLAPPING_ONLY --run-mode COHORT" + } +} diff --git a/modules/nf-core/gatk4/getpileupsummaries/environment.yml b/modules/nf-core/gatk4/getpileupsummaries/environment.yml new file mode 100644 index 000000000..67e0eb860 --- /dev/null +++ b/modules/nf-core/gatk4/getpileupsummaries/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/getpileupsummaries/main.nf b/modules/nf-core/gatk4/getpileupsummaries/main.nf new file mode 100644 index 000000000..c7f6d3308 --- /dev/null +++ b/modules/nf-core/gatk4/getpileupsummaries/main.nf @@ -0,0 +1,55 @@ +process GATK4_GETPILEUPSUMMARIES { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" + + input: + tuple val(meta), path(input), path(index), path(intervals) + tuple val(meta2), path(fasta) + tuple val(meta3), path(fai) + tuple val(meta4), path(dict) + path variants + path variants_tbi + + output: + tuple val(meta), path('*.pileups.table'), emit: table + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def interval_command = intervals ? "--intervals ${intervals}" : "--intervals ${variants}" + def reference_command = fasta ? "--reference ${fasta}" : '' + + def avail_mem = 3072 + if (!task.memory) { + log.info('[GATK GetPileupSummaries] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() + } + """ + gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ + GetPileupSummaries \\ + --input ${input} \\ + --variant ${variants} \\ + --output ${prefix}.pileups.table \\ + ${reference_command} \\ + ${interval_command} \\ + --tmp-dir . \\ + ${args} + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.pileups.table + """ +} diff --git a/modules/nf-core/gatk4/getpileupsummaries/meta.yml b/modules/nf-core/gatk4/getpileupsummaries/meta.yml new file mode 100644 index 000000000..04113b110 --- /dev/null +++ b/modules/nf-core/gatk4/getpileupsummaries/meta.yml @@ -0,0 +1,120 @@ +name: gatk4_getpileupsummaries +description: | + Summarizes counts of reads that support reference, alternate and other alleles for given sites. Results can be used with CalculateContamination. Requires a common germline variant sites file, such as from gnomAD. +keywords: + - gatk4 + - germlinevariantsites + - getpileupsumaries + - readcountssummary +tools: + - gatk4: + description: | + Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools + with a primary focus on variant discovery and genotyping. Its powerful processing engine + and high-performance computing features make it capable of taking on projects of any size. + homepage: https://gatk.broadinstitute.org/hc/en-us + documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s + doi: 10.1158/1538-7445.AM2017-3590 + licence: ["Apache-2.0"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: BAM/CRAM file to be summarised. + pattern: "*.{bam,cram}" + ontologies: [] + - index: + type: file + description: Index file for the input BAM/CRAM file. + pattern: "*.{bam.bai,cram.crai}" + ontologies: [] + - intervals: + type: file + description: File containing specified sites to be used for the summary. If + this option is not specified, variants file is used instead automatically. + pattern: "*.interval_list" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: The reference fasta file + pattern: "*.fasta" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Index of reference fasta file + pattern: "*.fasta.fai" + ontologies: [] + - - meta4: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - dict: + type: file + description: GATK sequence dictionary + pattern: "*.dict" + ontologies: [] + - variants: + type: file + description: Population vcf of germline sequencing, containing allele fractions. + Is also used as sites file if no separate sites file is specified. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - variants_tbi: + type: file + description: Index file for the germline resource. + pattern: "*.vcf.gz.tbi" + ontologies: [] +output: + table: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*.pileups.table": + type: file + description: Table containing read counts for each site. + pattern: "*.pileups.table" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@GCJMackenzie" +maintainers: + - "@GCJMackenzie" diff --git a/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test b/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test new file mode 100644 index 000000000..27351bc49 --- /dev/null +++ b/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test @@ -0,0 +1,100 @@ +nextflow_process { + + name "Test Process GATK4_GETPILEUPSUMMARIES" + script "../main.nf" + process "GATK4_GETPILEUPSUMMARIES" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/getpileupsummaries" + + test("human - bam") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true) , + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.interval_list', checkIfExists: true) + ] + input[1] = [[],[]] // fasta + input[2] = [[],[]] // fai + input[3] = [[],[]] // dict + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } + + test("human - cram") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true) , + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.interval_list', checkIfExists: true) + ] + input[1] = [ [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ] + input[2] = [ [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) + ] + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } + + test("human - bam - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true) , + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.interval_list', checkIfExists: true) + ] + input[1] = [[],[]] // fasta + input[2] = [[],[]] // fai + input[3] = [[],[]] // dict + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test.snap b/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test.snap new file mode 100644 index 000000000..8c5c61ec5 --- /dev/null +++ b/modules/nf-core/gatk4/getpileupsummaries/tests/main.nf.test.snap @@ -0,0 +1,125 @@ +{ + "human - bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ], + "table": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gatk4": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T12:53:49.568746566" + }, + "human - bam": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,2d7ce4a54df6b9249e12d60737a67dac" + ] + ], + "1": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ], + "table": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,2d7ce4a54df6b9249e12d60737a67dac" + ] + ], + "versions_gatk4": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T12:53:07.424914004" + }, + "human - cram": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,2d7ce4a54df6b9249e12d60737a67dac" + ] + ], + "1": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ], + "table": [ + [ + { + "id": "test" + }, + "test.pileups.table:md5,2d7ce4a54df6b9249e12d60737a67dac" + ] + ], + "versions_gatk4": [ + [ + "GATK4_GETPILEUPSUMMARIES", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T12:53:33.800648892" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/intervallisttools/environment.yml b/modules/nf-core/gatk4/intervallisttools/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/intervallisttools/environment.yml +++ b/modules/nf-core/gatk4/intervallisttools/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/intervallisttools/main.nf b/modules/nf-core/gatk4/intervallisttools/main.nf index 400fa0380..257399cdf 100644 --- a/modules/nf-core/gatk4/intervallisttools/main.nf +++ b/modules/nf-core/gatk4/intervallisttools/main.nf @@ -1,18 +1,18 @@ process GATK4_INTERVALLISTTOOLS { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(intervals) output: tuple val(meta), path("*_split/*/*.interval_list"), emit: interval_list - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -23,20 +23,20 @@ process GATK4_INTERVALLISTTOOLS { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK IntervalListTools] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK IntervalListTools] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ - mkdir ${prefix}_split gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ IntervalListTools \\ - --INPUT $intervals \\ + --INPUT ${intervals} \\ --OUTPUT ${prefix}_split \\ --TMP_DIR . \\ - $args + ${args} python3 < versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: @@ -65,10 +60,5 @@ process GATK4_INTERVALLISTTOOLS { touch ${prefix}_split/temp_0002_of_6/2scattered.interval_list touch ${prefix}_split/temp_0003_of_6/3scattered.interval_list touch ${prefix}_split/temp_0004_of_6/4scattered.interval_list - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/intervallisttools/meta.yml b/modules/nf-core/gatk4/intervallisttools/meta.yml index 8ee15a297..7ed79afe0 100644 --- a/modules/nf-core/gatk4/intervallisttools/meta.yml +++ b/modules/nf-core/gatk4/intervallisttools/meta.yml @@ -26,9 +26,10 @@ input: - intervals: type: file description: Interval file + ontologies: [] output: - - interval_list: - - meta: + interval_list: + - - meta: type: map description: | Groovy Map containing sample information @@ -37,15 +38,28 @@ output: type: file description: Interval list files pattern: "*.interval_list" - - _list: - type: file - description: Interval list files - pattern: "*.interval_list" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@praveenraj2018" maintainers: diff --git a/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test b/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test index 2891bf9e4..19089f485 100644 --- a/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test +++ b/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test @@ -40,12 +40,11 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() }, ) } - } test("test_gatk4_intervallisttools -stub") { @@ -61,12 +60,10 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() }, ) } - } - } diff --git a/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test.snap b/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test.snap index 7718ed003..100aec5fc 100644 --- a/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/intervallisttools/tests/main.nf.test.snap @@ -16,7 +16,11 @@ ] ], "1": [ - "versions.yml:md5,ff682cc9ad70d65a80280df57b316b03" + [ + "GATK4_INTERVALLISTTOOLS", + "gatk4", + "4.6.2.0" + ] ], "interval_list": [ [ @@ -31,16 +35,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,ff682cc9ad70d65a80280df57b316b03" + "versions_gatk4": [ + [ + "GATK4_INTERVALLISTTOOLS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-22T21:26:22.252885" + "timestamp": "2026-02-05T16:30:27.100653045" }, "test_gatk4_intervallisttools -stub": { "content": [ @@ -59,7 +67,11 @@ ] ], "1": [ - "versions.yml:md5,ff682cc9ad70d65a80280df57b316b03" + [ + "GATK4_INTERVALLISTTOOLS", + "gatk4", + "4.6.2.0" + ] ], "interval_list": [ [ @@ -74,15 +86,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,ff682cc9ad70d65a80280df57b316b03" + "versions_gatk4": [ + [ + "GATK4_INTERVALLISTTOOLS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-22T22:15:11.772344" + "timestamp": "2026-02-05T16:30:35.391255689" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/intervallisttools/tests/tags.yml b/modules/nf-core/gatk4/intervallisttools/tests/tags.yml deleted file mode 100644 index bf85ff5fa..000000000 --- a/modules/nf-core/gatk4/intervallisttools/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/intervallisttools: - - "modules/nf-core/gatk4/intervallisttools/**" diff --git a/modules/nf-core/gatk4/mergebamalignment/environment.yml b/modules/nf-core/gatk4/mergebamalignment/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/mergebamalignment/environment.yml +++ b/modules/nf-core/gatk4/mergebamalignment/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/mergebamalignment/main.nf b/modules/nf-core/gatk4/mergebamalignment/main.nf index 0085026c8..912f585a6 100644 --- a/modules/nf-core/gatk4/mergebamalignment/main.nf +++ b/modules/nf-core/gatk4/mergebamalignment/main.nf @@ -1,11 +1,11 @@ process GATK4_MERGEBAMALIGNMENT { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(aligned), path(unmapped) @@ -14,7 +14,7 @@ process GATK4_MERGEBAMALIGNMENT { output: tuple val(meta), path('*.bam'), emit: bam - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -25,34 +25,25 @@ process GATK4_MERGEBAMALIGNMENT { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK MergeBamAlignment] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK MergeBamAlignment] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ MergeBamAlignment \\ - --UNMAPPED_BAM $unmapped \\ - --ALIGNED_BAM $aligned \\ + --UNMAPPED_BAM ${unmapped} \\ + --ALIGNED_BAM ${aligned} \\ --OUTPUT ${prefix}.bam \\ - --REFERENCE_SEQUENCE $fasta \\ + --REFERENCE_SEQUENCE ${fasta} \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.bam - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/mergebamalignment/meta.yml b/modules/nf-core/gatk4/mergebamalignment/meta.yml index 7bde93459..0d9bda912 100644 --- a/modules/nf-core/gatk4/mergebamalignment/meta.yml +++ b/modules/nf-core/gatk4/mergebamalignment/meta.yml @@ -27,10 +27,12 @@ input: type: file description: The aligned bam file pattern: "*.{bam}" + ontologies: [] - unmapped: type: file description: The unmapped bam file pattern: "*.{bam}" + ontologies: [] - - meta2: type: map description: | @@ -39,6 +41,7 @@ input: - fasta: type: file description: The reference fasta file + ontologies: [] - - meta3: type: map description: | @@ -47,21 +50,40 @@ input: - dict: type: file description: GATK sequence dictionary + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: file description: The merged bam file pattern: "*.bam" + ontologies: [] - "*.bam": type: file description: The merged bam file pattern: "*.bam" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test index 96e93bb19..f12d8dc1f 100644 --- a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test +++ b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test @@ -16,28 +16,26 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } @@ -48,26 +46,24 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - } diff --git a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap index 719a7bb33..15212afd4 100644 --- a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap @@ -11,7 +11,11 @@ ] ], "1": [ - "versions.yml:md5,a72cfce8c9d171260cbb82b492be4372" + [ + "GATK4_MERGEBAMALIGNMENT", + "gatk4", + "4.6.2.0" + ] ], "bam": [ [ @@ -21,28 +25,38 @@ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,a72cfce8c9d171260cbb82b492be4372" + "versions_gatk4": [ + [ + "GATK4_MERGEBAMALIGNMENT", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T12:02:15.41024" + "timestamp": "2026-02-05T16:39:42.649628142" }, "test-gatk4-mergebamalignment": { "content": [ "30c325e1e032eb1782a280d34c0fb1c7", - [ - "versions.yml:md5,a72cfce8c9d171260cbb82b492be4372" - ] + { + "versions_gatk4": [ + [ + "GATK4_MERGEBAMALIGNMENT", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T12:02:08.379035" + "timestamp": "2026-02-05T16:39:36.797699941" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/mergevcfs/environment.yml b/modules/nf-core/gatk4/mergevcfs/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/mergevcfs/environment.yml +++ b/modules/nf-core/gatk4/mergevcfs/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/mergevcfs/main.nf b/modules/nf-core/gatk4/mergevcfs/main.nf index 9e8d43915..93112900a 100644 --- a/modules/nf-core/gatk4/mergevcfs/main.nf +++ b/modules/nf-core/gatk4/mergevcfs/main.nf @@ -1,11 +1,11 @@ process GATK4_MERGEVCFS { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(vcf) @@ -13,8 +13,8 @@ process GATK4_MERGEVCFS { output: tuple val(meta), path('*.vcf.gz'), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -22,39 +22,30 @@ process GATK4_MERGEVCFS { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def input_list = vcf.collect{ "--INPUT $it"}.join(' ') - def reference_command = dict ? "--SEQUENCE_DICTIONARY $dict" : "" + def input_list = vcf.collect { vcf_ -> "--INPUT ${vcf_}" }.join(' ') + def reference_command = dict ? "--SEQUENCE_DICTIONARY ${dict}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK MergeVcfs] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK MergeVcfs] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ MergeVcfs \\ - $input_list \\ + ${input_list} \\ --OUTPUT ${prefix}.vcf.gz \\ - $reference_command \\ + ${reference_command} \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf.gz + echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/mergevcfs/meta.yml b/modules/nf-core/gatk4/mergevcfs/meta.yml index b4f61d780..146eaf893 100644 --- a/modules/nf-core/gatk4/mergevcfs/meta.yml +++ b/modules/nf-core/gatk4/mergevcfs/meta.yml @@ -34,30 +34,54 @@ input: type: file description: Optional Sequence Dictionary as input pattern: "*.dict" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: file description: merged vcf file pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.vcf.gz": type: file description: merged vcf file pattern: "*.vcf.gz" - - tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: type: file - description: index files for the merged vcf files - pattern: "*.tbi" + description: merged vcf file + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.tbi": type: file description: index files for the merged vcf files pattern: "*.tbi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" maintainers: diff --git a/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test b/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test index 77ace10a2..fd9972b0a 100644 --- a/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test +++ b/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test @@ -20,17 +20,15 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - file(process.out.vcf.get(0).get(1)).name, - file(process.out.tbi.get(0).get(1)).name - ).match("test_gatk4_mergevcfs") - }, + { assert snapshot( + file(process.out.vcf[0][1]).name, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, ) } - } test("test_gatk4_mergevcfs_no_dict") { @@ -44,17 +42,15 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - file(process.out.vcf.get(0).get(1)).name, - file(process.out.tbi.get(0).get(1)).name - ).match("test_gatk4_mergevcfs_no_dict") - }, + { assert snapshot( + file(process.out.vcf[0][1]).name, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, ) } - } test("test_gatk4_mergevcfs_no_dict_stub") { @@ -71,17 +67,14 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - file(process.out.vcf.get(0).get(1)).name, - file(process.out.tbi.get(0).get(1)).name - ).match("test_gatk4_mergevcfs_no_dict_stub") - }, + { assert snapshot( + file(process.out.vcf[0][1]).name, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() }, ) } - } - } diff --git a/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test.snap b/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test.snap index 62cceed57..38e555502 100644 --- a/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/mergevcfs/tests/main.nf.test.snap @@ -2,34 +2,61 @@ "test_gatk4_mergevcfs_no_dict_stub": { "content": [ "test.vcf.gz", - "test.vcf.gz.tbi" + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_MERGEVCFS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-02-14T14:57:40.784590995" + "timestamp": "2026-02-05T16:40:17.349813218" }, "test_gatk4_mergevcfs": { "content": [ "test.vcf.gz", - "test.vcf.gz.tbi" + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_MERGEVCFS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-02-14T14:56:42.178255913" + "timestamp": "2026-02-05T16:40:03.274024419" }, "test_gatk4_mergevcfs_no_dict": { "content": [ "test.vcf.gz", - "test.vcf.gz.tbi" + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_MERGEVCFS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-02-14T14:57:11.404322124" + "timestamp": "2026-02-05T16:40:10.948156303" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/mergevcfs/tests/tags.yml b/modules/nf-core/gatk4/mergevcfs/tests/tags.yml deleted file mode 100644 index d2a74ba2c..000000000 --- a/modules/nf-core/gatk4/mergevcfs/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/mergevcfs: - - "modules/nf-core/gatk4/mergevcfs/**" diff --git a/modules/nf-core/gatk4/mutect2/environment.yml b/modules/nf-core/gatk4/mutect2/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/mutect2/environment.yml +++ b/modules/nf-core/gatk4/mutect2/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/mutect2/main.nf b/modules/nf-core/gatk4/mutect2/main.nf index 79d8d2826..828206403 100644 --- a/modules/nf-core/gatk4/mutect2/main.nf +++ b/modules/nf-core/gatk4/mutect2/main.nf @@ -1,28 +1,30 @@ process GATK4_MUTECT2 { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(input), path(input_index), path(intervals) tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) + tuple val(meta3), path(fai), path(gzi) tuple val(meta4), path(dict) - path(germline_resource) - path(germline_resource_tbi) - path(panel_of_normals) - path(panel_of_normals_tbi) + path alleles + path alleles_tbi + path germline_resource + path germline_resource_tbi + path panel_of_normals + path panel_of_normals_tbi output: - tuple val(meta), path("*.vcf.gz") , emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi - tuple val(meta), path("*.stats") , emit: stats - tuple val(meta), path("*.f1r2.tar.gz"), optional:true, emit: f1r2 - path "versions.yml" , emit: versions + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val(meta), path("*.tbi"), emit: tbi + tuple val(meta), path("*.stats"), emit: stats + tuple val(meta), path("*.f1r2.tar.gz"), emit: f1r2, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -30,46 +32,39 @@ process GATK4_MUTECT2 { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def inputs = input.collect{ "--input $it"}.join(" ") - def interval_command = intervals ? "--intervals $intervals" : "" - def pon_command = panel_of_normals ? "--panel-of-normals $panel_of_normals" : "" - def gr_command = germline_resource ? "--germline-resource $germline_resource" : "" + def inputs = input.collect { vcf_ -> "--input ${vcf_}" }.join(" ") + def interval_command = intervals ? "--intervals ${intervals}" : "" + def pon_command = panel_of_normals ? "--panel-of-normals ${panel_of_normals}" : "" + def gr_command = germline_resource ? "--germline-resource ${germline_resource}" : "" + def a_command = alleles ? "--alleles ${alleles}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK Mutect2] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK Mutect2] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ Mutect2 \\ - $inputs \\ + ${inputs} \\ --output ${prefix}.vcf.gz \\ - --reference $fasta \\ - $pon_command \\ - $gr_command \\ - $interval_command \\ + --reference ${fasta} \\ + ${pon_command} \\ + ${gr_command} \\ + ${a_command} \\ + ${interval_command} \\ --tmp-dir . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf.gz + echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi touch ${prefix}.vcf.gz.stats - touch ${prefix}.f1r2.tar.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + echo "" | gzip > ${prefix}.f1r2.tar.gz """ } diff --git a/modules/nf-core/gatk4/mutect2/meta.yml b/modules/nf-core/gatk4/mutect2/meta.yml index 27fd63a24..46e21377f 100644 --- a/modules/nf-core/gatk4/mutect2/meta.yml +++ b/modules/nf-core/gatk4/mutect2/meta.yml @@ -37,6 +37,7 @@ input: type: file description: Specify region the tools is run on. pattern: ".{bed,interval_list}" + ontologies: [] - - meta2: type: map description: | @@ -45,7 +46,8 @@ input: - fasta: type: file description: The reference fasta file - pattern: "*.fasta" + pattern: "*.{fasta,fasta.gz}" + ontologies: [] - - meta3: type: map description: | @@ -54,7 +56,13 @@ input: - fai: type: file description: Index of reference fasta file - pattern: "*.fasta.fai" + pattern: "*.{fasta.fai,fasta.fai.gz}" + ontologies: [] + - gzi: + type: file + description: Index of bgzipped reference fasta file + pattern: "*.fasta.gz.gzi" + ontologies: [] - - meta4: type: map description: | @@ -64,66 +72,101 @@ input: type: file description: GATK sequence dictionary pattern: "*.dict" - - - germline_resource: - type: file - description: Population vcf of germline sequencing, containing allele fractions. - pattern: "*.vcf.gz" - - - germline_resource_tbi: - type: file - description: Index file for the germline resource. - pattern: "*.vcf.gz.tbi" - - - panel_of_normals: - type: file - description: vcf file to be used as a panel of normals. - pattern: "*.vcf.gz" - - - panel_of_normals_tbi: - type: file - description: Index for the panel of normals. - pattern: "*.vcf.gz.tbi" + ontologies: [] + - alleles: + type: file + description: vcf file to be used to force-call alleles. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - alleles_tbi: + type: file + description: Index file for alleles to be force-called. + pattern: "*.vcf.gz.tbi" + ontologies: [] + - germline_resource: + type: file + description: Population vcf of germline sequencing, containing allele fractions. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - germline_resource_tbi: + type: file + description: Index file for the germline resource. + pattern: "*.vcf.gz.tbi" + ontologies: [] + - panel_of_normals: + type: file + description: vcf file to be used as a panel of normals. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - panel_of_normals_tbi: + type: file + description: Index for the panel of normals. + pattern: "*.vcf.gz.tbi" + ontologies: [] output: - - vcf: - - meta: - type: file - description: compressed vcf file - pattern: "*.vcf.gz" + vcf: + - - meta: + type: map + description: A Groovy map containing sample information - "*.vcf.gz": type: file description: compressed vcf file pattern: "*.vcf.gz" - - tbi: - - meta: - type: file - description: Index of vcf file - pattern: "*vcf.gz.tbi" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: + type: map + description: A Groovy map containing sample information - "*.tbi": type: file description: Index of vcf file pattern: "*vcf.gz.tbi" - - stats: - - meta: - type: file - description: Stats file that pairs with output vcf file - pattern: "*vcf.gz.stats" + ontologies: [] + stats: + - - meta: + type: map + description: A Groovy map containing sample information - "*.stats": type: file description: Stats file that pairs with output vcf file pattern: "*vcf.gz.stats" - - f1r2: - - meta: - type: file - description: file containing information to be passed to LearnReadOrientationModel - (only outputted when tumor_normal_pair mode is run) - pattern: "*.f1r2.tar.gz" + ontologies: [] + f1r2: + - - meta: + type: map + description: A Groovy map containing sample information - "*.f1r2.tar.gz": type: file description: file containing information to be passed to LearnReadOrientationModel (only outputted when tumor_normal_pair mode is run) pattern: "*.f1r2.tar.gz" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@GCJMackenzie" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/mutect2/tests/f1r2.config b/modules/nf-core/gatk4/mutect2/tests/f1r2.config deleted file mode 100644 index 2d3c8a170..000000000 --- a/modules/nf-core/gatk4/mutect2/tests/f1r2.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = { "--normal-sample $meta.normal_id --f1r2-tar-gz ${meta.id}.f1r2.tar.gz" } -} diff --git a/modules/nf-core/gatk4/mutect2/tests/main.nf.test b/modules/nf-core/gatk4/mutect2/tests/main.nf.test index aea8d2269..3f7afea60 100644 --- a/modules/nf-core/gatk4/mutect2/tests/main.nf.test +++ b/modules/nf-core/gatk4/mutect2/tests/main.nf.test @@ -8,10 +8,13 @@ nextflow_process { tag "modules_nfcore" tag "gatk4" tag "gatk4/mutect2" + config "./nextflow.config" - test("tumor_normal_pair") { - config "./pair.config" + test("human - bam - tumor_normal_pair") { when { + params { + module_args = "--normal-sample normal" + } process { """ input[0] = [ @@ -36,39 +39,43 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) ] - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) - input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) - input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + input[4] = [] + input[5] = [] + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2, - process.out.versions, - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("tumor_normal_pair_f1r2") { - config "./f1r2.config" + test("human - bam - tumor_normal_pair_f1r2") { + when { + params { + module_args = "--normal-sample normal --f1r2-tar-gz test.f1r2.tar.gz" + } process { """ input[0] = [ @@ -93,36 +100,41 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) ] - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) - input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) - input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + input[4] = [] + input[5] = [] + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2.collect { file(it[1]).getName() }, - process.out.versions - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2.collect { file(it[1]).getName() }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("tumor_single"){ + + test("human - bam - tumor_only"){ when { + params { + module_args = '' + } process { """ input[0] = [ @@ -137,36 +149,41 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) ] - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) - input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) - input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + input[4] = [] + input[5] = [] + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2, - process.out.versions - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("cram_input"){ + + test("human - cram"){ when { + params { + module_args = '' + } process{ """ input[0] = [ @@ -181,37 +198,41 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) ] - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) - input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) - input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + input[4] = [] + input[5] = [] + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2, - process.out.versions - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("generate_pon") { + test("human - bam - generate_pon") { when { + params { + module_args = '' + } process { """ input[0] = [ @@ -226,7 +247,8 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], @@ -236,27 +258,30 @@ nextflow_process { input[5] = [] input[6] = [] input[7] = [] + input[8] = [] + input[9] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2, - process.out.versions - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("mitochondria"){ + test("mitochondria - bam"){ when { + params { + module_args = "--mitochondria-mode" + } process { """ input[0] = [ @@ -271,7 +296,8 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], @@ -281,28 +307,82 @@ nextflow_process { input[5] = [] input[6] = [] input[7] = [] + input[8] = [] + input[9] = [] """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats, - process.out.f1r2, - process.out.versions - ).match() - } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - test("tumor_normal_pair_f1r2_stubs"){ - options "-stub-run" + test("mitochondria - bam - gz_ref"){ when { + params { + module_args = "--mitochondria-mode" + } + process { + """ + input[0] = [ + [ id:'test'], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/mitochon_standin.recalibrated.sorted.bam', checkIfExists: true)], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/mitochon_standin.recalibrated.sorted.bam.bai', checkIfExists: true)], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true)] + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + ] + input[2] = [ + [ id:'genome' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true)], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true)] + ] + input[3] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + ] + input[4] = [] + input[5] = [] + input[6] = [] + input[7] = [] + input[8] = [] + input[9] = [] + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("human - bam - tumor_normal_pair_f1r2 - stub"){ + + options "-stub" + + when { + params { + module_args = '' + } process { """ input[0] = [ @@ -327,34 +407,136 @@ nextflow_process { ] input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] ] input[3] = [ [ id:'genome' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) ] - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) - input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) - input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + input[4] = [] + input[5] = [] + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) """ } } then { + assert process.success assertAll( - { assert process.success }, - { - assert snapshot( - process.out.vcf.collect { file(it[1]).getName() }, - process.out.tbi.collect { file(it[1]).getName() }, - process.out.stats.collect { file(it[1]).getName() }, - process.out.f1r2.collect { file(it[1]).getName() }, - process.out.versions.collect { file(it[1]).getName() } - ).match() - } + { assert snapshot(process.out).match() } ) } + } + test("human - bam - tumor_normal_pair - force_call") { + when { + params { + module_args = "" + } + process { + """ + input[0] = [ + [ + id:'test', + normal_id:'normal', + tumor_id:'tumour' + ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true) + ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true) + ], + [] + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] + ] + input[3] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) + ] + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/axiom_exome_plus.genotypes.all_populations.poly.hg38.vcf.gz', checkIfExists: true) + input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/axiom_exome_plus.genotypes.all_populations.poly.hg38.vcf.gz.tbi', checkIfExists: true) + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } } + test("human - bam - tumor_only - force_call"){ + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test'], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true)], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true)], + [] + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true)], + [] + ] + input[3] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) + ] + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/axiom_exome_plus.genotypes.all_populations.poly.hg38.vcf.gz', checkIfExists: true) + input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/axiom_exome_plus.genotypes.all_populations.poly.hg38.vcf.gz.tbi', checkIfExists: true) + input[6] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz', checkIfExists: true) + input[7] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/gnomAD.r2.1.1.vcf.gz.tbi', checkIfExists: true) + input[8] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz', checkIfExists: true) + input[9] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/germlineresources/mills_and_1000G.indels.hg38.vcf.gz.tbi', checkIfExists: true) + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.tbi.collect { file(it[1]).getName() }, + process.out.stats, + process.out.f1r2, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } } diff --git a/modules/nf-core/gatk4/mutect2/tests/main.nf.test.snap b/modules/nf-core/gatk4/mutect2/tests/main.nf.test.snap index f047af19d..73ffa9fc3 100644 --- a/modules/nf-core/gatk4/mutect2/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/mutect2/tests/main.nf.test.snap @@ -1,33 +1,40 @@ { - "tumor_normal_pair_f1r2_stubs": { + "human - bam - generate_pon": { "content": [ - [ - "test.vcf.gz" - ], + "876aa6be01c0c8fc71ad8e99ed842240", [ "test.vcf.gz.tbi" ], [ - "test.vcf.gz.stats" + [ + { + "id": "test" + }, + "test.vcf.gz.stats:md5,b569ce66bbffe9588b3d221e821023ee" + ] ], [ - "test.f1r2.tar.gz" + ], - [ - "h" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-21T10:14:45.599103891" + "timestamp": "2026-02-05T16:54:59.699672374" }, - "generate_pon": { + "human - bam - tumor_only - force_call": { "content": [ - [ - "test.vcf.gz" - ], + "9c2928d0e751262c048ac162b9223e4e", [ "test.vcf.gz.tbi" ], @@ -36,56 +43,66 @@ { "id": "test" }, - "test.vcf.gz.stats:md5,b569ce66bbffe9588b3d221e821023ee" + "test.vcf.gz.stats:md5,2398263886ecb546c8055af4fbad6040" ] ], [ ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-20T15:57:18.264453766" + "timestamp": "2026-02-05T17:02:15.006936591" }, - "mitochondria": { + "human - bam - tumor_normal_pair": { "content": [ - [ - "test.vcf.gz" - ], + "7418ed45a029394253817a5eb7149334", [ "test.vcf.gz.tbi" ], [ [ { - "id": "test" + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" }, - "test.vcf.gz.stats:md5,4f77301a125913170b8e9e7828b4ca3f" + "test.vcf.gz.stats:md5,17d2091015d04cbd4a26b7a67dc659e6" ] ], [ ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-20T16:05:47.668766905" + "timestamp": "2026-02-05T16:44:25.776848294" }, - "cram_input": { + "human - cram": { "content": [ - [ - "test.vcf.gz" - ], + "1b65f1a163b517944bf2e4b74230e035", [ "test.vcf.gz.tbi" ], @@ -100,21 +117,58 @@ [ ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-20T15:52:27.894730554" + "timestamp": "2026-02-05T16:52:48.795368727" }, - "tumor_single": { + "mitochondria - bam": { "content": [ + "ea70f79e33805a2c0b47b32a48a8d26f", [ - "test.vcf.gz" + "test.vcf.gz.tbi" + ], + [ + [ + { + "id": "test" + }, + "test.vcf.gz.stats:md5,fc6ea14ca2da346babe78161beea28c9" + ] ], + [ + + ], + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T16:55:10.945977864" + }, + "human - bam - tumor_only": { + "content": [ + "1b65f1a163b517944bf2e4b74230e035", [ "test.vcf.gz.tbi" ], @@ -129,21 +183,58 @@ [ ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-20T15:43:28.935723443" + "timestamp": "2026-02-05T16:50:29.074224171" }, - "tumor_normal_pair": { + "mitochondria - bam - gz_ref": { "content": [ + "ea70f79e33805a2c0b47b32a48a8d26f", + [ + "test.vcf.gz.tbi" + ], [ - "test.vcf.gz" + [ + { + "id": "test" + }, + "test.vcf.gz.stats:md5,fc6ea14ca2da346babe78161beea28c9" + ] ], + [ + + ], + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T16:55:22.160325012" + }, + "human - bam - tumor_normal_pair - force_call": { + "content": [ + "63c4ff01a8316f4243b6b12b06ded74e", [ "test.vcf.gz.tbi" ], @@ -154,27 +245,136 @@ "normal_id": "normal", "tumor_id": "tumour" }, - "test.vcf.gz.stats:md5,17d2091015d04cbd4a26b7a67dc659e6" + "test.vcf.gz.stats:md5,81390058f99b80db30c89020aa9fc546" ] ], [ ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-20T15:31:31.913366311" + "timestamp": "2026-02-05T16:59:14.299303803" }, - "tumor_normal_pair_f1r2": { + "human - bam - tumor_normal_pair_f1r2 - stub": { "content": [ - [ - "test.vcf.gz" - ], + { + "0": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.f1r2.tar.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ], + "f1r2": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.f1r2.tar.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "stats": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test", + "normal_id": "normal", + "tumor_id": "tumour" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T16:55:48.221310078" + }, + "human - bam - tumor_normal_pair_f1r2": { + "content": [ + "7418ed45a029394253817a5eb7149334", [ "test.vcf.gz.tbi" ], @@ -191,14 +391,20 @@ [ "test.f1r2.tar.gz" ], - [ - "versions.yml:md5,d94731c50c20569fe9896235a843f382" - ] + { + "versions_gatk4": [ + [ + "GATK4_MUTECT2", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-21T09:45:52.321385704" + "timestamp": "2026-02-05T16:47:43.194989668" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/mutect2/tests/mito.config b/modules/nf-core/gatk4/mutect2/tests/mito.config deleted file mode 100644 index de61d3e24..000000000 --- a/modules/nf-core/gatk4/mutect2/tests/mito.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = { "--mitochondria-mode" } -} diff --git a/modules/nf-core/gatk4/mutect2/tests/nextflow.config b/modules/nf-core/gatk4/mutect2/tests/nextflow.config new file mode 100644 index 000000000..08e942851 --- /dev/null +++ b/modules/nf-core/gatk4/mutect2/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: GATK4_MUTECT2 { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/gatk4/mutect2/tests/pair.config b/modules/nf-core/gatk4/mutect2/tests/pair.config deleted file mode 100644 index 2a812b825..000000000 --- a/modules/nf-core/gatk4/mutect2/tests/pair.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = { "--normal-sample $meta.normal_id" } -} diff --git a/modules/nf-core/gatk4/mutect2/tests/tags.yml b/modules/nf-core/gatk4/mutect2/tests/tags.yml deleted file mode 100644 index 461879274..000000000 --- a/modules/nf-core/gatk4/mutect2/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/mutect2: - - "modules/nf-core/gatk4/mutect2/**" diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/README.md b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/README.md deleted file mode 100644 index c6a454565..000000000 --- a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Conda is not supported at the moment - -The [bioconda](https://bioconda.github.io/recipes/gatk4/README.html) recipe is not fully working as expected, cf [github issue](https://github.com/broadinstitute/gatk/issues/7811) - -Hence, we are using the docker container provided by the authors of the tool: - -- [broadinstitute/gatk](https://hub.docker.com/r/broadinstitute/gatk) - -This image is mirrored on the [nf-core quay.io](https://quay.io/repository/nf-core/gatk) for convenience. diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/environment.yml b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/environment.yml new file mode 100644 index 000000000..67e0eb860 --- /dev/null +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/main.nf b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/main.nf index 73d4a7158..2c29c87cc 100644 --- a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/main.nf +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/main.nf @@ -1,71 +1,58 @@ process GATK4_POSTPROCESSGERMLINECNVCALLS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' - //Conda is not supported at the moment: https://github.com/broadinstitute/gatk/issues/7811 - container "nf-core/gatk:4.5.0.0" //Biocontainers is missing a package + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(calls), path(model), path(ploidy) output: - tuple val(meta), path("*_genotyped_intervals.vcf.gz") , emit: intervals, optional: true - tuple val(meta), path("*_genotyped_segments.vcf.gz") , emit: segments, optional: true - tuple val(meta), path("*_denoised.vcf.gz") , emit: denoised, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*_genotyped_intervals.vcf.gz"), emit: intervals, optional: true + tuple val(meta), path("*_genotyped_segments.vcf.gz"), emit: segments, optional: true + tuple val(meta), path("*_denoised.vcf.gz"), emit: denoised, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_POSTPROCESSGERMLINECNVCALLS module does not support Conda. Please use Docker / Singularity / Podman instead." - } def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def calls_command = calls ? calls.collect{"--calls-shard-path $it"}.join(' ') : "" - def model_command = model ? model.collect{"--model-shard-path $it"}.join(' ') : "" - def ploidy_command = ploidy ? "--contig-ploidy-calls ${ploidy}" : "" + def calls_command = calls ? calls.collect { call -> "--calls-shard-path ${call}" }.join(' ') : "" + def model_command = model ? model.collect { mode -> "--model-shard-path ${mode}" }.join(' ') : "" + def ploidy_command = ploidy ? "--contig-ploidy-calls ${ploidy}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK GermlineCNVCaller] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK PostProcessGermlineCnvCalls] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ export THEANO_FLAGS="base_compiledir=\$PWD" + export PYTENSOR_FLAGS="base_compiledir=\$PWD" gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ PostprocessGermlineCNVCalls \\ - $calls_command \\ - $model_command \\ - $ploidy_command \\ + ${calls_command} \\ + ${model_command} \\ + ${ploidy_command} \\ + ${args} \\ --output-genotyped-intervals ${prefix}_genotyped_intervals.vcf.gz \\ --output-genotyped-segments ${prefix}_genotyped_segments.vcf.gz \\ --output-denoised-copy-ratios ${prefix}_denoised.vcf.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "GATK4_POSTPROCESSGERMLINECNVCALLS module does not support Conda. Please use Docker / Singularity / Podman instead." - } def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}_genotyped_intervals.vcf.gz - touch ${prefix}_genotyped_segments.vcf.gz - touch ${prefix}_denoised.vcf.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + echo "" | gzip > ${prefix}_genotyped_intervals.vcf.gz + echo "" | gzip > ${prefix}_genotyped_segments.vcf.gz + echo "" | gzip > ${prefix}_denoised.vcf.gz """ } diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/meta.yml b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/meta.yml index d090169ab..c093baf1d 100644 --- a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/meta.yml +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/meta.yml @@ -39,8 +39,8 @@ input: When a model is supplied to tool will run in CASE mode. pattern: "*-calls/" output: - - intervals: - - meta: + intervals: + - - meta: type: map description: | Groovy Map containing sample information @@ -49,12 +49,10 @@ output: type: file description: Intervals VCF file pattern: "*.vcf.gz" - - s: - type: file - description: Intervals VCF file - pattern: "*.vcf.gz" - - segments: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + segments: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,8 +61,10 @@ output: type: file description: Segments VCF file pattern: "*.vcf.gz" - - denoised: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + denoised: + - - meta: type: map description: | Groovy Map containing sample information @@ -73,11 +73,29 @@ output: type: file description: Denoised copy ratio file pattern: "*.vcf.gz" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ryanjameskennedy" maintainers: diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test new file mode 100644 index 000000000..f18e2fb0c --- /dev/null +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test @@ -0,0 +1,150 @@ +nextflow_process { + + name "Test Process GATK4_POSTPROCESSGERMLINECNVCALLS" + script "../main.nf" + config "./nextflow.config" + process "GATK4_POSTPROCESSGERMLINECNVCALLS" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/bedtointervallist" + tag "gatk4/collectreadcounts" + tag "gatk4/determinegermlinecontigploidy" + tag "gatk4/germlinecnvcaller" + tag "gatk4/postprocessgermlinecnvcalls" + + setup { + run("GATK4_BEDTOINTERVALLIST") { + script "../../bedtointervallist/main.nf" + process { + """ + intervals = [[ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true)] + dict = [ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.dict", checkIfExists: true)] + input = [intervals, dict] + """ + } + } + + run("GATK4_COLLECTREADCOUNTS"){ + script "../../collectreadcounts/main.nf" + process { + """ + input_bam = channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true), + ], + [ [ id:'test2', single_end:false ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true) + ]) + fasta = channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]).collect() + fai = channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta.fai", checkIfExists: true)]).collect() + dict = channel.of([ [ id:'test' ], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.dict", checkIfExists: true)]).collect() + input = [input_bam, fasta, fai, dict] + """ + } + } + run("GATK4_DETERMINEGERMLINECONTIGPLOIDY", alias: "GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT") { + script "../../determinegermlinecontigploidy/main.nf" + process { + """ + bed = channel.value(file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.multi_intervals.bed", checkIfExists: true)) + input = [ + GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'], tsv ] }) + .groupTuple() + .combine(bed) + .map({ meta, counts, bed -> [ meta, counts, bed, [] ]}), + [[],[]], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/contig_ploidy_priors_table.tsv", checkIfExists: true) + ] + """ + } + } + + run("GATK4_GERMLINECNVCALLER", alias: "GATK4_GERMLINECNVCALLER_COHORT") { + script "../../germlinecnvcaller/main.nf" + process { + """ + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .map({ meta, tsv -> [[id:'test'], tsv ] }) + .groupTuple() + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT.out.calls) + .combine(GATK4_BEDTOINTERVALLIST.out.interval_list) + .map({ meta, counts, meta2, calls, meta3, bed -> [ meta, counts, bed, calls, [] ]}) + """ + } + } + + run("GATK4_GERMLINECNVCALLER", alias: "GATK4_GERMLINECNVCALLER_CASE") { + script "../../germlinecnvcaller/main.nf" + process { + """ + input[0] = GATK4_COLLECTREADCOUNTS.out.tsv + .first() + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT.out.calls) + .combine(GATK4_GERMLINECNVCALLER_COHORT.out.cohortmodel) + .map({ meta, counts, meta2, calls, meta3, model -> [ [id:'test'], counts, [], calls, model ]}) + """ + } + } + } + + test("homo sapiens - counts") { + + when { + process { + """ + input[0] = GATK4_GERMLINECNVCALLER_COHORT.out.cohortcalls + .combine(GATK4_GERMLINECNVCALLER_COHORT.out.cohortmodel) + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT.out.calls) + .map({ meta, calls, meta2, model, meta3, ploidy -> [[id:'test'], calls, model, ploidy ]}) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.intervals[0][1]).name, + file(process.out.segments[0][1]).name, + file(process.out.denoised[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("homo sapiens - counts - stub") { + + options "-stub" + + when { + process { + """ + input[0] = GATK4_GERMLINECNVCALLER_COHORT.out.cohortcalls + .combine(GATK4_GERMLINECNVCALLER_COHORT.out.cohortmodel) + .combine(GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT.out.calls) + .map({ meta, calls, meta2, model, meta3, ploidy -> [[id:'test'], calls, model, ploidy ]}) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.intervals[0][1]).name, + file(process.out.segments[0][1]).name, + file(process.out.denoised[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test.snap b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test.snap new file mode 100644 index 000000000..71182fe84 --- /dev/null +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/main.nf.test.snap @@ -0,0 +1,44 @@ +{ + "homo sapiens - counts - stub": { + "content": [ + "test_genotyped_intervals.vcf.gz", + "test_genotyped_segments.vcf.gz", + "test_denoised.vcf.gz", + { + "versions_gatk4": [ + [ + "GATK4_POSTPROCESSGERMLINECNVCALLS", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T17:13:11.168329663" + }, + "homo sapiens - counts": { + "content": [ + "test_genotyped_intervals.vcf.gz", + "test_genotyped_segments.vcf.gz", + "test_denoised.vcf.gz", + { + "versions_gatk4": [ + [ + "GATK4_POSTPROCESSGERMLINECNVCALLS", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T17:12:53.53221471" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/nextflow.config b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/nextflow.config new file mode 100644 index 000000000..81566d90e --- /dev/null +++ b/modules/nf-core/gatk4/postprocessgermlinecnvcalls/tests/nextflow.config @@ -0,0 +1,15 @@ +process { + withName: 'GATK4_COLLECTREADCOUNTS*' { + ext.args = "--format TSV --interval-merging-rule OVERLAPPING_ONLY" + } + withName: 'GATK4_DETERMINEGERMLINECONTIGPLOIDY_COHORT' { + ext.args = "--interval-merging-rule OVERLAPPING_ONLY" + ext.prefix = "ploidy" + } + withName: 'GATK4_GERMLINECNVCALLER_COHORT' { + ext.args = "--interval-merging-rule OVERLAPPING_ONLY --run-mode COHORT" + } + withName: 'GATK4_GERMLINECNVCALLER_CASE' { + ext.args = "--run-mode CASE" + } +} diff --git a/modules/nf-core/gatk4/printreads/environment.yml b/modules/nf-core/gatk4/printreads/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/printreads/environment.yml +++ b/modules/nf-core/gatk4/printreads/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/printreads/main.nf b/modules/nf-core/gatk4/printreads/main.nf index f97180adc..66e7f2a6e 100644 --- a/modules/nf-core/gatk4/printreads/main.nf +++ b/modules/nf-core/gatk4/printreads/main.nf @@ -1,11 +1,11 @@ process GATK4_PRINTREADS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(input), path(index) @@ -14,10 +14,10 @@ process GATK4_PRINTREADS { tuple val(meta4), path(dict) output: - tuple val(meta), path("${prefix}.bam") , emit: bam, optional: true - tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true - tuple val(meta), path("${prefix}.sam") , emit: sam, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true + tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true + tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -28,9 +28,10 @@ process GATK4_PRINTREADS { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK PrintReads] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK PrintReads] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } if ("${input}" == "${prefix}.${input.extension}") { error("Output filename is the same as input filename. Please specify a different prefix.") @@ -38,16 +39,11 @@ process GATK4_PRINTREADS { """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ PrintReads \\ - $args \\ - --reference $fasta \\ - --input $input \\ - --read-index $index \\ + ${args} \\ + --reference ${fasta} \\ + --input ${input} \\ + --read-index ${index} \\ --output ${prefix}.${input.getExtension()} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: @@ -56,10 +52,5 @@ process GATK4_PRINTREADS { touch ${prefix}.${input.getExtension()} touch ${prefix}.${input.getExtension()} touch ${prefix}.${input.getExtension()} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/printreads/meta.yml b/modules/nf-core/gatk4/printreads/meta.yml index de8da7c56..34de84ceb 100644 --- a/modules/nf-core/gatk4/printreads/meta.yml +++ b/modules/nf-core/gatk4/printreads/meta.yml @@ -27,10 +27,12 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - index: type: file description: BAM/CRAM/SAM file pattern: "*.{bai,crai,sai}" + ontologies: [] - - meta2: type: map description: | @@ -40,6 +42,7 @@ input: type: file description: reference fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -49,6 +52,7 @@ input: type: file description: reference fasta index file pattern: "*.{fai}" + ontologies: [] - - meta4: type: map description: | @@ -58,9 +62,10 @@ input: type: file description: reference fasta dictionary file pattern: "*.{dict}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -69,8 +74,9 @@ output: type: file description: Sorted BAM file pattern: "*.{bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -79,8 +85,9 @@ output: type: file description: Sorted CRAM file pattern: "*.{cram}" - - sam: - - meta: + ontologies: [] + sam: + - - meta: type: map description: | Groovy Map containing sample information @@ -89,11 +96,28 @@ output: type: file description: Sorted SAM file pattern: "*.{sam}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/gatk4/printreads/tests/main.nf.test b/modules/nf-core/gatk4/printreads/tests/main.nf.test index c07886197..126c780c3 100644 --- a/modules/nf-core/gatk4/printreads/tests/main.nf.test +++ b/modules/nf-core/gatk4/printreads/tests/main.nf.test @@ -17,36 +17,31 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) ] - input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] - input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] - input[3] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( bam(process.out.bam[0][1]).getReadsMD5(), process.out.cram, process.out.sam, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } @@ -58,38 +53,32 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) ] - input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] - input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] - input[3] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( process.out.bam, bam(process.out.cram[0][1]).getHeaderMD5(), process.out.sam, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } - } diff --git a/modules/nf-core/gatk4/printreads/tests/main.nf.test.snap b/modules/nf-core/gatk4/printreads/tests/main.nf.test.snap index 7f1266f26..26aa18f4e 100644 --- a/modules/nf-core/gatk4/printreads/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/printreads/tests/main.nf.test.snap @@ -8,33 +8,45 @@ [ ], - [ - "versions.yml:md5,9b368270d802ed95c530a7f0105f6453" - ] + { + "versions_gatk4": [ + [ + "GATK4_PRINTREADS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:48:53.871683" + "timestamp": "2026-02-05T17:13:29.864614856" }, "test-gatk4-printreads-cram": { "content": [ [ ], - "591299d00e262474250c5ccc241bba59", + "b1319b92694dfa02102224820fcc1ada", [ ], - [ - "versions.yml:md5,9b368270d802ed95c530a7f0105f6453" - ] + { + "versions_gatk4": [ + [ + "GATK4_PRINTREADS", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T13:42:29.968056" + "timestamp": "2026-02-05T17:13:38.337993548" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/revertsam/environment.yml b/modules/nf-core/gatk4/revertsam/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/revertsam/environment.yml +++ b/modules/nf-core/gatk4/revertsam/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/revertsam/main.nf b/modules/nf-core/gatk4/revertsam/main.nf index 635784ab2..8aa5747e0 100644 --- a/modules/nf-core/gatk4/revertsam/main.nf +++ b/modules/nf-core/gatk4/revertsam/main.nf @@ -1,18 +1,18 @@ process GATK4_REVERTSAM { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(bam) output: tuple val(meta), path('*.bam'), emit: bam - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -23,32 +23,23 @@ process GATK4_REVERTSAM { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK RevertSam] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK RevertSam] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ RevertSam \\ - --INPUT $bam \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.reverted.bam \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.reverted.bam - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/revertsam/meta.yml b/modules/nf-core/gatk4/revertsam/meta.yml index fb73b13f7..3cbc0cd1c 100644 --- a/modules/nf-core/gatk4/revertsam/meta.yml +++ b/modules/nf-core/gatk4/revertsam/meta.yml @@ -25,21 +25,40 @@ input: type: file description: The input bam/sam file pattern: "*.{bam,sam}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: file description: The reverted bam/sam file pattern: "*.reverted.bam" + ontologies: [] - "*.bam": type: file description: The reverted bam/sam file pattern: "*.reverted.bam" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" maintainers: diff --git a/modules/nf-core/gatk4/revertsam/tests/main.nf.test b/modules/nf-core/gatk4/revertsam/tests/main.nf.test index b52680485..a051a9abd 100644 --- a/modules/nf-core/gatk4/revertsam/tests/main.nf.test +++ b/modules/nf-core/gatk4/revertsam/tests/main.nf.test @@ -16,21 +16,19 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } @@ -41,19 +39,17 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - } diff --git a/modules/nf-core/gatk4/revertsam/tests/main.nf.test.snap b/modules/nf-core/gatk4/revertsam/tests/main.nf.test.snap index 1cbb5ce6e..e782cdcb2 100644 --- a/modules/nf-core/gatk4/revertsam/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/revertsam/tests/main.nf.test.snap @@ -2,15 +2,21 @@ "test-gatk4-revertsam": { "content": [ "e3cfa46b13cc4fc425cccae944f43b10", - [ - "versions.yml:md5,ee8dfa21abb49349e4865984cc122b9e" - ] + { + "versions_gatk4": [ + [ + "GATK4_REVERTSAM", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:45:39.712635" + "timestamp": "2026-02-05T17:58:02.45058488" }, "test-gatk4-revertsam-stubs": { "content": [ @@ -24,7 +30,11 @@ ] ], "1": [ - "versions.yml:md5,ee8dfa21abb49349e4865984cc122b9e" + [ + "GATK4_REVERTSAM", + "gatk4", + "4.6.2.0" + ] ], "bam": [ [ @@ -34,15 +44,19 @@ "test.reverted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,ee8dfa21abb49349e4865984cc122b9e" + "versions_gatk4": [ + [ + "GATK4_REVERTSAM", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:45:46.856318" + "timestamp": "2026-02-05T17:49:32.744361592" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/samtofastq/environment.yml b/modules/nf-core/gatk4/samtofastq/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/samtofastq/environment.yml +++ b/modules/nf-core/gatk4/samtofastq/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/samtofastq/main.nf b/modules/nf-core/gatk4/samtofastq/main.nf index 35b9b76db..0e3867f87 100644 --- a/modules/nf-core/gatk4/samtofastq/main.nf +++ b/modules/nf-core/gatk4/samtofastq/main.nf @@ -1,18 +1,18 @@ process GATK4_SAMTOFASTQ { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(bam) output: tuple val(meta), path('*.fastq.gz'), emit: fastq - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -24,34 +24,25 @@ process GATK4_SAMTOFASTQ { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK SamToFastq] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK SamToFastq] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ SamToFastq \\ - --INPUT $bam \\ - $output \\ + --INPUT ${bam} \\ + ${output} \\ --TMP_DIR . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.fastq.gz - touch ${prefix}_1.fastq.gz - touch ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + echo "" | gzip > ${prefix}.fastq.gz + echo "" | gzip > ${prefix}_1.fastq.gz + echo "" | gzip > ${prefix}_2.fastq.gz """ } diff --git a/modules/nf-core/gatk4/samtofastq/meta.yml b/modules/nf-core/gatk4/samtofastq/meta.yml index 91a8e503f..b392f8bc1 100644 --- a/modules/nf-core/gatk4/samtofastq/meta.yml +++ b/modules/nf-core/gatk4/samtofastq/meta.yml @@ -25,21 +25,39 @@ input: type: file description: Input SAM/BAM file pattern: "*.{bam,sam}" + ontologies: [] output: - - fastq: - - meta: - type: file - description: converted fastq file - pattern: "*.fastq" + fastq: + - - meta: + type: map + description: A Groovy map containing sample information - "*.fastq.gz": type: file description: converted fastq file pattern: "*.fastq" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" maintainers: diff --git a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test index 30a41addd..df9393461 100644 --- a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test +++ b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test @@ -16,19 +16,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end: true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ] ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( path(process.out.fastq[0][1]).linesGzip[3..7], - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -41,19 +40,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end: false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( process.out.fastq[0][1].collect { path(it).linesGzip[3..7] }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -66,23 +64,21 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end: true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ] ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( process.out.fastq[0][1].collect { file(it).name }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } } - } diff --git a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap index 0e1ec4b79..84f2cc5f7 100644 --- a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap @@ -8,15 +8,21 @@ "+", "AAA6AEEEEEEEEEAEEE/6EEAEEEAEEEEEAEEEEEEEEEEEEEEEEEEEEE versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf.gz + echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/selectvariants/meta.yml b/modules/nf-core/gatk4/selectvariants/meta.yml index 5fd9c6f39..3297ea69b 100644 --- a/modules/nf-core/gatk4/selectvariants/meta.yml +++ b/modules/nf-core/gatk4/selectvariants/meta.yml @@ -34,9 +34,10 @@ input: type: file description: One or more genomic intervals over which to operate pattern: ".intervals" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -45,8 +46,10 @@ output: type: file description: Compressed VCF file pattern: "*.selectvariants.vcf.gz" - - tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -55,11 +58,28 @@ output: type: file description: Tabix index file pattern: "*.vcf.gz.tbi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@mjcipriano" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/selectvariants/tests/main.nf.test b/modules/nf-core/gatk4/selectvariants/tests/main.nf.test index d8a97d2c5..c9dfee2bb 100644 --- a/modules/nf-core/gatk4/selectvariants/tests/main.nf.test +++ b/modules/nf-core/gatk4/selectvariants/tests/main.nf.test @@ -11,10 +11,6 @@ nextflow_process { test("selectvariants - vcf input") { when { - params { - // define parameters here. Example: - // outdir = "tests/results" - } process { """ input[0] = [ @@ -28,13 +24,14 @@ nextflow_process { } then { + assert process.success assertAll( - {assert process.success}, - {assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2")} + { assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2") }, + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - - } test("selectvariants - gz input") { @@ -53,12 +50,13 @@ nextflow_process { } then { + assert process.success assertAll( - {assert process.success}, - {assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2")} + { assert path(process.out.vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.2") }, + { assert snapshot( + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - } diff --git a/modules/nf-core/gatk4/selectvariants/tests/main.nf.test.snap b/modules/nf-core/gatk4/selectvariants/tests/main.nf.test.snap new file mode 100644 index 000000000..6007162b1 --- /dev/null +++ b/modules/nf-core/gatk4/selectvariants/tests/main.nf.test.snap @@ -0,0 +1,38 @@ +{ + "selectvariants - gz input": { + "content": [ + { + "versions_gatk4": [ + [ + "GATK4_SELECTVARIANTS", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T10:16:52.22932" + }, + "selectvariants - vcf input": { + "content": [ + { + "versions_gatk4": [ + [ + "GATK4_SELECTVARIANTS", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T10:16:31.972787" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/selectvariants/tests/tags.yml b/modules/nf-core/gatk4/selectvariants/tests/tags.yml deleted file mode 100644 index d9fb50f77..000000000 --- a/modules/nf-core/gatk4/selectvariants/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/selectvariants: - - "modules/nf-core/gatk4/selectvariants/**" diff --git a/modules/nf-core/gatk4/shiftfasta/environment.yml b/modules/nf-core/gatk4/shiftfasta/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/shiftfasta/environment.yml +++ b/modules/nf-core/gatk4/shiftfasta/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/shiftfasta/main.nf b/modules/nf-core/gatk4/shiftfasta/main.nf index 350ff8d33..797167913 100644 --- a/modules/nf-core/gatk4/shiftfasta/main.nf +++ b/modules/nf-core/gatk4/shiftfasta/main.nf @@ -1,11 +1,11 @@ process GATK4_SHIFTFASTA { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(fasta) @@ -13,13 +13,13 @@ process GATK4_SHIFTFASTA { tuple val(meta3), path(dict) output: - tuple val(meta), path("*_shift.fasta") , emit: shift_fa - tuple val(meta), path("*_shift.fasta.fai") , emit: shift_fai - tuple val(meta), path("*_shift.back_chain") , emit: shift_back_chain - tuple val(meta), path("*_shift.dict") , emit: dict , optional: true - tuple val(meta), path("*.intervals") , emit: intervals , optional: true - tuple val(meta), path("*.shifted.intervals") , emit: shift_intervals , optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*_shift.fasta"), emit: shift_fa + tuple val(meta), path("*_shift.fasta.fai"), emit: shift_fai + tuple val(meta), path("*_shift.back_chain"), emit: shift_back_chain + tuple val(meta), path("*_shift.dict"), emit: dict, optional: true + tuple val(meta), path("*.intervals"), emit: intervals, optional: true + tuple val(meta), path("*.shifted.intervals"), emit: shift_intervals, optional: true + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -31,38 +31,30 @@ process GATK4_SHIFTFASTA { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK ShiftFasta] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK ShiftFasta] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ ShiftFasta \\ - --reference $fasta \\ + --reference ${fasta} \\ --output ${prefix}_shift.fasta \\ --shift-back-output ${prefix}_shift.back_chain \\ - $args \\ - $seq_dict \\ + ${args} \\ + ${seq_dict} \\ --tmp-dir . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ stub: + def prefix = task.ext.prefix ?: "${meta.id}" """ - touch test.intervals - touch test_shift.back_chain - touch test_shift.dict - touch test.shifted.intervals - touch test_shift.fasta - touch test_shift.fasta.fai - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + touch ${prefix}.intervals + touch ${prefix}_shift.back_chain + touch ${prefix}_shift.dict + touch ${prefix}.shifted.intervals + touch ${prefix}_shift.fasta + touch ${prefix}_shift.fasta.fai """ } diff --git a/modules/nf-core/gatk4/shiftfasta/meta.yml b/modules/nf-core/gatk4/shiftfasta/meta.yml index 28b2ac555..fdcfe83e2 100644 --- a/modules/nf-core/gatk4/shiftfasta/meta.yml +++ b/modules/nf-core/gatk4/shiftfasta/meta.yml @@ -28,6 +28,7 @@ input: type: file description: fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta2: type: map description: | @@ -37,6 +38,7 @@ input: type: file description: index for fasta file pattern: "*.{fai}" + ontologies: [] - - meta3: type: map description: | @@ -46,9 +48,10 @@ input: type: file description: sequence dictionary file pattern: "*.{dict}" + ontologies: [] output: - - shift_fa: - - meta: + shift_fa: + - - meta: type: map description: | Groovy Map containing fasta information @@ -57,8 +60,9 @@ output: type: file description: Shifted fasta file pattern: "*.{fa,fasta}" - - shift_fai: - - meta: + ontologies: [] + shift_fai: + - - meta: type: map description: | Groovy Map containing fasta information @@ -67,8 +71,9 @@ output: type: file description: Index file for the shifted fasta file pattern: "*.{fai}" - - shift_back_chain: - - meta: + ontologies: [] + shift_back_chain: + - - meta: type: map description: | Groovy Map containing fasta information @@ -77,8 +82,9 @@ output: type: file description: The shiftback chain file to use when lifting over pattern: "*.{back_chain}" - - dict: - - meta: + ontologies: [] + dict: + - - meta: type: map description: | Groovy Map containing fasta information @@ -87,8 +93,9 @@ output: type: file description: sequence dictionary file pattern: "*.{dict}" - - intervals: - - meta: + ontologies: [] + intervals: + - - meta: type: map description: | Groovy Map containing fasta information @@ -97,12 +104,9 @@ output: type: file description: Intervals file for the fasta file pattern: "*.{intervals}" - - s: - type: file - description: Intervals file for the fasta file - pattern: "*.{intervals}" - - shift_intervals: - - meta: + ontologies: [] + shift_intervals: + - - meta: type: map description: | Groovy Map containing fasta information @@ -111,15 +115,28 @@ output: type: file description: Intervals file for the shifted fasta file pattern: "*.{shifted.intervals}" - - s: - type: file - description: Intervals file for the shifted fasta file - pattern: "*.{shifted.intervals}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test b/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test index d11d144ea..843354e9a 100644 --- a/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test +++ b/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test @@ -18,15 +18,15 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] """ @@ -34,11 +34,10 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - } diff --git a/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test.snap b/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test.snap index bb7e5aa01..a4fe7d3af 100644 --- a/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/shiftfasta/tests/main.nf.test.snap @@ -60,7 +60,11 @@ ] ], "6": [ - "versions.yml:md5,afdffb5981aa10bdf40af3a50323fd54" + [ + "GATK4_SHIFTFASTA", + "gatk4", + "4.6.2.0" + ] ], "dict": [ [ @@ -119,15 +123,19 @@ "test.shifted.intervals:md5,6d8d74cd94813e56ec9f09933884f45d" ] ], - "versions": [ - "versions.yml:md5,afdffb5981aa10bdf40af3a50323fd54" + "versions_gatk4": [ + [ + "GATK4_SHIFTFASTA", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:11:50.342225" + "timestamp": "2026-02-05T17:51:13.969347846" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/splitintervals/environment.yml b/modules/nf-core/gatk4/splitintervals/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/splitintervals/environment.yml +++ b/modules/nf-core/gatk4/splitintervals/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/splitintervals/main.nf b/modules/nf-core/gatk4/splitintervals/main.nf index d59b6afb1..5945c8655 100644 --- a/modules/nf-core/gatk4/splitintervals/main.nf +++ b/modules/nf-core/gatk4/splitintervals/main.nf @@ -1,11 +1,11 @@ process GATK4_SPLITINTERVALS { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(intervals) @@ -15,7 +15,7 @@ process GATK4_SPLITINTERVALS { output: tuple val(meta), path("**.interval_list"), emit: split_intervals - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -23,27 +23,23 @@ process GATK4_SPLITINTERVALS { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--reference $fasta" : "" + def reference = fasta ? "--reference ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK SplitIntervals] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK SplitIntervals] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ SplitIntervals \\ --output ${prefix} \\ - --intervals $intervals \\ - $reference \\ + --intervals ${intervals} \\ + ${reference} \\ --tmp-dir . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ stub: @@ -52,10 +48,5 @@ process GATK4_SPLITINTERVALS { mkdir ${prefix} touch ${prefix}/0000-scattered.interval_list touch ${prefix}/0001-scattered.interval_list - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/splitintervals/meta.yml b/modules/nf-core/gatk4/splitintervals/meta.yml index 6a1b869b0..695334563 100644 --- a/modules/nf-core/gatk4/splitintervals/meta.yml +++ b/modules/nf-core/gatk4/splitintervals/meta.yml @@ -23,6 +23,7 @@ input: - intervals: type: file description: Interval file + ontologies: [] - - meta2: type: map description: | @@ -32,6 +33,7 @@ input: type: file description: Reference FASTA pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -41,6 +43,7 @@ input: type: file description: Reference FASTA index pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -50,22 +53,42 @@ input: type: file description: Reference sequence dictionary pattern: "*.dict" + ontologies: [] output: - - split_intervals: - - meta: + split_intervals: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test' ] + pattern: "*.interval_list" - "**.interval_list": - type: file - description: interval files + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] pattern: "*.interval_list" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/splitintervals/tests/main.nf.test b/modules/nf-core/gatk4/splitintervals/tests/main.nf.test index 26c20f88f..41d5c8f4b 100644 --- a/modules/nf-core/gatk4/splitintervals/tests/main.nf.test +++ b/modules/nf-core/gatk4/splitintervals/tests/main.nf.test @@ -17,26 +17,25 @@ nextflow_process { process { """ input[0] = [ - [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.multi_intervals.bed', checkIfExists: true) + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.multi_intervals.bed', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] input[3] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } @@ -49,25 +48,24 @@ nextflow_process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.interval_list', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.interval_list', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] input[3] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } @@ -82,28 +80,26 @@ nextflow_process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.interval_list', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.interval_list', checkIfExists: true) ] input[1] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] input[2] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] input[3] = [ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] - """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - } diff --git a/modules/nf-core/gatk4/splitintervals/tests/main.nf.test.snap b/modules/nf-core/gatk4/splitintervals/tests/main.nf.test.snap index d055a8737..77cc7afe8 100644 --- a/modules/nf-core/gatk4/splitintervals/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/splitintervals/tests/main.nf.test.snap @@ -14,7 +14,11 @@ ] ], "1": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ], "split_intervals": [ [ @@ -27,16 +31,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + "versions_gatk4": [ + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:06:41.633105" + "timestamp": "2026-02-05T17:52:08.822076018" }, "test-gatk4-splitintervals-bed": { "content": [ @@ -53,7 +61,11 @@ ] ], "1": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ], "split_intervals": [ [ @@ -66,16 +78,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + "versions_gatk4": [ + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-26T11:06:28.504041" + "timestamp": "2026-02-05T17:52:01.205689288" }, "test-gatk4-splitintervals-intervals-stub": { "content": [ @@ -92,7 +108,11 @@ ] ], "1": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ], "split_intervals": [ [ @@ -105,15 +125,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,384addd364fb36fdac7593eba22fcdb7" + "versions_gatk4": [ + [ + "GATK4_SPLITINTERVALS", + "gatk4", + "4.6.2.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-27T10:56:46.243594" + "timestamp": "2026-02-05T17:52:15.297589219" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/splitintervals/tests/nextflow.config b/modules/nf-core/gatk4/splitintervals/tests/nextflow.config index 18f7dda02..f012109c4 100644 --- a/modules/nf-core/gatk4/splitintervals/tests/nextflow.config +++ b/modules/nf-core/gatk4/splitintervals/tests/nextflow.config @@ -2,4 +2,4 @@ process { withName: GATK4_SPLITINTERVALS { ext.args = "--scatter-count 2" } -} \ No newline at end of file +} diff --git a/modules/nf-core/gatk4/variantfiltration/environment.yml b/modules/nf-core/gatk4/variantfiltration/environment.yml index 55993f440..67e0eb860 100644 --- a/modules/nf-core/gatk4/variantfiltration/environment.yml +++ b/modules/nf-core/gatk4/variantfiltration/environment.yml @@ -1,5 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::gatk4=4.5.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.2.0 + # renovate: datasource=conda depName=bioconda/gcnvkernel + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/variantfiltration/main.nf b/modules/nf-core/gatk4/variantfiltration/main.nf index 388c60abf..6256351b1 100644 --- a/modules/nf-core/gatk4/variantfiltration/main.nf +++ b/modules/nf-core/gatk4/variantfiltration/main.nf @@ -1,22 +1,23 @@ process GATK4_VARIANTFILTRATION { - tag "$meta.id" - label 'process_medium' + tag "${meta.id}" + label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.5.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.5.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ce/ced519873646379e287bc28738bdf88e975edd39a92e7bc6a34bccd37153d9d0/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:edb12e4f0bf02cd3'}" input: tuple val(meta), path(vcf), path(tbi) tuple val(meta2), path(fasta) tuple val(meta3), path(fai) tuple val(meta4), path(dict) + tuple val(meta5), path(gzi) output: tuple val(meta), path("*.vcf.gz"), emit: vcf - tuple val(meta), path("*.tbi") , emit: tbi - path "versions.yml" , emit: versions + tuple val(meta), path("*.tbi"), emit: tbi + tuple val("${task.process}"), val('gatk4'), eval("gatk --version | sed -n '/GATK.*v/s/.*v//p'"), topic: versions, emit: versions_gatk4 when: task.ext.when == null || task.ext.when @@ -25,35 +26,39 @@ process GATK4_VARIANTFILTRATION { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + // Infer .dict file name that gatk expects, even if ends in .fasta.gz + def dict_name = fasta.getBaseName() + if (dict_name ==~ /^.*\.(fasta|fna|fa)$/) { + dict_name = dict_name.replaceAll(/\.(fasta|fna|fa)$/, "") + } + dict_name = "${dict_name}.dict" + def avail_mem = 3072 if (!task.memory) { - log.info '[GATK VariantFiltration] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK VariantFiltration] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ + # Make sure the .dict file is named correctly + if [[ ${dict_name} != ${dict} ]]; then + ln -s ${dict} ${dict_name} + fi + gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ VariantFiltration \\ - --variant $vcf \\ + --variant ${vcf} \\ --output ${prefix}.vcf.gz \\ - --reference $fasta \\ + --reference ${fasta} \\ --tmp-dir . \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS + ${args} """ + stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf.gz + echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/gatk4/variantfiltration/meta.yml b/modules/nf-core/gatk4/variantfiltration/meta.yml index 8e23e205b..4177a706d 100644 --- a/modules/nf-core/gatk4/variantfiltration/meta.yml +++ b/modules/nf-core/gatk4/variantfiltration/meta.yml @@ -39,6 +39,7 @@ input: type: file description: Fasta file of reference genome pattern: "*.fasta" + ontologies: [] - - meta3: type: map description: | @@ -48,6 +49,7 @@ input: type: file description: Index of fasta file pattern: "*.fasta.fai" + ontologies: [] - - meta4: type: map description: | @@ -57,30 +59,65 @@ input: type: file description: Sequence dictionary of fastea file pattern: "*.dict" + ontologies: [] + - - meta5: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - gzi: + type: file + description: Genome index file only needed when the genome file was compressed + with the BGZF algorithm. + pattern: "*.gzi" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: file description: Compressed VCF file pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.vcf.gz": type: file description: Compressed VCF file pattern: "*.vcf.gz" - - tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: type: file - description: Index of VCF file - pattern: "*.vcf.gz.tbi" + description: Compressed VCF file + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - "*.tbi": type: file description: Index of VCF file pattern: "*.vcf.gz.tbi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_gatk4: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gatk4: + type: string + description: The name of the tool + - gatk --version | sed -n '/GATK.*v/s/.*v//p': + type: eval + description: The expression to obtain the version of the tool authors: - "@kevinmenden" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test b/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test index 36b7438d3..cbb647c47 100644 --- a/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test +++ b/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test @@ -9,7 +9,7 @@ nextflow_process { tag "gatk4" tag "gatk4/variantfiltration" - test("test_gatk4_variantfiltration_vcf_input") { + test("gatk4_variantfiltration - human - vcf - fasta") { when { process { @@ -31,22 +31,69 @@ nextflow_process { [ id:'genome' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] + input[4] = [ + [ id:'genome' ], // meta map + [] + ] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out.versions, - file(process.out.vcf.get(0).get(1)).name, - file(process.out.tbi.get(0).get(1)).name).match() }, + { assert snapshot( + path(process.out.vcf[0][1]).vcf.variantsMD5, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } + } + test("gatk4_variantfiltration - human - vcf - fasta.gz") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.idx', checkIfExists: true) + ] + input[1] = [ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + ] + input[2] = [ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true) + ] + input[3] = [ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + ] + input[4] = [ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf[0][1]).vcf.variantsMD5, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } } - test("test_gatk4_variantfiltration_gz_input") { + test("gatk4_variantfiltration - human - vcf.gz - fasta") { when { process { @@ -68,20 +115,23 @@ nextflow_process { [ id:'genome' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) ] + input[4] = [ + [ id:'genome' ], // meta map + [] + ] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out.versions, - file(process.out.vcf.get(0).get(1)).name, - file(process.out.tbi.get(0).get(1)).name).match() }, + { assert snapshot( + path(process.out.vcf[0][1]).vcf.variantsMD5, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - } - diff --git a/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test.snap b/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test.snap index 36c03f7c1..e1a3c785a 100644 --- a/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test.snap +++ b/modules/nf-core/gatk4/variantfiltration/tests/main.nf.test.snap @@ -1,30 +1,62 @@ { - "test_gatk4_variantfiltration_gz_input": { + "gatk4_variantfiltration - human - vcf - fasta.gz": { "content": [ - [ - "versions.yml:md5,96943659275ba62de1f0d283a2f6e97b" - ], - "test.vcf.gz", - "test.vcf.gz.tbi" + "cf0477cc14953b16caacbf5be507b88", + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_VARIANTFILTRATION", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-22T22:43:27.609784" + "timestamp": "2026-02-05T18:03:01.467326216" }, - "test_gatk4_variantfiltration_vcf_input": { + "gatk4_variantfiltration - human - vcf.gz - fasta": { "content": [ - [ - "versions.yml:md5,96943659275ba62de1f0d283a2f6e97b" - ], - "test.vcf.gz", - "test.vcf.gz.tbi" + "cf0477cc14953b16caacbf5be507b88", + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_VARIANTFILTRATION", + "gatk4", + "4.6.2.0" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-05-22T22:42:55.316294" + "timestamp": "2026-02-05T18:03:09.049097033" + }, + "gatk4_variantfiltration - human - vcf - fasta": { + "content": [ + "cf0477cc14953b16caacbf5be507b88", + "test.vcf.gz.tbi", + { + "versions_gatk4": [ + [ + "GATK4_VARIANTFILTRATION", + "gatk4", + "4.6.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-05T18:02:52.913618285" } } \ No newline at end of file diff --git a/modules/nf-core/gatk4/variantfiltration/tests/tags.yml b/modules/nf-core/gatk4/variantfiltration/tests/tags.yml deleted file mode 100644 index 4818037d7..000000000 --- a/modules/nf-core/gatk4/variantfiltration/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -gatk4/variantfiltration: - - "modules/nf-core/gatk4/variantfiltration/**" diff --git a/modules/nf-core/gawk/environment.yml b/modules/nf-core/gawk/environment.yml new file mode 100644 index 000000000..185a0f545 --- /dev/null +++ b/modules/nf-core/gawk/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::gawk=5.3.1 diff --git a/modules/nf-core/gawk/main.nf b/modules/nf-core/gawk/main.nf new file mode 100644 index 000000000..33dd24ccd --- /dev/null +++ b/modules/nf-core/gawk/main.nf @@ -0,0 +1,60 @@ +process GAWK { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a1/a125c778baf3865331101a104b60d249ee15fe1dca13bdafd888926cc5490a34/data' : + 'community.wave.seqera.io/library/gawk:5.3.1--e09efb5dfc4b8156' }" + + input: + tuple val(meta), path(input, arity: '0..*') + path(program_file) + val(disable_redirect_output) + + output: + tuple val(meta), path("*.${suffix}"), emit: output + tuple val("${task.process}"), val('gawk'), eval("awk -Wversion | sed '1!d; s/.*Awk //; s/,.*//'"), topic: versions, emit: versions_gawk + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' // args is used for the main arguments of the tool + def args2 = task.ext.args2 ?: '' // args2 is used to specify a program when no program file has been given + prefix = task.ext.prefix ?: "${meta.id}" + suffix = task.ext.suffix ?: "${input.collect{ file -> file.getExtension()}.get(0)}" // use the first extension of the input files + + program = program_file ? "-f ${program_file}" : "${args2}" + lst_gz = input.findResults{ file -> file.getExtension().endsWith("gz") ? file.toString() : null } + unzip = lst_gz ? "gunzip -q -f ${lst_gz.join(" ")}" : "" + input_cmd = input.collect { file -> file.toString() - ~/\.gz$/ }.join(" ") + output_cmd = suffix.endsWith("gz") ? "| gzip > ${prefix}.${suffix}" : "> ${prefix}.${suffix}" + output = disable_redirect_output ? "" : output_cmd + cleanup = lst_gz ? "rm ${lst_gz.collect{ file -> file - ~/\.gz$/ }.join(" ")}" : "" + + input.collect{ file -> + assert file.name != "${prefix}.${suffix}" : "Input and output names are the same, set prefix in module configuration to disambiguate!" + } + + """ + ${unzip} + + awk \\ + ${args} \\ + ${program} \\ + ${input_cmd} \\ + ${output} + + ${cleanup} + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + suffix = task.ext.suffix ?: "${input.collect{ file -> file.getExtension()}.get(0)}" + def create_cmd = suffix.endsWith("gz") ? "echo '' | gzip >" : "touch" + + """ + ${create_cmd} ${prefix}.${suffix} + """ +} diff --git a/modules/nf-core/gawk/meta.yml b/modules/nf-core/gawk/meta.yml new file mode 100644 index 000000000..96cd0c72b --- /dev/null +++ b/modules/nf-core/gawk/meta.yml @@ -0,0 +1,84 @@ +name: "gawk" +description: | + If you are like many computer users, you would frequently like to make changes in various text files + wherever certain patterns appear, or extract data from parts of certain lines while discarding the rest. + The job is easy with awk, especially the GNU implementation gawk. +keywords: + - gawk + - awk + - txt + - text + - file parsing +tools: + - "gawk": + description: "GNU awk" + homepage: "https://www.gnu.org/software/gawk/" + documentation: "https://www.gnu.org/software/gawk/manual/" + tool_dev_url: "https://www.gnu.org/prep/ftp.html" + licence: + - "GPL v3" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: The input file - Specify the logic that needs to be executed + on this file on the `ext.args2` or in the program file. If the files + have a `.gz` extension, they will be unzipped using `zcat`. + pattern: "*" + ontologies: [] + - program_file: + type: file + description: Optional file containing logic for awk to execute. If you don't + wish to use a file, you can use `ext.args2` to specify the logic. + pattern: "*" + ontologies: [] + - disable_redirect_output: + type: boolean + description: Disable the redirection of awk output to a given file. This is + useful if you want to use awk's built-in redirect to write files instead + of the shell's redirect. +output: + output: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.${suffix}": + type: file + description: The output file - if using shell redirection, specify the + name of this file using `ext.prefix` and the extension using + `ext.suffix`. Otherwise, ensure the awk program produces files with + the extension in `ext.suffix`. + pattern: "*" + ontologies: [] + versions_gawk: + - - ${task.process}: + type: string + description: The name of the process + - gawk: + type: string + description: The name of the tool + - awk -Wversion | sed '1!d; s/.*Awk //; s/,.*//': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gawk: + type: string + description: The name of the tool + - awk -Wversion | sed '1!d; s/.*Awk //; s/,.*//': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@nvnieuwk" +maintainers: + - "@nvnieuwk" diff --git a/modules/nf-core/gawk/tests/main.nf.test b/modules/nf-core/gawk/tests/main.nf.test new file mode 100644 index 000000000..3bd0a43d6 --- /dev/null +++ b/modules/nf-core/gawk/tests/main.nf.test @@ -0,0 +1,211 @@ +nextflow_process { + + name "Test Process GAWK" + script "../main.nf" + process "GAWK" + + tag "modules" + tag "modules_nfcore" + tag "gawk" + + config "./nextflow.config" + + test("Convert fasta to bed") { + when { + params { + gawk_suffix = "bed" + gawk_args2 = '\'BEGIN { FS = OFS = "\t"}; { print \$1, "0", \$2 }\'' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = [] + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Convert fasta to bed - stub") { + + options "-stub" + + when { + params { + gawk_suffix = "bed" + gawk_args2 = '\'BEGIN { FS = OFS = "\t"}; { print \$1, "0", \$2 }\'' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = [] + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + } + + test("Convert fasta to bed with program file") { + when { + params { + gawk_suffix = "bed" + gawk_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = Channel.of('BEGIN { FS = OFS = "\t"}; { print \$1, "0", \$2 }').collectFile(name:"program.awk") + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Convert fasta to bed using awk redirect instead of shell redirect") { + when { + params { + gawk_suffix = "bed" + gawk_args2 = '\'BEGIN { FS = OFS = "\t"}; { print \$1, "0", \$2 > "test.bed" }\'' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = [] + input[2] = true + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Extract first column from multiple files") { + when { + params { + gawk_suffix = "bed" + gawk_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test' ], + [file(params.modules_testdata_base_path + 'generic/txt/hello.txt', checkIfExists: true), + file(params.modules_testdata_base_path + 'generic/txt/species_names.txt', checkIfExists: true)] + ] + input[1] = Channel.of('BEGIN {FS=" "}; {print \$1}').collectFile(name:"program.awk") + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Unzip files before processing") { + when { + params { + gawk_suffix = "bed" + gawk_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test' ], + [file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_chrM.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA24385_sv.vcf.gz', checkIfExists: true)] + ] + input[1] = Channel.of('/^#CHROM/ { print \$1, \$10 }').collectFile(name:"column_header.awk") + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Compress after processing") { + when { + params { + gawk_suffix = "txt.gz" + gawk_args2 = '\'BEGIN { FS = OFS = "\t"}; { print \$1, "0", \$2 }\'' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = [] + input[2] = false + """ + } + } + + then { + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() + } + } + + test("Input and output files are similar") { + when { + params { + gawk_suffix = "txt" + gawk_args = "" + gawk_args2 = "" + } + process { + """ + input[0] = [ + [ id:'hello' ], + [file(params.modules_testdata_base_path + 'generic/txt/hello.txt', checkIfExists: true), + file(params.modules_testdata_base_path + 'generic/txt/species_names.txt', checkIfExists: true)] + ] + input[1] = Channel.of('BEGIN {FS=" "}; {print \$1}').collectFile(name:"program.awk") + input[2] = false + """ + } + } + + then { + assert process.failed + assert process.errorReport.contains("Input and output names are the same, set prefix in module configuration to disambiguate!") + } + } +} diff --git a/modules/nf-core/gawk/tests/main.nf.test.snap b/modules/nf-core/gawk/tests/main.nf.test.snap new file mode 100644 index 000000000..9d6a36973 --- /dev/null +++ b/modules/nf-core/gawk/tests/main.nf.test.snap @@ -0,0 +1,199 @@ +{ + "Compress after processing": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.txt.gz:md5,87a15eb9c2ff20ccd5cd8735a28708f7" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:50.761549948", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Convert fasta to bed": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,87a15eb9c2ff20ccd5cd8735a28708f7" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:30:50.804933797", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Convert fasta to bed with program file": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,87a15eb9c2ff20ccd5cd8735a28708f7" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:10.838989113", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Convert fasta to bed - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ], + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:00.182649403", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Extract first column from multiple files": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,566c51674bd643227bb2d83e0963376d" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:30.796772884", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Unzip files before processing": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,1e31ebd4a060aab5433bbbd9ab24e403" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:40.72259289", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "Convert fasta to bed using awk redirect instead of shell redirect": { + "content": [ + { + "output": [ + [ + { + "id": "test" + }, + "test.bed:md5,87a15eb9c2ff20ccd5cd8735a28708f7" + ] + ], + "versions_gawk": [ + [ + "GAWK", + "gawk", + "5.3.1" + ] + ] + } + ], + "timestamp": "2026-03-04T11:31:20.33222004", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/gawk/tests/nextflow.config b/modules/nf-core/gawk/tests/nextflow.config new file mode 100644 index 000000000..895709a76 --- /dev/null +++ b/modules/nf-core/gawk/tests/nextflow.config @@ -0,0 +1,6 @@ +process { + withName: GAWK { + ext.suffix = params.gawk_suffix + ext.args2 = params.gawk_args2 + } +} diff --git a/modules/nf-core/genmod/annotate/environment.yml b/modules/nf-core/genmod/annotate/environment.yml index 227ee8920..6b91c71a0 100644 --- a/modules/nf-core/genmod/annotate/environment.yml +++ b/modules/nf-core/genmod/annotate/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::genmod=3.9 + - bioconda::genmod=3.10.2 + - conda-forge::python=3.11.14 diff --git a/modules/nf-core/genmod/annotate/main.nf b/modules/nf-core/genmod/annotate/main.nf index 0b8b232de..6236e8566 100644 --- a/modules/nf-core/genmod/annotate/main.nf +++ b/modules/nf-core/genmod/annotate/main.nf @@ -4,15 +4,15 @@ process GENMOD_ANNOTATE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/genmod:3.9--pyhdfd78af_0': - 'biocontainers/genmod:3.9--pyhdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/31/31b331bee43c7ff070bdde5460a4102ba31c3bfb0ee0d70197001ff011036555/data' : + 'community.wave.seqera.io/library/genmod_python:31b2fba4d3b7ba6f' }" input: tuple val(meta), path(input_vcf) output: tuple val(meta), path("*_annotate.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('genmod'), eval("genmod --version | sed 's/^.*genmod version: //'"), emit: versions_genmod, topic: versions when: task.ext.when == null || task.ext.when @@ -26,21 +26,11 @@ process GENMOD_ANNOTATE { $args \\ --outfile ${prefix}_annotate.vcf \\ $input_vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}_annotate.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/genmod/annotate/meta.yml b/modules/nf-core/genmod/annotate/meta.yml index bb4afb6b4..65f8fda0c 100644 --- a/modules/nf-core/genmod/annotate/meta.yml +++ b/modules/nf-core/genmod/annotate/meta.yml @@ -22,9 +22,10 @@ input: type: file description: VCF file pattern: "*.{vcf}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -33,11 +34,28 @@ output: type: file description: Annotated VCF file pattern: "*.{vcf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_genmod: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/genmod/annotate/tests/main.nf.test b/modules/nf-core/genmod/annotate/tests/main.nf.test index a4b3fccba..7b053b2ee 100644 --- a/modules/nf-core/genmod/annotate/tests/main.nf.test +++ b/modules/nf-core/genmod/annotate/tests/main.nf.test @@ -26,9 +26,10 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.versions, path(process.out.vcf.get(0).get(1)).vcf.summary, - ).match() } + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.findAll { key, val -> key.startsWith("versions") }, + ).match() } ) } diff --git a/modules/nf-core/genmod/annotate/tests/main.nf.test.snap b/modules/nf-core/genmod/annotate/tests/main.nf.test.snap new file mode 100644 index 000000000..23618cce2 --- /dev/null +++ b/modules/nf-core/genmod/annotate/tests/main.nf.test.snap @@ -0,0 +1,65 @@ +{ + "genmod_annotate": { + "content": [ + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=57, phased=false, phasedAutodetect=false]", + "ec9b1d7d21c9f6c0a6e0dffb56732fc3", + { + "versions_genmod": [ + [ + "GENMOD_ANNOTATE", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:45:39.879885252" + }, + "genmod_annotate - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_annotate.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GENMOD_ANNOTATE", + "genmod", + "3.10.2" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_annotate.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_genmod": [ + [ + "GENMOD_ANNOTATE", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:14:43.571171183" + } +} \ No newline at end of file diff --git a/modules/nf-core/genmod/annotate/tests/tags.yml b/modules/nf-core/genmod/annotate/tests/tags.yml deleted file mode 100644 index 88bb35a18..000000000 --- a/modules/nf-core/genmod/annotate/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -genmod/annotate: - - modules/nf-core/genmod/annotate/** diff --git a/modules/nf-core/genmod/compound/environment.yml b/modules/nf-core/genmod/compound/environment.yml index 227ee8920..6b91c71a0 100644 --- a/modules/nf-core/genmod/compound/environment.yml +++ b/modules/nf-core/genmod/compound/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::genmod=3.9 + - bioconda::genmod=3.10.2 + - conda-forge::python=3.11.14 diff --git a/modules/nf-core/genmod/compound/main.nf b/modules/nf-core/genmod/compound/main.nf index ca6a22a19..d28bda9be 100644 --- a/modules/nf-core/genmod/compound/main.nf +++ b/modules/nf-core/genmod/compound/main.nf @@ -4,15 +4,15 @@ process GENMOD_COMPOUND { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/genmod:3.9--pyhdfd78af_0': - 'biocontainers/genmod:3.9--pyhdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/31/31b331bee43c7ff070bdde5460a4102ba31c3bfb0ee0d70197001ff011036555/data' : + 'community.wave.seqera.io/library/genmod_python:31b2fba4d3b7ba6f' }" input: tuple val(meta), path(input_vcf) output: tuple val(meta), path("*_compound.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('genmod'), eval("genmod --version | sed 's/^.*genmod version: //'"), emit: versions_genmod, topic: versions when: task.ext.when == null || task.ext.when @@ -27,21 +27,11 @@ process GENMOD_COMPOUND { --processes ${task.cpus} \\ --outfile ${prefix}_compound.vcf \\ $input_vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}_compound.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/genmod/compound/meta.yml b/modules/nf-core/genmod/compound/meta.yml index ebd6a110c..87b33921b 100644 --- a/modules/nf-core/genmod/compound/meta.yml +++ b/modules/nf-core/genmod/compound/meta.yml @@ -22,9 +22,10 @@ input: type: file description: VCF file pattern: "*.{vcf}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -33,11 +34,28 @@ output: type: file description: Output VCF file pattern: "*.{vcf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_genmod: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/genmod/compound/tests/main.nf.test b/modules/nf-core/genmod/compound/tests/main.nf.test index 4c667c173..760126600 100644 --- a/modules/nf-core/genmod/compound/tests/main.nf.test +++ b/modules/nf-core/genmod/compound/tests/main.nf.test @@ -25,9 +25,9 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.versions, path(process.out.vcf.get(0).get(1)).vcf.summary, - ).match() } + process.out.findAll { key, val -> key.startsWith("versions") }, + ).match() } ) } diff --git a/modules/nf-core/genmod/compound/tests/main.nf.test.snap b/modules/nf-core/genmod/compound/tests/main.nf.test.snap new file mode 100644 index 000000000..15d10bc06 --- /dev/null +++ b/modules/nf-core/genmod/compound/tests/main.nf.test.snap @@ -0,0 +1,64 @@ +{ + "genmod_compound": { + "content": [ + "VcfFile [chromosomes=[MT], sampleCount=3, variantCount=22, phased=false, phasedAutodetect=false]", + { + "versions_genmod": [ + [ + "GENMOD_COMPOUND", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:47:53.481557902" + }, + "genmod_compound - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_compound.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GENMOD_COMPOUND", + "genmod", + "3.10.2" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_compound.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_genmod": [ + [ + "GENMOD_COMPOUND", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:14:51.229110934" + } +} \ No newline at end of file diff --git a/modules/nf-core/genmod/compound/tests/tags.yml b/modules/nf-core/genmod/compound/tests/tags.yml deleted file mode 100644 index 870b35e8b..000000000 --- a/modules/nf-core/genmod/compound/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -genmod/compound: - - modules/nf-core/genmod/compound/** diff --git a/modules/nf-core/genmod/models/environment.yml b/modules/nf-core/genmod/models/environment.yml index 227ee8920..6b91c71a0 100644 --- a/modules/nf-core/genmod/models/environment.yml +++ b/modules/nf-core/genmod/models/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::genmod=3.9 + - bioconda::genmod=3.10.2 + - conda-forge::python=3.11.14 diff --git a/modules/nf-core/genmod/models/main.nf b/modules/nf-core/genmod/models/main.nf index a869221e9..39a1c1a16 100644 --- a/modules/nf-core/genmod/models/main.nf +++ b/modules/nf-core/genmod/models/main.nf @@ -4,8 +4,8 @@ process GENMOD_MODELS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/genmod:3.9--pyhdfd78af_0': - 'biocontainers/genmod:3.9--pyhdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/31/31b331bee43c7ff070bdde5460a4102ba31c3bfb0ee0d70197001ff011036555/data' : + 'community.wave.seqera.io/library/genmod_python:31b2fba4d3b7ba6f' }" input: tuple val(meta), path(input_vcf), path (fam) @@ -13,7 +13,7 @@ process GENMOD_MODELS { output: tuple val(meta), path("*_models.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('genmod'), eval("genmod --version | sed 's/^.*genmod version: //'"), emit: versions_genmod, topic: versions when: task.ext.when == null || task.ext.when @@ -32,21 +32,11 @@ process GENMOD_MODELS { --processes ${task.cpus} \\ --outfile ${prefix}_models.vcf \\ $input_vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}_models.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/genmod/models/meta.yml b/modules/nf-core/genmod/models/meta.yml index a6249114a..5754d011b 100644 --- a/modules/nf-core/genmod/models/meta.yml +++ b/modules/nf-core/genmod/models/meta.yml @@ -22,16 +22,20 @@ input: type: file description: vcf file pattern: "*.{vcf}" + ontologies: [] - fam: type: file description: PED file with family information - - - reduced_penetrance: - type: file - description: file with gene ids that have reduced penetrance - pattern: "*.{tsv}" + ontologies: [] + - reduced_penetrance: + type: file + description: file with gene ids that have reduced penetrance + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -40,11 +44,28 @@ output: type: file description: Output VCF file pattern: "*.{vcf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_genmod: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/genmod/models/tests/main.nf.test b/modules/nf-core/genmod/models/tests/main.nf.test index 0b9a3ebd0..83fbd4093 100644 --- a/modules/nf-core/genmod/models/tests/main.nf.test +++ b/modules/nf-core/genmod/models/tests/main.nf.test @@ -27,9 +27,9 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.versions, path(process.out.vcf.get(0).get(1)).vcf.summary, - ).match() } + process.out.findAll { key, val -> key.startsWith("versions") }, + ).match() } ) } diff --git a/modules/nf-core/genmod/models/tests/main.nf.test.snap b/modules/nf-core/genmod/models/tests/main.nf.test.snap new file mode 100644 index 000000000..2184f631b --- /dev/null +++ b/modules/nf-core/genmod/models/tests/main.nf.test.snap @@ -0,0 +1,64 @@ +{ + "genmod_models - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_models.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GENMOD_MODELS", + "genmod", + "3.10.2" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_models.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_genmod": [ + [ + "GENMOD_MODELS", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:14:58.376387801" + }, + "genmod_models": { + "content": [ + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=57, phased=false, phasedAutodetect=false]", + { + "versions_genmod": [ + [ + "GENMOD_MODELS", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:47:59.960270364" + } +} \ No newline at end of file diff --git a/modules/nf-core/genmod/models/tests/tags.yml b/modules/nf-core/genmod/models/tests/tags.yml deleted file mode 100644 index 72b3b6bbd..000000000 --- a/modules/nf-core/genmod/models/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -genmod/models: - - modules/nf-core/genmod/models/** diff --git a/modules/nf-core/genmod/score/environment.yml b/modules/nf-core/genmod/score/environment.yml index 227ee8920..6b91c71a0 100644 --- a/modules/nf-core/genmod/score/environment.yml +++ b/modules/nf-core/genmod/score/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::genmod=3.9 + - bioconda::genmod=3.10.2 + - conda-forge::python=3.11.14 diff --git a/modules/nf-core/genmod/score/main.nf b/modules/nf-core/genmod/score/main.nf index 756fc7313..f5db31eab 100644 --- a/modules/nf-core/genmod/score/main.nf +++ b/modules/nf-core/genmod/score/main.nf @@ -4,8 +4,8 @@ process GENMOD_SCORE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/genmod:3.9--pyhdfd78af_0': - 'biocontainers/genmod:3.9--pyhdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/31/31b331bee43c7ff070bdde5460a4102ba31c3bfb0ee0d70197001ff011036555/data' : + 'community.wave.seqera.io/library/genmod_python:31b2fba4d3b7ba6f' }" input: tuple val(meta), path(input_vcf), path (fam) @@ -13,7 +13,7 @@ process GENMOD_SCORE { output: tuple val(meta), path("*_score.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('genmod'), eval("genmod --version | sed 's/^.*genmod version: //'"), emit: versions_genmod, topic: versions when: task.ext.when == null || task.ext.when @@ -31,21 +31,11 @@ process GENMOD_SCORE { $config_file \\ --outfile ${prefix}_score.vcf \\ $input_vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}_score.vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - genmod: \$(echo \$(genmod --version 2>&1) | sed 's/^.*genmod version: //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/genmod/score/meta.yml b/modules/nf-core/genmod/score/meta.yml index c5fe2e2ac..893b620d6 100644 --- a/modules/nf-core/genmod/score/meta.yml +++ b/modules/nf-core/genmod/score/meta.yml @@ -22,16 +22,19 @@ input: type: file description: vcf file pattern: "*.{vcf}" + ontologies: [] - fam: type: file description: PED file with family information - - - score_config: - type: file - description: rank model config file - pattern: "*.{ini}" + ontologies: [] + - score_config: + type: file + description: rank model config file + pattern: "*.{ini}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -40,11 +43,28 @@ output: type: file description: Output VCF file pattern: "*.{vcf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_genmod: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - genmod: + type: string + description: Name of the tool + - "genmod --version | sed 's/^.*genmod version: //'": + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/genmod/score/tests/main.nf.test b/modules/nf-core/genmod/score/tests/main.nf.test index 6181f63ae..710176292 100644 --- a/modules/nf-core/genmod/score/tests/main.nf.test +++ b/modules/nf-core/genmod/score/tests/main.nf.test @@ -27,9 +27,10 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.versions, path(process.out.vcf.get(0).get(1)).vcf.summary, - ).match() } + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.findAll { key, val -> key.startsWith("versions") }, + ).match() } ) } diff --git a/modules/nf-core/genmod/score/tests/main.nf.test.snap b/modules/nf-core/genmod/score/tests/main.nf.test.snap new file mode 100644 index 000000000..9923b99c4 --- /dev/null +++ b/modules/nf-core/genmod/score/tests/main.nf.test.snap @@ -0,0 +1,65 @@ +{ + "genmod_score": { + "content": [ + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=57, phased=false, phasedAutodetect=false]", + "50a04b1524fe1e21e49ebd9afdd0d91e", + { + "versions_genmod": [ + [ + "GENMOD_SCORE", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:46:03.729403607" + }, + "genmod_score - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_score.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GENMOD_SCORE", + "genmod", + "3.10.2" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_score.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_genmod": [ + [ + "GENMOD_SCORE", + "genmod", + "3.10.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.2" + }, + "timestamp": "2025-12-22T14:08:59.88453697" + } +} \ No newline at end of file diff --git a/modules/nf-core/genmod/score/tests/tags.yml b/modules/nf-core/genmod/score/tests/tags.yml deleted file mode 100644 index cef831ed3..000000000 --- a/modules/nf-core/genmod/score/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -genmod/score: - - modules/nf-core/genmod/score/** diff --git a/modules/nf-core/gens/preparecovandbaf/environment.yml b/modules/nf-core/gens/preparecovandbaf/environment.yml new file mode 100644 index 000000000..47d573b0a --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/environment.yml @@ -0,0 +1,11 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.23 + - conda-forge::pip=26.0.1 + - conda-forge::python=3.14.3 + - pip: + - gens-input-data-tools==2.0.1 diff --git a/modules/nf-core/gens/preparecovandbaf/main.nf b/modules/nf-core/gens/preparecovandbaf/main.nf new file mode 100644 index 000000000..6d4e9a0da --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/main.nf @@ -0,0 +1,46 @@ +process PREPARECOVANDBAF { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/67/67abc0d3d1eaaeaff3eafb36babecf56b5912c2e7b0c5100a9f32eda1c82cb30/data': + 'community.wave.seqera.io/library/htslib_python_pip_gens-input-data-tools:8fd1a0ecd4a60110' }" + + input: + tuple val(meta), path(read_counts), path(gvcf), path(gvcf_tbi) + path baf_positions + + output: + tuple val(meta), path("*.cov.bed.gz") , emit: cov_gz + tuple val(meta), path("*.cov.bed.gz.tbi") , emit: cov_tbi + tuple val(meta), path("*.baf.bed.gz") , emit: baf_gz + tuple val(meta), path("*.baf.bed.gz.tbi") , emit: baf_tbi + tuple val("${task.process}"), val('preparecovandbaf'), eval("generate_cov_and_baf --version"), topic: versions, emit: versions_preparecovandbaf + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + generate_cov_and_baf \\ + --coverage $read_counts \\ + --gvcf $gvcf \\ + --label $prefix \\ + --baf_positions $baf_positions \\ + --bgzip_tabix_output \\ + $args \\ + --outdir . + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}.cov.bed.gz + touch ${prefix}.cov.bed.gz.tbi + echo "" | gzip > ${prefix}.baf.bed.gz + touch ${prefix}.baf.bed.gz.tbi + """ +} diff --git a/modules/nf-core/gens/preparecovandbaf/meta.yml b/modules/nf-core/gens/preparecovandbaf/meta.yml new file mode 100644 index 000000000..7de5e1159 --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/meta.yml @@ -0,0 +1,110 @@ +name: "preparecovandbaf" +description: Tools for preparing inputs for visualization in Gens +keywords: + - gens + - preparecovandbaf + - preprocessing + - genomics + - CNV +tools: + - "gens": + description: "Scripts for preparing input data to Gens" + homepage: "https://github.com/SMD-Bioinformatics-Lund/Prepare-Gens-input-data" + documentation: "https://github.com/SMD-Bioinformatics-Lund/Prepare-Gens-input-data/README.md" + tool_dev_url: "https://github.com/SMD-Bioinformatics-Lund/Prepare-Gens-input-data" + licence: [MIT] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - read_counts: + type: file + description: Binned coverage calculations from GATK + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - gvcf: + type: file + description: GVCF. It is used to calculate B-allele frequencies at the sites specified in baf_positions. It can be generated using any SNV-caller. + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - gvcf_tbi: + type: file + description: GVCF tabix index + pattern: "*.vcf.gz.tbi" + ontologies: [] + - baf_positions: + type: file + description: Sites to sample for BAF calculations + pattern: "*.{tsv,tsv.gz}" + + ontologies: + - edam: http://edamontology.org/format_3475 # TSV +output: + cov_gz: + - - meta: + type: map + description: | + Groovy Map containing sample information + - "*.cov.bed.gz": + type: file + description: Coverage bed (bgzipped) + + cov_tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + - "*.cov.bed.gz.tbi": + type: file + description: Tabix index for coverage bed + + baf_gz: + - - meta: + type: map + description: | + Groovy Map containing sample information + - "*.baf.bed.gz": + type: file + description: BAF bed (bgzipped) + + baf_tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + - "*.baf.bed.gz.tbi": + type: file + description: Tabix index for BAF bed + + versions_preparecovandbaf: + - - "${task.process}": + type: string + description: The process the versions were collected from + - "preparecovandbaf": + type: string + description: The tool name + - "generate_cov_and_baf --version": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - "${task.process}": + type: string + description: The process the versions were collected from + - "preparecovandbaf": + type: string + description: The tool name + - "generate_cov_and_baf --version": + type: eval + description: The expression used to obtain the tool version +authors: + - "@jakob37" +maintainers: + - "@jakob37" diff --git a/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test b/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test new file mode 100644 index 000000000..f466ecb95 --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test @@ -0,0 +1,66 @@ +nextflow_process { + + name "Test Process PREPARECOVANDBAF" + script "modules/nf-core/gens/preparecovandbaf/main.nf" + process "PREPARECOVANDBAF" + + tag "modules" + tag "modules_nfcore" + tag "gens" + tag "gens/preparecovandbaf" + + test("gens_preparecovandbaf") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/hg002_chr20_90000_to_100000.standardizedCR.tsv", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/hg002_chr20_90000_to_100000.dnascope.gvcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/hg002_chr20_90000_to_100000.dnascope.gvcf.gz.tbi", checkIfExists: true), + ] + input[1] = [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/tab/gnomad_hg38_chr20_90000_to_100000.0.05.txt.gz", checkIfExists: true), + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("gens_preparecovandbaf - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/gatk/hg002_chr20_90000_to_100000.standardizedCR.tsv", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/hg002_chr20_90000_to_100000.dnascope.gvcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/hg002_chr20_90000_to_100000.dnascope.gvcf.gz.tbi", checkIfExists: true), + ] + input[1] = [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/tab/gnomad_hg38_chr20_90000_to_100000.0.05.txt.gz", checkIfExists: true), + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test.snap b/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test.snap new file mode 100644 index 000000000..f027761d3 --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/tests/main.nf.test.snap @@ -0,0 +1,180 @@ +{ + "gens_preparecovandbaf - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "PREPARECOVANDBAF", + "preparecovandbaf", + "1.1.5" + ] + ], + "baf_gz": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "baf_tbi": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cov_gz": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "cov_tbi": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_preparecovandbaf": [ + [ + "PREPARECOVANDBAF", + "preparecovandbaf", + "1.1.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-26T12:47:53.193429367" + }, + "gens_preparecovandbaf": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz:md5,2df1734048f1bab141050822a426145e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz.tbi:md5,66025dc44413e9e17c8e11af09e06dbe" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz:md5,ae86e22390df1ba20a931b70be92079f" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz.tbi:md5,442c8518dd2f818757a10ca4f06c1b6c" + ] + ], + "4": [ + [ + "PREPARECOVANDBAF", + "preparecovandbaf", + "1.1.5" + ] + ], + "baf_gz": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz:md5,ae86e22390df1ba20a931b70be92079f" + ] + ], + "baf_tbi": [ + [ + { + "id": "test" + }, + "test.baf.bed.gz.tbi:md5,442c8518dd2f818757a10ca4f06c1b6c" + ] + ], + "cov_gz": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz:md5,2df1734048f1bab141050822a426145e" + ] + ], + "cov_tbi": [ + [ + { + "id": "test" + }, + "test.cov.bed.gz.tbi:md5,66025dc44413e9e17c8e11af09e06dbe" + ] + ], + "versions_preparecovandbaf": [ + [ + "PREPARECOVANDBAF", + "preparecovandbaf", + "1.1.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-26T12:47:42.547489104" + } +} \ No newline at end of file diff --git a/modules/nf-core/gens/preparecovandbaf/tests/tags.yml b/modules/nf-core/gens/preparecovandbaf/tests/tags.yml new file mode 100644 index 000000000..2c5ae0497 --- /dev/null +++ b/modules/nf-core/gens/preparecovandbaf/tests/tags.yml @@ -0,0 +1,2 @@ +gens/preparecovandbaf: + - modules/nf-core/gens/preparecovandbaf/** diff --git a/modules/nf-core/glnexus/environment.yml b/modules/nf-core/glnexus/environment.yml index 9190508a9..c9e4703dc 100644 --- a/modules/nf-core/glnexus/environment.yml +++ b/modules/nf-core/glnexus/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: + - bioconda::bcftools=1.21 - bioconda::glnexus=1.4.1 diff --git a/modules/nf-core/glnexus/main.nf b/modules/nf-core/glnexus/main.nf index 191f04995..65180995e 100644 --- a/modules/nf-core/glnexus/main.nf +++ b/modules/nf-core/glnexus/main.nf @@ -4,16 +4,16 @@ process GLNEXUS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glnexus:1.4.1--h40d77a6_0' : - 'biocontainers/glnexus:1.4.1--h40d77a6_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/6c/6cf504ad8e4ebda286609fa3c1a5f9af68dbca9ec06bb4428e219e84754bd140/data' : + 'community.wave.seqera.io/library/bcftools_glnexus:cf380f1a6410f606' }" input: - tuple val(meta), path(gvcfs) + tuple val(meta), path(gvcfs), path(custom_config) tuple val(meta2), path(bed) output: tuple val(meta), path("*.bcf"), emit: bcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('glnexus'), eval("glnexus_cli 2>&1 | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+'"), topic: versions, emit: versions_glnexus when: task.ext.when == null || task.ext.when @@ -24,7 +24,7 @@ process GLNEXUS { def regions = bed ? "--bed ${bed}" : "" // Make list of GVCFs to merge - def input = gvcfs.collect { it.toString() } + def input = gvcfs.collect {vcf -> vcf.toString() } def avail_mem = 3 if (!task.memory) { log.info '[Glnexus] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' @@ -39,21 +39,11 @@ process GLNEXUS { $args \\ ${input.join(' ')} \\ > ${prefix}.bcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - glnexus: \$( echo \$(glnexus_cli 2>&1) | head -n 1 | sed 's/^.*release v//; s/ .*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.bcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - glnexus: \$( echo \$(glnexus_cli 2>&1) | head -n 1 | sed 's/^.*release v//; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/glnexus/meta.yml b/modules/nf-core/glnexus/meta.yml index 8f18bf3f8..cacfa5c90 100644 --- a/modules/nf-core/glnexus/meta.yml +++ b/modules/nf-core/glnexus/meta.yml @@ -23,6 +23,12 @@ input: type: list description: Input genomic vcf files pattern: "*.{gvcf,gvcf.gz,g.vcf,g.vcf.gz}" + - custom_config: + type: file + description: Custom YML config for additional profiles + pattern: "*.{yml,yaml}" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML - - meta2: type: map description: | @@ -33,20 +39,38 @@ input: description: Input BED file pattern: "*.bed" output: - - bcf: - - meta: - type: file - description: merged BCF file - pattern: "*.bcf" + bcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] - "*.bcf": type: file description: merged BCF file pattern: "*.bcf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_glnexus: + - - ${task.process}: + type: string + description: The name of the process + - glnexus: + type: string + description: The name of the tool + - glnexus_cli 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - glnexus: + type: string + description: The name of the tool + - glnexus_cli 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/glnexus/tests/main.nf.test b/modules/nf-core/glnexus/tests/main.nf.test new file mode 100644 index 000000000..647373559 --- /dev/null +++ b/modules/nf-core/glnexus/tests/main.nf.test @@ -0,0 +1,126 @@ +nextflow_process { + + name "Test Process GLNEXUS" + script "../main.nf" + process "GLNEXUS" + + tag "modules" + tag "modules_nfcore" + tag "glnexus" + + test("vcfs, []") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz', checkIfExists: true), + ], + [] + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcfs, [], custom_config") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz', checkIfExists: true), + ], + file(params.modules_testdata_base_path + '/delete_me/glnexus/gatk.yml', checkIfExists: true) + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcfs, bed") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz', checkIfExists: true), + ], + [] + ]) + input[1] = [ + [ id:'region' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcfs, bed - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test2.genome.vcf.gz', checkIfExists: true), + ], + [] + ]) + input[1] = [ + [ id:'region' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true), + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } +} diff --git a/modules/nf-core/glnexus/tests/main.nf.test.snap b/modules/nf-core/glnexus/tests/main.nf.test.snap new file mode 100644 index 000000000..00426dd67 --- /dev/null +++ b/modules/nf-core/glnexus/tests/main.nf.test.snap @@ -0,0 +1,166 @@ +{ + "vcfs, bed - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ], + "bcf": [ + [ + { + "id": "test" + }, + "test.bcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_glnexus": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-14T22:43:16.499731323" + }, + "vcfs, [], custom_config": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "1": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ], + "bcf": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "versions_glnexus": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-14T22:39:47.593781473" + }, + "vcfs, bed": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "1": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ], + "bcf": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "versions_glnexus": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-14T22:41:26.083883984" + }, + "vcfs, []": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "1": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ], + "bcf": [ + [ + { + "id": "test" + }, + "test.bcf:md5,62b2cea9c1b92ac63645cb031eea46fc" + ] + ], + "versions_glnexus": [ + [ + "GLNEXUS", + "glnexus", + "1.4.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-14T22:36:50.552668413" + } +} \ No newline at end of file diff --git a/modules/nf-core/haplocheck/main.nf b/modules/nf-core/haplocheck/main.nf deleted file mode 100644 index 0d26c449e..000000000 --- a/modules/nf-core/haplocheck/main.nf +++ /dev/null @@ -1,44 +0,0 @@ -process HAPLOCHECK { - tag "$meta.id" - label 'process_low' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/haplocheck:1.3.3--h4a94de4_0': - 'biocontainers/haplocheck:1.3.3--h4a94de4_0' }" - - input: - tuple val(meta), path(vcf) - - output: - tuple val(meta), path("*.txt") , emit: txt - tuple val(meta), path("*.html"), emit: html - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - """ - haplocheck --raw --out $prefix $vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplocheck: \$(echo \$(haplocheck --version 2>&1) | sed 's/.*\\([0-9].[0-9].[0-9]\\).*/\\1/' ) - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.raw.txt - touch ${prefix}.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplocheck: \$(echo \$(haplocheck --version 2>&1) | sed 's/.*\\([0-9].[0-9].[0-9]\\).*/\\1/' ) - END_VERSIONS - """ -} diff --git a/modules/nf-core/haplocheck/meta.yml b/modules/nf-core/haplocheck/meta.yml deleted file mode 100644 index 25e6127a7..000000000 --- a/modules/nf-core/haplocheck/meta.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: "haplocheck" -description: | - Haplocheck detects contamination patterns in mtDNA AND WGS sequencing studies by analyzing - the mitochondrial DNA. Haplocheck also works as a proxy tool for nDNA studies and provides - users a graphical report to investigate the contamination further. Internally, it uses the - Haplogrep tool, that supports rCRS and RSRS mitochondrial versions. -keywords: - - mitochondrial - - mtDNA - - contamination -tools: - - "haplocheck": - description: "Detects in-sample contamination in mtDNA or WGS sequencing studies - by analyzing the mitochondrial content." - homepage: "https://github.com/genepi/haplocheck" - documentation: "https://github.com/genepi/haplocheck" - tool_dev_url: "https://github.com/genepi/haplocheck" - doi: 10.1101/gr.256545.119 - licence: ["MIT"] - identifier: biotools:haplocheck -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - vcf: - type: file - description: VCF file - pattern: "*.{vcf.gz}" -output: - - txt: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.txt": - type: file - description: Raw report in txt format - pattern: "*.{txt}" - - html: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.html": - type: file - description: Haplocheck HTML report - pattern: "*.{html}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@lmtani" -maintainers: - - "@lmtani" diff --git a/modules/nf-core/haplocheck/tests/main.nf.test b/modules/nf-core/haplocheck/tests/main.nf.test deleted file mode 100644 index 8957d02e2..000000000 --- a/modules/nf-core/haplocheck/tests/main.nf.test +++ /dev/null @@ -1,56 +0,0 @@ - -nextflow_process { - - name "Test Process HAPLOCHECK" - script "../main.nf" - process "HAPLOCHECK" - - tag "modules" - tag "modules_nfcore" - tag "haplocheck" - - test("test-haplocheck") { - - when { - process { - """ - input[0] = [ - [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_chrM.vcf.gz', checkIfExists: true) - ] - - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("test-haplocheck-stub") { - options '-stub' - when { - process { - """ - input[0] = [ - [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_chrM.vcf.gz', checkIfExists: true) - ] - - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - -} diff --git a/modules/nf-core/haplocheck/tests/main.nf.test.snap b/modules/nf-core/haplocheck/tests/main.nf.test.snap deleted file mode 100644 index abe1eab56..000000000 --- a/modules/nf-core/haplocheck/tests/main.nf.test.snap +++ /dev/null @@ -1,100 +0,0 @@ -{ - "test-haplocheck-stub": { - "content": [ - { - "0": [ - [ - { - "id": "test" - }, - "test.raw.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test" - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - "versions.yml:md5,ff75b052ef552a4c9cecf3f60403af9f" - ], - "html": [ - [ - { - "id": "test" - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "txt": [ - [ - { - "id": "test" - }, - "test.raw.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,ff75b052ef552a4c9cecf3f60403af9f" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-02T13:41:40.703528" - }, - "test-haplocheck": { - "content": [ - { - "0": [ - [ - { - "id": "test" - }, - "test.raw.txt:md5,69f4e5b28a59b97fc19eb8e8b650d9d5" - ] - ], - "1": [ - [ - { - "id": "test" - }, - "test.html:md5,59d69052c86edff0301816956eaf4d5f" - ] - ], - "2": [ - "versions.yml:md5,ff75b052ef552a4c9cecf3f60403af9f" - ], - "html": [ - [ - { - "id": "test" - }, - "test.html:md5,59d69052c86edff0301816956eaf4d5f" - ] - ], - "txt": [ - [ - { - "id": "test" - }, - "test.raw.txt:md5,69f4e5b28a59b97fc19eb8e8b650d9d5" - ] - ], - "versions": [ - "versions.yml:md5,ff75b052ef552a4c9cecf3f60403af9f" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-02T13:43:05.761086" - } -} \ No newline at end of file diff --git a/modules/nf-core/haplogrep3/classify/main.nf b/modules/nf-core/haplogrep3/classify/main.nf deleted file mode 100644 index 056b0635f..000000000 --- a/modules/nf-core/haplogrep3/classify/main.nf +++ /dev/null @@ -1,47 +0,0 @@ -process HAPLOGREP3_CLASSIFY { - tag "$meta.id" - label 'process_single' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/haplogrep3:3.2.2--hdfd78af_0': - 'biocontainers/haplogrep3:3.2.2--hdfd78af_0' }" - - input: - tuple val(meta), path(inputfile) - - output: - tuple val(meta), path("*.txt"), emit: txt - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - """ - haplogrep3 \\ - classify \\ - $args \\ - --in $inputfile \\ - --out ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplogrep3: \$(echo \$(haplogrep3 2>&1) | (sed '2!d') | (sed 's/Haplogrep 3 //')) - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplogrep3: \$(echo \$(haplogrep3 2>&1) | (sed '2!d') | (sed 's/Haplogrep 3 //')) - END_VERSIONS - """ - -} diff --git a/modules/nf-core/haplogrep3/classify/meta.yml b/modules/nf-core/haplogrep3/classify/meta.yml deleted file mode 100644 index 4c5c925d2..000000000 --- a/modules/nf-core/haplogrep3/classify/meta.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: "haplogrep3_classify" -description: classification into haplogroups -keywords: - - haplogroups - - classify - - mtDNA -tools: - - "haplogrep3": - description: "A tool for mtDNA haplogroup classification." - homepage: "https://github.com/genepi/haplogrep3" - documentation: "https://github.com/genepi/haplogrep3" - tool_dev_url: "https://github.com/genepi/haplogrep3" - licence: ["MIT"] - identifier: "" -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - inputfile: - type: file - description: valid options are hsd, vcf, or fasta files - pattern: "*.{vcf,vcf.gz,fasta,hsd}" -output: - - txt: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.txt": - type: file - description: text file with classification information - pattern: "*.{txt}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@lucpen" -maintainers: - - "@lucpen" - - "@ramprasadn" diff --git a/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap b/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap deleted file mode 100644 index d1a276d25..000000000 --- a/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap +++ /dev/null @@ -1,72 +0,0 @@ -{ - "test-haplogrep3-classify-stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" - ], - "txt": [ - [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" - }, - "timestamp": "2025-01-28T15:34:35.106097277" - }, - "test-haplogrep3-classify": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,fb242df629aa6168371d1d742f0fb179" - ] - ], - "1": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" - ], - "txt": [ - [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,fb242df629aa6168371d1d742f0fb179" - ] - ], - "versions": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" - }, - "timestamp": "2025-01-28T15:36:19.954363253" - } -} \ No newline at end of file diff --git a/modules/nf-core/haplogrep3/classify/tests/nextflow.config b/modules/nf-core/haplogrep3/classify/tests/nextflow.config deleted file mode 100644 index 7f57266a1..000000000 --- a/modules/nf-core/haplogrep3/classify/tests/nextflow.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: HAPLOGREP3_CLASSIFY { - ext.args = '--tree phylotree-rsrs@17.1' - } -} diff --git a/modules/nf-core/hisat2/build/environment.yml b/modules/nf-core/hisat2/build/environment.yml new file mode 100644 index 000000000..cbf12eadc --- /dev/null +++ b/modules/nf-core/hisat2/build/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::hisat2=2.2.1 + - bioconda::samtools=1.20 diff --git a/modules/nf-core/hisat2/build/main.nf b/modules/nf-core/hisat2/build/main.nf new file mode 100644 index 000000000..906d36fe5 --- /dev/null +++ b/modules/nf-core/hisat2/build/main.nf @@ -0,0 +1,64 @@ +process HISAT2_BUILD { + tag "${fasta}" + label 'process_high' + label 'process_high_memory' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d2/d2ec9b73c6b92e99334c6500b1b622edaac316315ac1708f0b425df3131d0a83/data' : + 'community.wave.seqera.io/library/hisat2_samtools:6be64e12472a7b75' }" + + input: + tuple val(meta), path(fasta) + tuple val(meta2), path(gtf) + tuple val(meta3), path(splicesites) + + output: + tuple val(meta), path("hisat2"), emit: index + tuple val("${task.process}"), val('hisat2'), eval("hisat2 --version | sed -n 's/.*version \\([^ ]*\\).*/\\1/p'"), emit: versions_hisat2, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def avail_mem = 0 + if (!task.memory) { + log.info("[HISAT2 index build] Available memory not known - defaulting to 0. Specify process memory requirements to change this.") + } + else { + log.info("[HISAT2 index build] Available memory: ${task.memory}") + avail_mem = task.memory.toGiga() + } + + def ss = '' + def exon = '' + def extract_exons = '' + def hisat2_build_memory = params.hisat2_build_memory ? (params.hisat2_build_memory as MemoryUnit).toGiga() : 0 + if (avail_mem >= hisat2_build_memory) { + log.info("[HISAT2 index build] At least ${hisat2_build_memory} GB available, so using splice sites and exons to build HISAT2 index") + extract_exons = gtf ? "hisat2_extract_exons.py ${gtf} > ${gtf.baseName}.exons.txt" : "" + ss = splicesites ? "--ss ${splicesites}" : "" + exon = gtf ? "--exon ${gtf.baseName}.exons.txt" : "" + } + else { + log.info("[HISAT2 index build] Less than ${hisat2_build_memory} GB available, so NOT using splice sites and exons to build HISAT2 index.") + log.info("[HISAT2 index build] Use --hisat2_build_memory [small number] to skip this check.") + } + """ + mkdir hisat2 + ${extract_exons} + hisat2-build \\ + -p ${task.cpus} \\ + ${ss} \\ + ${exon} \\ + ${args} \\ + ${fasta} \\ + hisat2/${fasta.baseName} + """ + + stub: + """ + mkdir hisat2 + """ +} diff --git a/modules/nf-core/hisat2/build/meta.yml b/modules/nf-core/hisat2/build/meta.yml new file mode 100644 index 000000000..805804910 --- /dev/null +++ b/modules/nf-core/hisat2/build/meta.yml @@ -0,0 +1,88 @@ +name: hisat2_build +description: Builds HISAT2 index for reference genome +keywords: + - build + - index + - fasta + - genome + - reference +tools: + - hisat2: + description: HISAT2 is a fast and sensitive alignment program for mapping next-generation + sequencing reads (both DNA and RNA) to a population of human genomes as well + as to a single reference genome. + homepage: https://daehwankimlab.github.io/hisat2/ + documentation: https://daehwankimlab.github.io/hisat2/manual/ + doi: "10.1038/s41587-019-0201-4" + licence: ["MIT"] + identifier: biotools:hisat2 +input: + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Reference fasta file + pattern: "*.{fa,fasta,fna}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - gtf: + type: file + description: Reference gtf annotation file + pattern: "*.{gtf}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - splicesites: + type: file + description: Splices sites in gtf file + pattern: "*.{txt}" + ontologies: [] +output: + index: + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - hisat2: + type: file + description: HISAT2 genome index file + pattern: "*.ht2" + ontologies: [] + versions_hisat2: + - - ${task.process}: + type: string + description: The name of the process + - hisat2: + type: string + description: The name of the tool + - "hisat2 --version | sed -n 's/.*version \\([^ ]*\\).*/\\1/p'": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - hisat2: + type: string + description: The name of the tool + - "hisat2 --version | sed -n 's/.*version \\([^ ]*\\).*/\\1/p'": + type: eval + description: The expression to obtain the version of the tool + +authors: + - "@ntoda03" +maintainers: + - "@ntoda03" diff --git a/modules/nf-core/hisat2/build/tests/main.nf.test b/modules/nf-core/hisat2/build/tests/main.nf.test new file mode 100644 index 000000000..9bee5f676 --- /dev/null +++ b/modules/nf-core/hisat2/build/tests/main.nf.test @@ -0,0 +1,104 @@ +nextflow_process { + + name "Test Process HISAT2_BUILD" + script "../main.nf" + process "HISAT2_BUILD" + tag "modules" + tag "modules_nfcore" + tag "hisat2" + tag "hisat2/build" + tag "hisat2/extractsplicesites" + + test("Should run without failures") { + + setup { + run("HISAT2_EXTRACTSPLICESITES") { + script "../../extractsplicesites/main.nf" + process { + """ + input[0] = Channel.of([ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[1] = Channel.of([ [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) + ]) + input[2] = HISAT2_EXTRACTSPLICESITES.out.txt + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("Should run without failures - stub") { + + options "-stub" + + setup { + run("HISAT2_EXTRACTSPLICESITES") { + script "../../extractsplicesites/main.nf" + process { + """ + input[0] = Channel.of([ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + outdir = "$outputDir" + } + + process { + """ + input[0] = Channel.of([ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[1] = Channel.of([ [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) + ]) + input[2] = HISAT2_EXTRACTSPLICESITES.out.txt + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/hisat2/build/tests/main.nf.test.snap b/modules/nf-core/hisat2/build/tests/main.nf.test.snap new file mode 100644 index 000000000..99b33cb2c --- /dev/null +++ b/modules/nf-core/hisat2/build/tests/main.nf.test.snap @@ -0,0 +1,54 @@ +{ + "Should run without failures - stub": { + "content": [ + [ + [ + { + "id": "genome" + }, + "hisat2" + ] + ], + { + "versions_hisat2": [ + [ + "HISAT2_BUILD", + "hisat2", + "2.2.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-02T15:53:37.611420605" + }, + "Should run without failures": { + "content": [ + [ + [ + { + "id": "genome" + }, + "hisat2" + ] + ], + { + "versions_hisat2": [ + [ + "HISAT2_BUILD", + "hisat2", + "2.2.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-02T15:53:31.34596606" + } +} \ No newline at end of file diff --git a/modules/nf-core/hmtnote/annotate/hmtnote-annotate.diff b/modules/nf-core/hmtnote/annotate/hmtnote-annotate.diff deleted file mode 100644 index 745e98637..000000000 --- a/modules/nf-core/hmtnote/annotate/hmtnote-annotate.diff +++ /dev/null @@ -1,51 +0,0 @@ -Changes in component 'nf-core/hmtnote/annotate' -'modules/nf-core/hmtnote/annotate/environment.yml' is unchanged -'modules/nf-core/hmtnote/annotate/meta.yml' is unchanged -Changes in 'hmtnote/annotate/main.nf': ---- modules/nf-core/hmtnote/annotate/main.nf -+++ modules/nf-core/hmtnote/annotate/main.nf -@@ -11,7 +11,7 @@ - tuple val(meta), path(vcf) - - output: -- tuple val(meta), path("*_annotated.vcf"), emit: vcf -+ tuple val(meta), path("${prefix}.vcf"), emit: vcf - path "versions.yml" , emit: versions - - when: -@@ -19,27 +19,27 @@ - - script: - def args = task.ext.args ?: '' -- def prefix = task.ext.prefix ?: "${meta.id}" -+ prefix = task.ext.prefix ?: "${meta.id}" - - """ - hmtnote \\ - annotate \\ - $vcf \\ -- ${prefix}_annotated.vcf \\ -+ ${prefix}.vcf \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": -- hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' )) -+ hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' ) - END_VERSIONS - """ - stub: -- def prefix = task.ext.prefix ?: "${meta.id}" -+ prefix = task.ext.prefix ?: "${meta.id}" - """ -- touch ${prefix}_annotated.vcf -+ touch ${prefix}.vcf - cat <<-END_VERSIONS > versions.yml - "${task.process}": -- hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' )) -+ hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' ) - END_VERSIONS - """ - } - -************************************************************ diff --git a/modules/nf-core/hmtnote/annotate/main.nf b/modules/nf-core/hmtnote/annotate/main.nf deleted file mode 100644 index a894d0073..000000000 --- a/modules/nf-core/hmtnote/annotate/main.nf +++ /dev/null @@ -1,45 +0,0 @@ -process HMTNOTE_ANNOTATE { - tag "$meta.id" - label 'process_low' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/hmtnote:0.7.2--pyhdfd78af_1': - 'biocontainers/hmtnote:0.7.2--pyhdfd78af_1' }" - - input: - tuple val(meta), path(vcf) - - output: - tuple val(meta), path("${prefix}.vcf"), emit: vcf - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - - """ - hmtnote \\ - annotate \\ - $vcf \\ - ${prefix}.vcf \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' ) - END_VERSIONS - """ - stub: - prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.vcf - cat <<-END_VERSIONS > versions.yml - "${task.process}": - hmtnote: \$(echo \$(hmtnote --version 2>&1) | sed 's/^.*hmtnote, version //; s/Using.*\$//' ) - END_VERSIONS - """ -} diff --git a/modules/nf-core/hmtnote/annotate/meta.yml b/modules/nf-core/hmtnote/annotate/meta.yml deleted file mode 100644 index 661d5cde0..000000000 --- a/modules/nf-core/hmtnote/annotate/meta.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: hmtnote_annotate -description: Human mitochondrial variants annotation using HmtVar. Contains .plk file - with annotation, so can be run offline -keywords: - - hmtnote - - mitochondria - - annotation -tools: - - hmtnote: - description: Human mitochondrial variants annotation using HmtVar. - homepage: https://github.com/robertopreste/HmtNote - documentation: https://hmtnote.readthedocs.io/en/latest/usage.html - doi: "10.1101/600619" - licence: ["MIT"] - identifier: "" -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - - vcf: - type: file - description: vcf file - pattern: "*.vcf" -output: - - vcf: - - meta: - type: map - description: | - Groovy Map containing sample information - - "*_annotated.vcf": - type: file - description: annotated vcf - pattern: "*_annotated.vcf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@sysbiocoder" -maintainers: - - "@sysbiocoder" diff --git a/modules/nf-core/last/lastdb/environment.yml b/modules/nf-core/last/lastdb/environment.yml new file mode 100644 index 000000000..f8d361e0b --- /dev/null +++ b/modules/nf-core/last/lastdb/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::last=1611 diff --git a/modules/nf-core/last/lastdb/main.nf b/modules/nf-core/last/lastdb/main.nf new file mode 100644 index 000000000..8f5b5c27e --- /dev/null +++ b/modules/nf-core/last/lastdb/main.nf @@ -0,0 +1,46 @@ +process LAST_LASTDB { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/0d/0d27a2649f1291ff817dc8f73357ffac206424cd972d3855421e4258acc600f7/data' + : 'community.wave.seqera.io/library/last:1611--e1193b3871fa0975'}" + + input: + tuple val(meta), path(fastx) + + output: + tuple val(meta), path("lastdb"), emit: index + // last-dotplot has no --version option so let's use lastal from the same suite + tuple val("${task.process}"), val('last'), eval("lastal --version | sed 's/lastal //'"), emit: versions_last, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir lastdb + lastdb \\ + $args \\ + -P $task.cpus \\ + lastdb/${prefix} \\ + $fastx + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir lastdb + touch lastdb/${prefix}.bck + touch lastdb/${prefix}.des + touch lastdb/${prefix}.prj + touch lastdb/${prefix}.sds + touch lastdb/${prefix}.ssp + touch lastdb/${prefix}.suf + touch lastdb/${prefix}.tis + + """ +} diff --git a/modules/nf-core/last/lastdb/meta.yml b/modules/nf-core/last/lastdb/meta.yml new file mode 100644 index 000000000..4c041d211 --- /dev/null +++ b/modules/nf-core/last/lastdb/meta.yml @@ -0,0 +1,65 @@ +cd# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "last_lastdb" +description: Prepare sequences for subsequent alignment with lastal. +keywords: + - LAST + - index + - fasta + - fastq +tools: + - "last": + description: "LAST finds & aligns related regions of sequences." + homepage: "https://gitlab.com/mcfrith/last" + documentation: "https://gitlab.com/mcfrith/last/-/blob/main/doc/lastdb.rst" + tool_dev_url: "https://gitlab.com/mcfrith/last" + licence: ["GPL v3-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - fastx: + type: file + description: > + Sequence file in FASTA or FASTQ format. May be compressed with gzip. + pattern: "*.{fasta,fasta.gz,fastq,fastq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ +output: + index: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - lastdb: + type: directory + description: directory containing the files of the LAST index + pattern: "lastdb/" + versions_last: + - - "${task.process}": + type: string + description: The name of the process + - last: + type: string + description: The name of the tool + - "lastal --version | sed 's/lastal //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - "${task.process}": + type: string + description: The name of the process + - last: + type: string + description: The name of the tool + - "lastal --version | sed 's/lastal //'": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@charles-plessy" +maintainers: + - "@charles-plessy" diff --git a/modules/nf-core/last/lastdb/tests/main.nf.test b/modules/nf-core/last/lastdb/tests/main.nf.test new file mode 100644 index 000000000..1d5d40329 --- /dev/null +++ b/modules/nf-core/last/lastdb/tests/main.nf.test @@ -0,0 +1,80 @@ +nextflow_process { + + name "Test Process LAST_LASTDB" + script "../main.nf" + process "LAST_LASTDB" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "last" + tag "last/lastdb" + + test("sarscov2 - fasta") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fastq gzipped") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fasta stub") { + + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/last/lastdb/tests/main.nf.test.snap b/modules/nf-core/last/lastdb/tests/main.nf.test.snap new file mode 100644 index 000000000..e54777878 --- /dev/null +++ b/modules/nf-core/last/lastdb/tests/main.nf.test.snap @@ -0,0 +1,173 @@ +{ + "sarscov2 - fasta stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.des:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.prj:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sds:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.ssp:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.suf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tis:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.des:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.prj:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sds:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.ssp:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.suf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tis:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_last": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-13T10:40:55.31640271" + }, + "sarscov2 - fastq gzipped": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,05b14d8ac418b3193d9cc921086cea05", + "test.des:md5,26ab49015cc572172b9efa50fc5190bc", + "test.prj:md5,a90d0d376caa024349b452d3d6d51676", + "test.sds:md5,d3deb4c985081c9f5ad6684d405bd20b", + "test.ssp:md5,5c17139a9022b0cb97f007146fa1c6da", + "test.suf:md5,9ac359afa86a8964d81a87a1d4f05ef0", + "test.tis:md5,d57a3a5f7e3e036807356c15bd3aad97" + ] + ] + ], + "1": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,05b14d8ac418b3193d9cc921086cea05", + "test.des:md5,26ab49015cc572172b9efa50fc5190bc", + "test.prj:md5,a90d0d376caa024349b452d3d6d51676", + "test.sds:md5,d3deb4c985081c9f5ad6684d405bd20b", + "test.ssp:md5,5c17139a9022b0cb97f007146fa1c6da", + "test.suf:md5,9ac359afa86a8964d81a87a1d4f05ef0", + "test.tis:md5,d57a3a5f7e3e036807356c15bd3aad97" + ] + ] + ], + "versions_last": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-13T10:40:49.204117613" + }, + "sarscov2 - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,157526d333b88523cb15ac4efe00738f", + "test.des:md5,3a9ea6d336e113a74d7fdca5e7b623fc", + "test.prj:md5,bb7b997633125f0310d02114b8531449", + "test.sds:md5,e7729db27ac7a5a109c9d48cfcdc9015", + "test.ssp:md5,53524efdea3d8989201419a29e81ec1f", + "test.suf:md5,ef7482260705bb8146acbbbdce6c0068", + "test.tis:md5,b7c40f06b1309dc6f37849eeb86dfd22" + ] + ] + ], + "1": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "test.bck:md5,157526d333b88523cb15ac4efe00738f", + "test.des:md5,3a9ea6d336e113a74d7fdca5e7b623fc", + "test.prj:md5,bb7b997633125f0310d02114b8531449", + "test.sds:md5,e7729db27ac7a5a109c9d48cfcdc9015", + "test.ssp:md5,53524efdea3d8989201419a29e81ec1f", + "test.suf:md5,ef7482260705bb8146acbbbdce6c0068", + "test.tis:md5,b7c40f06b1309dc6f37849eeb86dfd22" + ] + ] + ], + "versions_last": [ + [ + "LAST_LASTDB", + "last", + "1611" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-13T10:40:42.992657054" + } +} \ No newline at end of file diff --git a/modules/nf-core/last/lastdb/tests/nextflow.config b/modules/nf-core/last/lastdb/tests/nextflow.config new file mode 100644 index 000000000..50628ecdb --- /dev/null +++ b/modules/nf-core/last/lastdb/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: LAST_LASTDB { + ext.args = '-Q0' + } + +} diff --git a/modules/nf-core/manta/germline/environment.yml b/modules/nf-core/manta/germline/environment.yml index fe5ade506..697c36d1c 100644 --- a/modules/nf-core/manta/germline/environment.yml +++ b/modules/nf-core/manta/germline/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - bioconda::manta=1.6.0 + - conda-forge::python=2.7.15 diff --git a/modules/nf-core/manta/germline/main.nf b/modules/nf-core/manta/germline/main.nf index c1b339a95..c1550f5c6 100644 --- a/modules/nf-core/manta/germline/main.nf +++ b/modules/nf-core/manta/germline/main.nf @@ -5,8 +5,8 @@ process MANTA_GERMLINE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/manta:1.6.0--h9ee0642_1' : - 'biocontainers/manta:1.6.0--h9ee0642_1' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f6/f696c93e6209e33ac0d15f1ecfa799bc67329eec07b0569e065ea8b220b53953/data' : + 'community.wave.seqera.io/library/manta_python:0eb71149179b3920' }" input: //Matching the target bed with the input sample allows to parallelize the same sample run across different intervals or a single bed file @@ -16,13 +16,13 @@ process MANTA_GERMLINE { path(config) output: - tuple val(meta), path("*candidate_small_indels.vcf.gz") , emit: candidate_small_indels_vcf - tuple val(meta), path("*candidate_small_indels.vcf.gz.tbi"), emit: candidate_small_indels_vcf_tbi - tuple val(meta), path("*candidate_sv.vcf.gz") , emit: candidate_sv_vcf - tuple val(meta), path("*candidate_sv.vcf.gz.tbi") , emit: candidate_sv_vcf_tbi - tuple val(meta), path("*diploid_sv.vcf.gz") , emit: diploid_sv_vcf - tuple val(meta), path("*diploid_sv.vcf.gz.tbi") , emit: diploid_sv_vcf_tbi - path "versions.yml" , emit: versions + tuple val(meta), path("*candidate_small_indels.vcf.gz") , emit: candidate_small_indels_vcf + tuple val(meta), path("*candidate_small_indels.vcf.gz.tbi") , emit: candidate_small_indels_vcf_tbi + tuple val(meta), path("*candidate_sv.vcf.gz") , emit: candidate_sv_vcf + tuple val(meta), path("*candidate_sv.vcf.gz.tbi") , emit: candidate_sv_vcf_tbi + tuple val(meta), path("*diploid_sv.vcf.gz") , emit: diploid_sv_vcf + tuple val(meta), path("*diploid_sv.vcf.gz.tbi") , emit: diploid_sv_vcf_tbi + tuple val("${task.process}"), val("manta"), eval("configManta.py --version"), topic: versions, emit: versions_manta when: task.ext.when == null || task.ext.when @@ -30,7 +30,7 @@ process MANTA_GERMLINE { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def input_files = input.collect{"--bam ${it}"}.join(' ') + def input_files = input.collect{ bam -> "--bam ${bam}"}.join(' ') def options_manta = target_bed ? "--callRegions $target_bed" : "" def config_option = config ? "--config ${config}" : "" """ @@ -56,11 +56,6 @@ process MANTA_GERMLINE { ${prefix}.diploid_sv.vcf.gz mv manta/results/variants/diploidSV.vcf.gz.tbi \\ ${prefix}.diploid_sv.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - manta: \$( configManta.py --version ) - END_VERSIONS """ stub: @@ -72,10 +67,5 @@ process MANTA_GERMLINE { touch ${prefix}.candidate_sv.vcf.gz.tbi echo "" | gzip > ${prefix}.diploid_sv.vcf.gz touch ${prefix}.diploid_sv.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - manta: \$( configManta.py --version ) - END_VERSIONS """ } diff --git a/modules/nf-core/manta/germline/meta.yml b/modules/nf-core/manta/germline/meta.yml index 4072ab8e5..83ff420b8 100644 --- a/modules/nf-core/manta/germline/meta.yml +++ b/modules/nf-core/manta/germline/meta.yml @@ -29,18 +29,22 @@ input: type: file description: BAM/CRAM/SAM file. For joint calling use a list of files. pattern: "*.{bam,cram,sam}" + ontologies: [] - index: type: file description: BAM/CRAM/SAM index file. For joint calling use a list of files. pattern: "*.{bai,crai,sai}" + ontologies: [] - target_bed: type: file description: BED file containing target regions for variant calling pattern: "*.{bed}" + ontologies: [] - target_bed_tbi: type: file description: Index for BED file containing target regions for variant calling pattern: "*.{bed.tbi}" + ontologies: [] - - meta2: type: map description: | @@ -50,6 +54,7 @@ input: type: file description: Genome reference FASTA file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -59,13 +64,15 @@ input: type: file description: Genome reference FASTA index file pattern: "*.{fa.fai,fasta.fai}" - - - config: - type: file - description: Manta configuration file - pattern: "*.{ini,conf,config}" + ontologies: [] + - config: + type: file + description: Manta configuration file + pattern: "*.{ini,conf,config}" + ontologies: [] output: - - candidate_small_indels_vcf: - - meta: + candidate_small_indels_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -74,8 +81,9 @@ output: type: file description: Gzipped VCF file containing variants pattern: "*.{vcf.gz}" - - candidate_small_indels_vcf_tbi: - - meta: + ontologies: [] + candidate_small_indels_vcf_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -84,8 +92,9 @@ output: type: file description: Index for gzipped VCF file containing variants pattern: "*.{vcf.gz.tbi}" - - candidate_sv_vcf: - - meta: + ontologies: [] + candidate_sv_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -94,8 +103,9 @@ output: type: file description: Gzipped VCF file containing variants pattern: "*.{vcf.gz}" - - candidate_sv_vcf_tbi: - - meta: + ontologies: [] + candidate_sv_vcf_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -104,8 +114,9 @@ output: type: file description: Index for gzipped VCF file containing variants pattern: "*.{vcf.gz.tbi}" - - diploid_sv_vcf: - - meta: + ontologies: [] + diploid_sv_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -114,8 +125,9 @@ output: type: file description: Gzipped VCF file containing variants pattern: "*.{vcf.gz}" - - diploid_sv_vcf_tbi: - - meta: + ontologies: [] + diploid_sv_vcf_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -124,11 +136,30 @@ output: type: file description: Index for gzipped VCF file containing variants pattern: "*.{vcf.gz.tbi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_manta: + - - ${task.process}: + type: string + description: The name of the process + - manta: + type: string + description: The name of the tool + - configManta.py --version: + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - manta: + type: string + description: The name of the tool + - configManta.py --version: + type: eval + description: The expression to obtain the version of the tool + authors: - "@maxulysse" - "@ramprasadn" diff --git a/modules/nf-core/manta/germline/tests/main.nf.test b/modules/nf-core/manta/germline/tests/main.nf.test index 1d49ad23a..cfae4b3d6 100644 --- a/modules/nf-core/manta/germline/tests/main.nf.test +++ b/modules/nf-core/manta/germline/tests/main.nf.test @@ -38,10 +38,12 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert snapshot(process.out.version).match("version") } + { assert snapshot ( + path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + process.out.findAll { key, val -> key.startsWith("versions_") } + ).match() } ) } @@ -75,10 +77,12 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert snapshot(process.out.version).match("bed_version") } + { assert snapshot ( + path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + process.out.findAll { key, val -> key.startsWith("versions_") } + ).match() } ) } @@ -116,10 +120,12 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1") }, - { assert snapshot(process.out.version).match("joint_version") } + { assert snapshot ( + path(process.out.candidate_small_indels_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.candidate_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + path(process.out.diploid_sv_vcf.get(0).get(1)).linesGzip.contains("##fileformat=VCFv4.1"), + process.out.findAll { key, val -> key.startsWith("versions_") } + ).match() } ) } diff --git a/modules/nf-core/manta/germline/tests/main.nf.test.snap b/modules/nf-core/manta/germline/tests/main.nf.test.snap index 79d5541e3..1b23abf61 100644 --- a/modules/nf-core/manta/germline/tests/main.nf.test.snap +++ b/modules/nf-core/manta/germline/tests/main.nf.test.snap @@ -51,7 +51,11 @@ ] ], "6": [ - "versions.yml:md5,18070b443a26855ef64dafa179dfba01" + [ + "MANTA_GERMLINE", + "manta", + "1.6.0" + ] ], "candidate_small_indels_vcf": [ [ @@ -101,39 +105,82 @@ "test.diploid_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,18070b443a26855ef64dafa179dfba01" + "versions_manta": [ + [ + "MANTA_GERMLINE", + "manta", + "1.6.0" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-03-21T17:54:09.788372" + "timestamp": "2025-12-11T16:30:33.370543407" }, - "joint_version": { - "content": null, + "human - cram": { + "content": [ + true, + true, + true, + { + "versions_manta": [ + [ + "MANTA_GERMLINE", + "manta", + "1.6.0" + ] + ] + } + ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-03-21T15:03:07.745972" + "timestamp": "2025-12-11T16:43:35.235895962" }, - "bed_version": { - "content": null, + "human - cram - bed": { + "content": [ + true, + true, + true, + { + "versions_manta": [ + [ + "MANTA_GERMLINE", + "manta", + "1.6.0" + ] + ] + } + ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-03-21T13:49:38.745653" + "timestamp": "2025-12-11T16:43:45.131664257" }, - "version": { - "content": null, + "human - cram - bed - jointcalling": { + "content": [ + true, + true, + true, + { + "versions_manta": [ + [ + "MANTA_GERMLINE", + "manta", + "1.6.0" + ] + ] + } + ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-03-21T13:49:14.885769" + "timestamp": "2025-12-11T16:43:55.610167195" } } \ No newline at end of file diff --git a/modules/nf-core/manta/germline/tests/tags.yml b/modules/nf-core/manta/germline/tests/tags.yml deleted file mode 100644 index 99d1a73ca..000000000 --- a/modules/nf-core/manta/germline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -manta/germline: - - "modules/nf-core/manta/germline/**" diff --git a/modules/nf-core/mosdepth/environment.yml b/modules/nf-core/mosdepth/environment.yml index e93798738..1c7f3ee84 100644 --- a/modules/nf-core/mosdepth/environment.yml +++ b/modules/nf-core/mosdepth/environment.yml @@ -1,6 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: # renovate: datasource=conda depName=bioconda/mosdepth - - mosdepth=0.3.8 + - htslib=1.22.1 + - mosdepth=0.3.11=h0ec343a_1 diff --git a/modules/nf-core/mosdepth/main.nf b/modules/nf-core/mosdepth/main.nf index 6f4a83834..63739bfae 100644 --- a/modules/nf-core/mosdepth/main.nf +++ b/modules/nf-core/mosdepth/main.nf @@ -4,8 +4,8 @@ process MOSDEPTH { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mosdepth:0.3.8--hd299d5a_0' : - 'biocontainers/mosdepth:0.3.8--hd299d5a_0'}" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/00/00d32b53160c26794959da7303ee6e2107afd4d292060c9f287b0af1fddbd847/data' : + 'community.wave.seqera.io/library/mosdepth_htslib:0f58993cb6d93294'}" input: tuple val(meta), path(bam), path(bai), path(bed) @@ -24,7 +24,7 @@ process MOSDEPTH { tuple val(meta), path('*.quantized.bed.gz.csi') , optional:true, emit: quantized_csi tuple val(meta), path('*.thresholds.bed.gz') , optional:true, emit: thresholds_bed tuple val(meta), path('*.thresholds.bed.gz.csi'), optional:true, emit: thresholds_csi - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('mosdepth'), eval("mosdepth --version | sed 's/mosdepth //g'"), topic: versions, emit: versions_mosdepth when: task.ext.when == null || task.ext.when @@ -34,11 +34,11 @@ process MOSDEPTH { def prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--fasta ${fasta}" : "" def interval = bed ? "--by ${bed}" : "" - if (bed && args.contains("--by")) { + if (bed && (args.contains("--by") || args.contains("-b "))) { error "'--by' can only be specified once when running mosdepth! Either remove input BED file definition or remove '--by' from 'ext.args' definition" } - if (!bed && args.contains("--thresholds")) { - error "'--thresholds' can only be specified in conjunction with '--by'" + if (args.contains("--thresholds") && !(bed || args.contains("--by") || args.contains("-b "))) { + error "'--thresholds' can only be specified in conjunction with '--by' or an input bed file" } """ @@ -49,15 +49,17 @@ process MOSDEPTH { $args \\ $prefix \\ $bam - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - mosdepth: \$(mosdepth --version 2>&1 | sed 's/^.*mosdepth //; s/ .*\$//') - END_VERSIONS """ stub: + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + if (bed && (args.contains("--by") || args.contains("-b "))) { + error "'--by' can only be specified once when running mosdepth! Either remove input BED file definition or remove '--by' from 'ext.args' definition" + } + if (args.contains("--thresholds") && !(bed || args.contains("--by") || args.contains("-b "))) { + error "'--thresholds' can only be specified in conjunction with '--by' or an input bed file" + } """ touch ${prefix}.global.dist.txt touch ${prefix}.region.dist.txt @@ -71,10 +73,5 @@ process MOSDEPTH { touch ${prefix}.quantized.bed.gz.csi echo "" | gzip > ${prefix}.thresholds.bed.gz touch ${prefix}.thresholds.bed.gz.csi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - mosdepth: \$(mosdepth --version 2>&1 | sed 's/^.*mosdepth //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/mosdepth/meta.yml b/modules/nf-core/mosdepth/meta.yml index dc783c900..04c8bfe1e 100644 --- a/modules/nf-core/mosdepth/meta.yml +++ b/modules/nf-core/mosdepth/meta.yml @@ -23,14 +23,17 @@ input: type: file description: Input BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - bai: type: file description: Index for BAM/CRAM file pattern: "*.{bai,crai}" + ontologies: [] - bed: type: file description: BED file with intersected intervals pattern: "*.{bed}" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +43,10 @@ input: type: file description: Reference genome FASTA file pattern: "*.{fa,fasta}" + ontologies: [] output: - - global_txt: - - meta: + global_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,8 +55,9 @@ output: type: file description: Text file with global cumulative coverage distribution pattern: "*.{global.dist.txt}" - - summary_txt: - - meta: + ontologies: [] + summary_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -61,8 +66,9 @@ output: type: file description: Text file with summary mean depths per chromosome and regions pattern: "*.{summary.txt}" - - regions_txt: - - meta: + ontologies: [] + regions_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -71,8 +77,9 @@ output: type: file description: Text file with region cumulative coverage distribution pattern: "*.{region.dist.txt}" - - per_base_d4: - - meta: + ontologies: [] + per_base_d4: + - - meta: type: map description: | Groovy Map containing sample information @@ -81,8 +88,9 @@ output: type: file description: D4 file with per-base coverage pattern: "*.{per-base.d4}" - - per_base_bed: - - meta: + ontologies: [] + per_base_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -91,8 +99,9 @@ output: type: file description: BED file with per-base coverage pattern: "*.{per-base.bed.gz}" - - per_base_csi: - - meta: + ontologies: [] + per_base_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -101,8 +110,9 @@ output: type: file description: Index file for BED file with per-base coverage pattern: "*.{per-base.bed.gz.csi}" - - regions_bed: - - meta: + ontologies: [] + regions_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -111,8 +121,9 @@ output: type: file description: BED file with per-region coverage pattern: "*.{regions.bed.gz}" - - regions_csi: - - meta: + ontologies: [] + regions_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -121,8 +132,9 @@ output: type: file description: Index file for BED file with per-region coverage pattern: "*.{regions.bed.gz.csi}" - - quantized_bed: - - meta: + ontologies: [] + quantized_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -131,8 +143,9 @@ output: type: file description: BED file with binned coverage pattern: "*.{quantized.bed.gz}" - - quantized_csi: - - meta: + ontologies: [] + quantized_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -141,8 +154,9 @@ output: type: file description: Index file for BED file with binned coverage pattern: "*.{quantized.bed.gz.csi}" - - thresholds_bed: - - meta: + ontologies: [] + thresholds_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -152,8 +166,9 @@ output: description: BED file with the number of bases in each region that are covered at or above each threshold pattern: "*.{thresholds.bed.gz}" - - thresholds_csi: - - meta: + ontologies: [] + thresholds_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -162,11 +177,29 @@ output: type: file description: Index file for BED file with threshold coverage pattern: "*.{thresholds.bed.gz.csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_mosdepth: + - - ${task.process}: + type: string + description: The process the versions were collected from + - mosdepth: + type: string + description: The tool name + - "mosdepth --version | sed 's/mosdepth //g'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - mosdepth: + type: string + description: The tool name + - "mosdepth --version | sed 's/mosdepth //g'": + type: string + description: The command used to generate the version of the tool authors: - "@joseespinosa" - "@drpatelh" @@ -174,6 +207,5 @@ authors: - "@matthdsm" maintainers: - "@joseespinosa" - - "@drpatelh" - "@ramprasadn" - "@matthdsm" diff --git a/modules/nf-core/mosdepth/tests/main.nf.test b/modules/nf-core/mosdepth/tests/main.nf.test index 0b3c860d3..b05dde5be 100644 --- a/modules/nf-core/mosdepth/tests/main.nf.test +++ b/modules/nf-core/mosdepth/tests/main.nf.test @@ -7,10 +7,14 @@ nextflow_process { tag "modules" tag "modules_nfcore" tag "mosdepth" + config "./nextflow.config" test("homo_sapiens - bam, bai, []") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -25,9 +29,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -36,6 +40,9 @@ nextflow_process { test("homo_sapiens - bam, bai, bed") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -50,9 +57,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -61,6 +68,9 @@ nextflow_process { test("homo_sapiens - cram, crai, []") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -78,9 +88,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -89,6 +99,9 @@ nextflow_process { test("homo_sapiens - cram, crai, bed") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -106,9 +119,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -116,8 +129,10 @@ nextflow_process { test("homo_sapiens - bam, bai, [] - window") { - config "./window.config" when { + params { + module_args = "--by 100" + } process { """ input[0] = [ @@ -132,9 +147,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -142,8 +157,10 @@ nextflow_process { test("homo_sapiens - bam, bai, [] - quantized") { - config "./quantized.config" when { + params { + module_args = "--quantize 0:1:4:100:200" + } process { """ input[0] = [ @@ -158,9 +175,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -168,8 +185,10 @@ nextflow_process { test("homo_sapiens - bam, bai, bed - thresholds") { - config "./threshold.config" when { + params { + module_args = "--thresholds 1,10,20,30" + } process { """ input[0] = [ @@ -184,9 +203,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -194,8 +213,10 @@ nextflow_process { test("homo_sapiens - bam, bai, bed - fail") { - config "./window.config" when { + params { + module_args = "--by 100" + } process { """ input[0] = [ @@ -210,9 +231,7 @@ nextflow_process { } then { - assertAll( - { assert process.failed } - ) + assert process.failed } } @@ -221,6 +240,9 @@ nextflow_process { options "-stub" when { + params { + module_args = "" + } process { """ input[0] = [ @@ -235,9 +257,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } diff --git a/modules/nf-core/mosdepth/tests/main.nf.test.snap b/modules/nf-core/mosdepth/tests/main.nf.test.snap index c604540b0..c27fcc791 100644 --- a/modules/nf-core/mosdepth/tests/main.nf.test.snap +++ b/modules/nf-core/mosdepth/tests/main.nf.test.snap @@ -39,7 +39,11 @@ ] ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -221,16 +225,20 @@ "test.thresholds.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:16.953408231" + "timestamp": "2025-09-23T13:06:13.219131" }, "homo_sapiens - cram, crai, bed": { "content": [ @@ -260,7 +268,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -289,7 +301,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -307,7 +319,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -340,7 +352,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -367,7 +379,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -394,16 +406,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:50.160217828" + "timestamp": "2025-09-23T13:22:14.011309" }, "homo_sapiens - bam, bai, [] - quantized": { "content": [ @@ -433,7 +449,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -456,7 +476,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -480,7 +500,7 @@ "id": "test", "single_end": true }, - "test.quantized.bed.gz.csi:md5,4f69e6ace50206a2768be66ded3a56f0" + "test.quantized.bed.gz.csi:md5,c0a3176a59010639455a4aefb3f247ef" ] ], "global_txt": [ @@ -507,7 +527,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -528,7 +548,7 @@ "id": "test", "single_end": true }, - "test.quantized.bed.gz.csi:md5,4f69e6ace50206a2768be66ded3a56f0" + "test.quantized.bed.gz.csi:md5,c0a3176a59010639455a4aefb3f247ef" ] ], "regions_bed": [ @@ -555,16 +575,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:01.164885111" + "timestamp": "2025-09-23T13:22:22.818082" }, "homo_sapiens - bam, bai, bed": { "content": [ @@ -594,7 +618,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -623,7 +651,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -641,7 +669,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -674,7 +702,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -701,7 +729,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -728,16 +756,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:39.071657456" + "timestamp": "2025-09-23T13:22:04.449943" }, "homo_sapiens - bam, bai, [] - window": { "content": [ @@ -767,7 +799,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -796,7 +832,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -814,7 +850,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,2a30bcb7f5c7632136b3efce24723970" + "test.regions.bed.gz.csi:md5,17a2cbe22a948d7c004b90a1f28347a1" ] ], "8": [ @@ -847,7 +883,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -874,7 +910,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,2a30bcb7f5c7632136b3efce24723970" + "test.regions.bed.gz.csi:md5,17a2cbe22a948d7c004b90a1f28347a1" ] ], "regions_txt": [ @@ -901,16 +937,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:55.631776118" + "timestamp": "2025-09-23T13:22:18.435089" }, "homo_sapiens - bam, bai, []": { "content": [ @@ -940,7 +980,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -963,7 +1007,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1002,7 +1046,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1038,16 +1082,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:33.642125299" + "timestamp": "2025-09-23T13:21:59.785829" }, "homo_sapiens - cram, crai, []": { "content": [ @@ -1077,7 +1125,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -1100,7 +1152,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1139,7 +1191,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1175,16 +1227,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:44.704920941" + "timestamp": "2025-09-23T13:22:09.294766" }, "homo_sapiens - bam, bai, bed - thresholds": { "content": [ @@ -1222,11 +1278,15 @@ "id": "test", "single_end": true }, - "test.thresholds.bed.gz.csi:md5,219414a0751185adb98d2235d83ea055" + "test.thresholds.bed.gz.csi:md5,2c52ab89e7496af475de3cb2ca04c7b3" ] ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -1255,7 +1315,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1273,7 +1333,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -1306,7 +1366,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1333,7 +1393,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -1369,18 +1429,22 @@ "id": "test", "single_end": true }, - "test.thresholds.bed.gz.csi:md5,219414a0751185adb98d2235d83ea055" + "test.thresholds.bed.gz.csi:md5,2c52ab89e7496af475de3cb2ca04c7b3" ] ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:06.737266831" + "timestamp": "2025-09-23T13:22:27.300204" } } \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/nextflow.config b/modules/nf-core/mosdepth/tests/nextflow.config new file mode 100644 index 000000000..b21c05b56 --- /dev/null +++ b/modules/nf-core/mosdepth/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: "MOSDEPTH" { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/mosdepth/tests/quantized.config b/modules/nf-core/mosdepth/tests/quantized.config deleted file mode 100644 index 63c553506..000000000 --- a/modules/nf-core/mosdepth/tests/quantized.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--quantize 0:1:4:100:200" -} \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/tags.yml b/modules/nf-core/mosdepth/tests/tags.yml deleted file mode 100644 index 5cd2e08e2..000000000 --- a/modules/nf-core/mosdepth/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -mosdepth: - - "modules/nf-core/mosdepth/**" diff --git a/modules/nf-core/mosdepth/tests/threshold.config b/modules/nf-core/mosdepth/tests/threshold.config deleted file mode 100644 index 9b014ddf5..000000000 --- a/modules/nf-core/mosdepth/tests/threshold.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--thresholds 1,10,20,30" -} \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/window.config b/modules/nf-core/mosdepth/tests/window.config deleted file mode 100644 index 7a0f755ce..000000000 --- a/modules/nf-core/mosdepth/tests/window.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--by 100" -} \ No newline at end of file diff --git a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c1f4a7982b743963_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c1f4a7982b743963_1.txt new file mode 100644 index 000000000..761903040 --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c1f4a7982b743963_1.txt @@ -0,0 +1,1552 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-64: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.39.3-py310hbcd5346_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py314h2e6c369_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.2.28-py314h5bd0f2a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.52.0-h04a0ce9_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 +md5: a9f577daf3de00bca7c3c76c0ecbd1de +depends: +- __glibc >=2.17,<3.0.a0 +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28948 +timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 +md5: aaa2a381ccc56eac91d63b6c1240312f +depends: +- cpython +- python-gil +license: MIT +license_family: MIT +size: 8191 +timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 +md5: 2934f256a8acfe48f6ebb4fce6cde29c +depends: +- python >=3.9 +- typing-extensions >=4.0.0 +license: MIT +license_family: MIT +size: 18074 +timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab +md5: c6b0543676ecb1fb2d7643941fe375f2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 64927 +timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda +noarch: generic +sha256: c31ab719d256bc6f89926131e88ecd0f0c5d003fe8481852c6424f4ec6c7eb29 +md5: a2ac7763a9ac75055b68f325d3255265 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7514 +timestamp: 1767044983590 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda +sha256: 3ad3500bff54a781c29f16ce1b288b36606e2189d0b0ef2f67036554f47f12b0 +md5: 8910d2c46f7e7b519129f486e0fe927a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- libbrotlicommon 1.2.0 hb03c661_1 +license: MIT +license_family: MIT +size: 367376 +timestamp: 1764017265553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 +md5: d2ffd7602c02f2b316fd921d39876885 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 260182 +timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc +md5: 4492fd26db29495f0ba23f146cd5638d +depends: +- __unix +license: ISC +size: 147413 +timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda +sha256: a6b118fd1ed6099dc4fc03f9c492b88882a780fadaef4ed4f93dc70757713656 +md5: 765c4d97e877cdbbb88ff33152b86125 +depends: +- python >=3.10 +license: ISC +size: 151445 +timestamp: 1772001170301 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda +sha256: d86dfd428b2e3c364fa90e07437c8405d635aa4ef54b25ab51d9c712be4112a5 +md5: 49ee13eb9b8f44d63879c69b8a40a74b +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58510 +timestamp: 1773660086450 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda +sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 +md5: ea8a6c3256897cc31263de9f455e25d9 +depends: +- python >=3.10 +- __unix +- python +license: BSD-3-Clause +license_family: BSD +size: 97676 +timestamp: 1764518652276 +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 +md5: b866ff7007b934d564961066c8195983 +depends: +- humanfriendly >=9.1 +- python >=3.9 +license: MIT +license_family: MIT +size: 43758 +timestamp: 1733928076798 +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 +md5: 071cf7b0ce333c81718b054066c15102 +depends: +- networkx >=2.0 +- numpy +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 39326 +timestamp: 1735759976140 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda +noarch: generic +sha256: 91b06300879df746214f7363d6c27c2489c80732e46a369eb2afc234bcafb44c +md5: 3bb89e4f795e5414addaa531d6b1500a +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50078 +timestamp: 1770674447292 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda +sha256: 0cc345e4dead417996ce9a1f088b28d858f03d113d43c1963d29194366dcce27 +md5: a0535741a4934b3e386051065c58761a +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat 2.7.4 hecca717_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 145274 +timestamp: 1771259434699 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda +sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c +md5: 867127763fbe935bab59815b6e0b7b5c +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +license: MIT +license_family: MIT +size: 270705 +timestamp: 1771382710863 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 +md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 +depends: +- python >=3.10 +- hyperframe >=6.1,<7 +- hpack >=4.1,<5 +- python +license: MIT +license_family: MIT +size: 95967 +timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba +md5: 0a802cb9888dd14eeefc611f05c40b6e +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 30731 +timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d +md5: 7fe569c10905402ed47024fc481bb371 +depends: +- __unix +- python >=3.9 +license: MIT +license_family: MIT +size: 73563 +timestamp: 1733928021866 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 +md5: daddf757c3ecd6067b9af1df1f25d89e +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 67994 +timestamp: 1766267728652 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 +md5: 8e6923fc12f1fe8f8c4e5c9f343256ac +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 17397 +timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda +sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a +md5: c80d8a3b84358cb967fa81e7075fbc8a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: MIT +license_family: MIT +size: 12723451 +timestamp: 1773822285671 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda +sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 +md5: 53abe63df7e10a6ba605dc5f9f961d36 +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 50721 +timestamp: 1760286526795 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda +sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 +md5: 080594bf4493e6bae2607e65390c520a +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +license_family: APACHE +size: 34387 +timestamp: 1773931568510 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b +md5: 04558c96691bed63104678757beb4f8d +depends: +- markupsafe >=2.0 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 120685 +timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 +md5: ada41c863af263cc4c5fcbaff7c3e4dc +depends: +- attrs >=22.2.0 +- jsonschema-specifications >=2023.3.6 +- python >=3.10 +- referencing >=0.28.4 +- rpds-py >=0.25.0 +- python +license: MIT +license_family: MIT +size: 82356 +timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 +md5: 439cd0f567d697b20a8f45cb70a1005a +depends: +- python >=3.10 +- referencing >=0.31.0 +- python +license: MIT +license_family: MIT +size: 19236 +timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 +sha256: 7f243680ca03eba7457b7a48f93a9440ba8181a8eac20a3eb5ef165ab6c96664 +md5: b3723b235b0758abaae8c82ce4d80146 +depends: +- __glibc >=2.17,<3.0.a0 +- expat >=2.2.10,<3.0.0a0 +- fontconfig +- fonts-conda-forge +- libgcc-ng >=9.3.0 +- mathjax 2.7.* +- nspr >=4.29,<5.0a0 +- nss >=3.62,<4.0a0 +- sqlite >=3.34.0,<4.0a0 +license: MIT +license_family: MIT +size: 62099926 +timestamp: 1615199463039 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda +sha256: 836ec4b895352110335b9fdcfa83a8dcdbe6c5fb7c06c4929130600caea91c0a +md5: 6f2e2c8f58160147c4d1c6f4c14cbac4 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 249959 +timestamp: 1768184673131 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda +sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c +md5: 18335a698559cdbcd86150a48bf54ba6 +depends: +- __glibc >=2.17,<3.0.a0 +- zstd >=1.5.7,<1.6.0a0 +constrains: +- binutils_impl_linux-64 2.45.1 +license: GPL-3.0-only +license_family: GPL +size: 728002 +timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +sha256: f84cb54782f7e9cea95e810ea8fef186e0652d0fa73d3009914fa2c1262594e1 +md5: a752488c68f2e7c456bcbd8f16eec275 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 261513 +timestamp: 1773113328888 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda +build_number: 5 +sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c +md5: c160954f7418d7b6e87eaf05a8913fa9 +depends: +- libopenblas >=0.3.30,<0.3.31.0a0 +- libopenblas >=0.3.30,<1.0a0 +constrains: +- mkl <2026 +- liblapack 3.11.0 5*_openblas +- libcblas 3.11.0 5*_openblas +- blas 2.305 openblas +- liblapacke 3.11.0 5*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18213 +timestamp: 1765818813880 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda +build_number: 5 +sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 +md5: 6636a2b6f1a87572df2970d3ebc87cc0 +depends: +- libblas 3.11.0 5_h4a7cf45_openblas +constrains: +- liblapacke 3.11.0 5*_openblas +- blas 2.305 openblas +- liblapack 3.11.0 5*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18194 +timestamp: 1765818837135 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 +md5: 6c77a605a7a689d17d4819c0f8ac9a00 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 73490 +timestamp: 1761979956660 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda +sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 +md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- expat 2.7.4.* +license: MIT +license_family: MIT +size: 76798 +timestamp: 1771259418166 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 +md5: a360c33a5abe61c07959e449fa1453eb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 58592 +timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 +md5: e289f3d17880e44b633ba911d57a321b +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8049 +timestamp: 1774298163029 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d +md5: fb16b4b69e3f1dcfe79d80db8fd0c55d +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 384575 +timestamp: 1774298162622 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda +sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 +md5: 0aa00f03f9e39fb9876085dee11a85d4 +depends: +- __glibc >=2.17,<3.0.a0 +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_18 +- libgomp 15.2.0 he0feb66_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1041788 +timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda +sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 +md5: d5e96b1ed75ca01906b3d2469b4ce493 +depends: +- libgcc 15.2.0 he0feb66_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27526 +timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda +sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee +md5: 9063115da5bc35fdc3e1002e69b9ef6e +depends: +- libgfortran5 15.2.0 h68bc16d_18 +constrains: +- libgfortran-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27523 +timestamp: 1771378269450 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda +sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 +md5: 646855f357199a12f02a87382d429b75 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=15.2.0 +constrains: +- libgfortran 15.2.0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 2482475 +timestamp: 1771378241063 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda +sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 +md5: 239c5e9546c38a1e884d69effcf4c882 +depends: +- __glibc >=2.17,<3.0.a0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 603262 +timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda +sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 +md5: 8397539e3a0bbd1695584fb4f927485a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 633710 +timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda +build_number: 5 +sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 +md5: b38076eb5c8e40d0106beda6f95d7609 +depends: +- libblas 3.11.0 5_h4a7cf45_openblas +constrains: +- blas 2.305 openblas +- liblapacke 3.11.0 5*_openblas +- libcblas 3.11.0 5*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18200 +timestamp: 1765818857876 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda +sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb +md5: c7c83eecbb72d88b940c249af56c8b17 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- xz 5.8.2.* +license: 0BSD +size: 113207 +timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda +sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 +md5: 2c21e66f50753a083cbe6b80f38268fa +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-2-Clause +license_family: BSD +size: 92400 +timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda +sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 +md5: be43915efc66345cccb3c310b6ed0374 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.30,<0.3.31.0a0 +license: BSD-3-Clause +license_family: BSD +size: 5927939 +timestamp: 1763114673331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda +sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c +md5: 5f13ffc7d30ffec87864e678df9957b4 +depends: +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libzlib >=1.3.1,<2.0a0 +license: zlib-acknowledgement +size: 317669 +timestamp: 1770691470744 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda +sha256: d716847b7deca293d2e49ed1c8ab9e4b9e04b9d780aea49a97c26925b28a7993 +md5: fd893f6a3002a635b5e50ceb9dd2c0f4 +depends: +- __glibc >=2.17,<3.0.a0 +- icu >=78.2,<79.0a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: blessing +size: 951405 +timestamp: 1772818874251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda +sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e +md5: 1b08cd684f34175e4514474793d44bcb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc 15.2.0 he0feb66_18 +constrains: +- libstdcxx-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5852330 +timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 +md5: cd5a90476766d53e901500df9215e927 +depends: +- __glibc >=2.17,<3.0.a0 +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 435273 +timestamp: 1762022005702 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda +sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee +md5: db409b7c1720428638e7c0d509d3e1b5 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 40311 +timestamp: 1766271528534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b +md5: aea31d2e5b1091feca96fcfe945c3cf9 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 429011 +timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa +md5: 92ed62436b625154323d40d5f2f11dd7 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 395888 +timestamp: 1727278577118 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 +md5: d87ff7921124eccd67248aa483c23fec +depends: +- __glibc >=2.17,<3.0.a0 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 63629 +timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b +md5: ba0a9221ce1063f31692c07370d062f3 +depends: +- importlib-metadata >=4.4 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 85893 +timestamp: 1770694658918 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda +sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e +md5: 5b5203189eb668f042ac2b0826244964 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 64736 +timestamp: 1754951288511 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda +sha256: c279be85b59a62d5c52f5dd9a4cd43ebd08933809a8416c22c3131595607d4cf +md5: 9a17c4307d23318476d7fbf0fedc0cde +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- jinja2 >=3.0.0 +license: BSD-3-Clause +license_family: BSD +size: 27424 +timestamp: 1772445227915 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 +sha256: 02fef69bde69db264a12f21386612262f545b6e3e68d8f1ccec19f3eaae58edf +md5: 86e69bd82c2a2c6fd29f5ab7e02b3691 +license: Apache-2.0 +license_family: Apache +size: 22281629 +timestamp: 1662784498331 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 +md5: 592132998493b3ff25fd7479396e8351 +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 14465 +timestamp: 1733255681319 +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda +sha256: f005760b13093362fc9c997d603dd487de32ab2e821a3cbce52a42bcb8136517 +md5: 698a8a27c2b9d8a542c70cb47099a75e +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars-lts-cpu +- pyaml-env +- pydantic >=2.7.1 +- python >=3.8,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard +license: GPL-3.0-or-later +license_family: GPL3 +size: 4198799 +timestamp: 1765300743879 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda +sha256: 541fd4390a0687228b8578247f1536a821d9261389a65585af9d1a6f2a14e1e0 +md5: 30bec5e8f4c3969e2b1bd407c5e52afb +depends: +- python >=3.10 +- python +license: MIT +size: 280459 +timestamp: 1774380620329 +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 +md5: e941e85e273121222580723010bd4fa2 +depends: +- python >=3.9 +- python +license: MIT +license_family: MIT +size: 39262 +timestamp: 1770905275632 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda +sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 +md5: 47e340acb35de30501a76c7c799c41d7 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: X11 AND BSD-3-Clause +size: 891641 +timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 +md5: a2c1eeadae7a309daed9d62c96012a2b +depends: +- python >=3.11 +- python +constrains: +- numpy >=1.25 +- scipy >=1.11.2 +- matplotlib-base >=3.8 +- pandas >=2.0 +license: BSD-3-Clause +license_family: BSD +size: 1587439 +timestamp: 1765215107045 +- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda +sha256: e3664264bd936c357523b55c71ed5a30263c6ba278d726a75b1eb112e6fb0b64 +md5: e235d5566c9cc8970eb2798dd4ecf62f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: MPL-2.0 +license_family: MOZILLA +size: 228588 +timestamp: 1762348634537 +- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda +sha256: 44dd98ffeac859d84a6dcba79a2096193a42fc10b29b28a5115687a680dd6aea +md5: 567fbeed956c200c1db5782a424e58ee +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libsqlite >=3.51.0,<4.0a0 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +- nspr >=4.38,<5.0a0 +license: MPL-2.0 +license_family: MOZILLA +size: 2057773 +timestamp: 1763485556350 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda +sha256: f2ba8cb0d86a6461a6bcf0d315c80c7076083f72c6733c9290086640723f79ec +md5: 36f5b7eb328bdc204954a2225cf908e2 +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- python_abi 3.14.* *_cp314 +- libcblas >=3.9.0,<4.0a0 +- liblapack >=3.9.0,<4.0a0 +- libblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8927860 +timestamp: 1773839233468 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda +sha256: 3900f9f2dbbf4129cf3ad6acf4e4b6f7101390b53843591c53b00f034343bc4d +md5: 11b3379b191f63139e29c0d19dee24cd +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libpng >=1.6.50,<1.7.0a0 +- libstdcxx >=14 +- libtiff >=4.7.1,<4.8.0a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-2-Clause +license_family: BSD +size: 355400 +timestamp: 1758489294972 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda +sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c +md5: f61eb8cd60ff9057122a3d338b99c00f +depends: +- __glibc >=2.17,<3.0.a0 +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3164551 +timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda +sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 +md5: b76541e68fea4d511b1ac46a28dcd2c6 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 72010 +timestamp: 1769093650580 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda +sha256: 9e6ec8f3213e8b7d64b0ad45f84c51a2c9eba4398efda31e196c9a56186133ee +md5: 79678378ae235e24b3aa83cee1b38207 +depends: +- python +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libwebp-base >=1.6.0,<2.0a0 +- zlib-ng >=2.3.3,<2.4.0a0 +- python_abi 3.14.* *_cp314 +- tk >=8.6.13,<8.7.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libxcb >=1.17.0,<2.0a0 +- openjpeg >=2.5.4,<3.0a0 +- lcms2 >=2.18,<3.0a0 +- libtiff >=4.7.1,<4.8.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +license: HPND +size: 1073026 +timestamp: 1770794002408 +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 +md5: 3e9427ee186846052e81fadde8ebe96a +depends: +- narwhals >=1.15.1 +- packaging +- python >=3.10 +constrains: +- ipywidgets >=7.6 +license: MIT +license_family: MIT +size: 5251872 +timestamp: 1772628857717 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda +sha256: d332c2d5002fc440ae37ed9679ffc21b552f18d20232390005d1dd3bce0888d3 +md5: d5a4e013a30dd8dfde9ab39f45aaf9c1 +depends: +- polars-runtime-32 ==1.39.3 +- python >=3.10 +- python +constrains: +- numpy >=1.16.0 +- pyarrow >=7.0.0 +- fastexcel >=0.9 +- openpyxl >=3.0.0 +- xlsx2csv >=0.8.0 +- connectorx >=0.3.2 +- deltalake >=1.0.0 +- pyiceberg >=0.7.1 +- altair >=5.4.0 +- great_tables >=0.8.0 +- polars-runtime-32 ==1.39.3 +- polars-runtime-64 ==1.39.3 +- polars-runtime-compat ==1.39.3 +license: MIT +license_family: MIT +size: 533495 +timestamp: 1774207987966 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda +sha256: e466fb31f67ba9bde18deafeb34263ca5eb25807f39ead0e9d753a8e82c4c4f4 +md5: ef0340e75068ac8ff96462749b5c98e7 +depends: +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +license: MIT +license_family: MIT +size: 3902 +timestamp: 1760206808444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda +noarch: python +sha256: 9744f8086bb0832998f5b01076f57ddc9efbe460e493b14303c3567dc4f401e7 +md5: f9327f9f2cfc4215f55b613e64afd3ba +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 37570276 +timestamp: 1774207987966 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.39.3-py310hbcd5346_1.conda +noarch: python +sha256: bf0b932713f0f27924f42159c98426e0073bb6145ed796eaa4cec79ca05363c7 +md5: 4b9b312453eebd6fbdbbe2a88fa1b5c4 +depends: +- python +- libgcc >=14 +- libstdcxx >=14 +- __glibc >=2.17,<3.0.a0 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 37224264 +timestamp: 1774207985377 +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +sha256: 4ce2e1ee31a6217998f78c31ce7dc0a3e0557d9238b51d49dd20c52d467a126d +md5: f2c23a77b25efcad57d377b34bd84941 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 593603 +timestamp: 1769710381284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 +md5: b3c17d95b5a10c6e64a21fa17573e70e +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: MIT +license_family: MIT +size: 8252 +timestamp: 1726802366959 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 +md5: e17be1016bcc3516827b836cd3e4d9dc +depends: +- python >=3.9 +- pyyaml >=5.0,<=7.0 +license: MIT +license_family: MIT +size: 14645 +timestamp: 1736766960536 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda +sha256: 868569d9505b7fe246c880c11e2c44924d7613a8cdcc1f6ef85d5375e892f13d +md5: c3946ed24acdb28db1b5d63321dbca7d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- typing-extensions >=4.6.1 +- annotated-types >=0.6.0 +- pydantic-core ==2.41.5 +- python +license: MIT +license_family: MIT +size: 340482 +timestamp: 1764434463101 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py314h2e6c369_1.conda +sha256: 7e0ae379796e28a429f8e48f2fe22a0f232979d65ec455e91f8dac689247d39f +md5: 432b0716a1dfac69b86aa38fdd59b7e6 +depends: +- python +- typing-extensions >=4.6.0,!=4.7.0 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 1943088 +timestamp: 1762988995556 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda +sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a +md5: 6b6ece66ebcae2d5f326c77ef2c5a066 +depends: +- python >=3.9 +license: BSD-2-Clause +license_family: BSD +size: 889287 +timestamp: 1750615908735 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 +md5: 461219d1a5bd61342293efa2c0c90eac +depends: +- __unix +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 21085 +timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda +build_number: 101 +sha256: cb0628c5f1732f889f53a877484da98f5a0e0f47326622671396fb4f2b0cd6bd +md5: c014ad06e60441661737121d3eae8a60 +depends: +- __glibc >=2.17,<3.0.a0 +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-64 >=2.36.1 +- libexpat >=2.7.3,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.2,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.51.2,<4.0a0 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +- ncurses >=6.5,<7.0a0 +- openssl >=3.5.5,<4.0a0 +- python_abi 3.14.* *_cp314 +- readline >=8.3,<9.0a0 +- tk >=8.6.13,<8.7.0a0 +- tzdata +- zstd >=1.5.7,<1.6.0a0 +license: Python-2.0 +size: 36702440 +timestamp: 1770675584356 +python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 +md5: 130584ad9f3a513cdd71b1fdc1244e9c +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 27848 +timestamp: 1772388605021 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda +sha256: 233aebd94c704ac112afefbb29cf4170b7bc606e22958906f2672081bc50638a +md5: 235765e4ea0d0301c75965985163b5a1 +depends: +- cpython 3.14.3.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50062 +timestamp: 1770674497152 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 +md5: 310259a5b03ff02289d7705f39e2b1d2 +depends: +- kaleido-core 0.2.1.* +- python >=3.5 +license: MIT +license_family: MIT +size: 18320 +timestamp: 1615204747600 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +build_number: 8 +sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 +md5: 0539938c55b6b1a59b560e843ad864a4 +constrains: +- python 3.14.* *_cp314 +license: BSD-3-Clause +license_family: BSD +size: 6989 +timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda +sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d +md5: 2035f68f96be30dc60a5dfd7452c7941 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- yaml >=0.2.5,<0.3.0a0 +license: MIT +license_family: MIT +size: 202391 +timestamp: 1770223462836 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda +sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 +md5: d7d95fc8287ea7bf33e0e7116d2b95ec +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-3.0-only +license_family: GPL +size: 345073 +timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 +md5: 870293df500ca7e18bedefa5838a22ab +depends: +- attrs >=22.2.0 +- python >=3.10 +- rpds-py >=0.7.0 +- typing_extensions >=4.4.0 +- python +license: MIT +license_family: MIT +size: 51788 +timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.2.28-py314h5bd0f2a_0.conda +sha256: e085e336f1446f5263a3ec9747df8c719b6996753901181add50dc4fdd8bb2e8 +md5: 3c8b6a8c4d0ff5a264e9831eac4941f4 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +license: Apache-2.0 AND CNRI-Python +license_family: PSF +size: 411924 +timestamp: 1772255161535 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda +sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 +md5: c65df89a0b2e321045a9e01d1337b182 +depends: +- python >=3.10 +- certifi >=2017.4.17 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.21.1,<3 +- python +constrains: +- chardet >=3.0.2,<6 +license: Apache-2.0 +license_family: APACHE +size: 63602 +timestamp: 1766926974520 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda +sha256: b06ce84d6a10c266811a7d3adbfa1c11f13393b91cc6f8a5b468277d90be9590 +md5: 7a6289c50631d620652f5045a63eb573 +depends: +- markdown-it-py >=2.2.0 +- pygments >=2.13.0,<3.0.0 +- python >=3.10 +- typing_extensions >=4.0.0,<5.0.0 +- python +license: MIT +license_family: MIT +size: 208472 +timestamp: 1771572730357 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 +md5: 0c20a8ebcddb24a45da89d5e917e6cb9 +depends: +- python >=3.10 +- rich >=12 +- click >=8 +- typing-extensions >=4 +- __unix +- python +license: MIT +license_family: MIT +size: 64356 +timestamp: 1769850479089 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda +sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 +md5: c1c368b5437b0d1a68f372ccf01cb133 +depends: +- python +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 376121 +timestamp: 1764543122774 +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 +md5: 472239e4eb7b5a84bb96b3ed7e3a596a +depends: +- colormath >=3.0.0 +- python >=3.9 +license: MIT +license_family: MIT +size: 22284 +timestamp: 1735770589188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.52.0-h04a0ce9_0.conda +sha256: c9af81e7830d9c4b67a7f48e512d060df2676b29cac59e3b31f09dbfcee29c58 +md5: 7d9d7efe9541d4bb71b5934e8ee348ea +depends: +- __glibc >=2.17,<3.0.a0 +- icu >=78.2,<79.0a0 +- libgcc >=14 +- libsqlite 3.52.0 hf4e2dac_0 +- libzlib >=1.3.1,<2.0a0 +- ncurses >=6.5,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 203641 +timestamp: 1772818888368 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda +sha256: 7e395d67fd249d901beb1ae269057763c0d8c3ee5f7a348694bdb16d158a37d9 +md5: d705f9d8a1185a2b01cced191177a028 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- regex >=2022.1.18 +- requests >=2.26.0 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 939648 +timestamp: 1764028306357 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda +sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac +md5: cffd3bdd58090148f4cfcd831f4b26ab +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +constrains: +- xorg-libx11 >=1.8.12,<2.0a0 +license: TCL +license_family: BSD +size: 3301196 +timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 +md5: e5ce43272193b38c2e9037446c1d9206 +depends: +- python >=3.10 +- __unix +- python +license: MPL-2.0 and MIT +size: 94132 +timestamp: 1770153424136 +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda +sha256: 39d8ae33c43cdb8f771373e149b0b4fae5a08960ac58dcca95b2f1642bb17448 +md5: 260af1b0a94f719de76b4e14094e9a3b +depends: +- importlib-metadata >=3.6 +- python >=3.10 +- typing-extensions >=4.10.0 +- typing_extensions >=4.14.0 +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 36838 +timestamp: 1771532971545 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c +md5: edd329d7d3a4ab45dcf905899a7a6115 +depends: +- typing_extensions ==4.15.0 pyhcf101f3_0 +license: PSF-2.0 +license_family: PSF +size: 91383 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda +sha256: 70db27de58a97aeb7ba7448366c9853f91b21137492e0b4430251a1870aa8ff4 +md5: a0a4a3035667fc34f29bfbd5c190baa6 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +license: MIT +license_family: MIT +size: 18923 +timestamp: 1764158430324 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 +md5: 0caa1af407ecff61170c9437a808404d +depends: +- python >=3.10 +- python +license: PSF-2.0 +license_family: PSF +size: 51692 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c +md5: ad659d0a2b3e47e38d829aa8cad2d610 +license: LicenseRef-Public-Domain +size: 119135 +timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda +sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a +md5: 9272daa869e03efe68833e3dc7a02130 +depends: +- backports.zstd >=1.0.0 +- brotli-python >=1.2.0 +- h2 >=4,<5 +- pysocks >=1.5.6,<2.0,!=1.5.7 +- python >=3.10 +license: MIT +license_family: MIT +size: 103172 +timestamp: 1767817860341 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b +md5: b2895afaf55bf96a8c8282a2e47a5de0 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 15321 +timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 +md5: 1dafce8548e38671bea82e3f5c6ce22f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 20591 +timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda +sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad +md5: a77f85f77be52ff59391544bfe73390a +depends: +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +license: MIT +license_family: MIT +size: 85189 +timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda +sha256: b4533f7d9efc976511a73ef7d4a2473406d7f4c750884be8e8620b0ce70f4dae +md5: 30cd29cb87d819caead4d55184c1d115 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24194 +timestamp: 1764460141901 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda +sha256: ea4e50c465d70236408cb0bfe0115609fd14db1adcd8bd30d8918e0291f8a75f +md5: 2aadb0d17215603a82a2a6b0afd9a4cb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: Zlib +license_family: Other +size: 122618 +timestamp: 1770167931827 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 +md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 +depends: +- __glibc >=2.17,<3.0.a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 601375 +timestamp: 1764777111296 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt new file mode 100644 index 000000000..a55a4d49d --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt @@ -0,0 +1,126 @@ + +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +@EXPLICIT +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 +https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda#2934f256a8acfe48f6ebb4fce6cde29c +https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c +https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda#7fe569c10905402ed47024fc481bb371 +https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda#b866ff7007b934d564961066c8195983 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 +https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda#071cf7b0ce333c81718b054066c15102 +https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.5-hecca717_0.conda#7de50d165039df32d38be74c1b34a910 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb +https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 +https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e +https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac +https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 +https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda#daddf757c3ecd6067b9af1df1f25d89e +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda#c1c368b5437b0d1a68f372ccf01cb133 +https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab +https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2#86e69bd82c2a2c6fd29f5ab7e02b3691 +https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda#e235d5566c9cc8970eb2798dd4ecf62f +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee +https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.53.0-h04a0ce9_0.conda#dc540e5bd5616d83a1ec46af8315ff98 +https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2#b3723b235b0758abaae8c82ce4d80146 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 +https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 +https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda#ba0a9221ce1063f31692c07370d062f3 +https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 +https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 +https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda#e941e85e273121222580723010bd4fa2 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.40.0-py310hbcd5346_0.conda#03a6899e17bb731c8e21b08212f1a64c +https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda#ef0340e75068ac8ff96462749b5c98e7 +https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda#2035f68f96be30dc60a5dfd7452c7941 +https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda#e17be1016bcc3516827b836cd3e4d9dc +https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.3-py314h2e6c369_0.conda#1f3fd537f929b8d3236f9f0f0e7f7a32 +https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda#a0a4a3035667fc34f29bfbd5c190baa6 +https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.3-pyhcf101f3_0.conda#f690e6f204efd2e5c06b57518a383d98 +https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda#130584ad9f3a513cdd71b1fdc1244e9c +https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2#310259a5b03ff02289d7705f39e2b1d2 +https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 +https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda#0242025a3c804966bf71aa04eee82f66 +https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda#0c20a8ebcddb24a45da89d5e917e6cb9 +https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda#472239e4eb7b5a84bb96b3ed7e3a596a +https://conda.anaconda.org/conda-forge/linux-64/regex-2026.4.4-py314h5bd0f2a_0.conda#4ffb42385183c854564f1f9adcf80a63 +https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda#d705f9d8a1185a2b01cced191177a028 +https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda#e5ce43272193b38c2e9037446c1d9206 +https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda#260af1b0a94f719de76b4e14094e9a3b +https://conda.anaconda.org/bioconda/noarch/multiqc-1.34-pyhdfd78af_0.conda#a7111ab9a6a6146b40cbce16655ac873 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda#f2c23a77b25efcad57d377b34bd84941 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt new file mode 100644 index 000000000..a58231a01 --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt @@ -0,0 +1,1502 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-aarch64: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.4-hfae3067_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py314hac3e5ec_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.39.3-py310hff09b76_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.39.3-py310hf00a4a2_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.41.5-py314h451b6cc_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.2.28-py314h51f160d_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.52.0-hf1c7be2_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: a2527b1d81792a0ccd2c05850960df119c2b6d8f5fdec97f2db7d25dc23b1068 +md5: 468fd3bb9e1f671d36c2cbc677e56f1d +depends: +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28926 +timestamp: 1770939656741 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 +md5: aaa2a381ccc56eac91d63b6c1240312f +depends: +- cpython +- python-gil +license: MIT +license_family: MIT +size: 8191 +timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 +md5: 2934f256a8acfe48f6ebb4fce6cde29c +depends: +- python >=3.9 +- typing-extensions >=4.0.0 +license: MIT +license_family: MIT +size: 18074 +timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab +md5: c6b0543676ecb1fb2d7643941fe375f2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 64927 +timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda +noarch: generic +sha256: c31ab719d256bc6f89926131e88ecd0f0c5d003fe8481852c6424f4ec6c7eb29 +md5: a2ac7763a9ac75055b68f325d3255265 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7514 +timestamp: 1767044983590 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda +sha256: 5a5b0cdcd7ed89c6a8fb830924967f6314a2b71944bc1ebc2c105781ba97aa75 +md5: a1b5c571a0923a205d663d8678df4792 +depends: +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +constrains: +- libbrotlicommon 1.2.0 he30d5cf_1 +license: MIT +license_family: MIT +size: 373193 +timestamp: 1764017486851 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +sha256: b3495077889dde6bb370938e7db82be545c73e8589696ad0843a32221520ad4c +md5: 840d8fc0d7b3209be93080bc20e07f2d +depends: +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 192412 +timestamp: 1771350241232 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda +sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc +md5: 4492fd26db29495f0ba23f146cd5638d +depends: +- __unix +license: ISC +size: 147413 +timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda +sha256: a6b118fd1ed6099dc4fc03f9c492b88882a780fadaef4ed4f93dc70757713656 +md5: 765c4d97e877cdbbb88ff33152b86125 +depends: +- python >=3.10 +license: ISC +size: 151445 +timestamp: 1772001170301 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda +sha256: d86dfd428b2e3c364fa90e07437c8405d635aa4ef54b25ab51d9c712be4112a5 +md5: 49ee13eb9b8f44d63879c69b8a40a74b +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58510 +timestamp: 1773660086450 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda +sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 +md5: ea8a6c3256897cc31263de9f455e25d9 +depends: +- python >=3.10 +- __unix +- python +license: BSD-3-Clause +license_family: BSD +size: 97676 +timestamp: 1764518652276 +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 +md5: b866ff7007b934d564961066c8195983 +depends: +- humanfriendly >=9.1 +- python >=3.9 +license: MIT +license_family: MIT +size: 43758 +timestamp: 1733928076798 +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 +md5: 071cf7b0ce333c81718b054066c15102 +depends: +- networkx >=2.0 +- numpy +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 39326 +timestamp: 1735759976140 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda +noarch: generic +sha256: 91b06300879df746214f7363d6c27c2489c80732e46a369eb2afc234bcafb44c +md5: 3bb89e4f795e5414addaa531d6b1500a +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50078 +timestamp: 1770674447292 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.4-hfae3067_0.conda +sha256: 5f087bef054c681edcaae84a8c2230585b938691e371ff92957a30707b7fcdf7 +md5: b304307db639831ad7caabd2eac6fca6 +depends: +- libexpat 2.7.4 hfae3067_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 137701 +timestamp: 1771259543650 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda +sha256: 835aff8615dd8d8fff377679710ce81b8a2c47b6404e21a92fb349fda193a15c +md5: 0fed1ff55f4938a65907f3ecf62609db +depends: +- libexpat >=2.7.4,<3.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libgcc >=14 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +license: MIT +license_family: MIT +size: 279044 +timestamp: 1771382728182 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 +md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 +depends: +- python >=3.10 +- hyperframe >=6.1,<7 +- hpack >=4.1,<5 +- python +license: MIT +license_family: MIT +size: 95967 +timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba +md5: 0a802cb9888dd14eeefc611f05c40b6e +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 30731 +timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d +md5: 7fe569c10905402ed47024fc481bb371 +depends: +- __unix +- python >=3.9 +license: MIT +license_family: MIT +size: 73563 +timestamp: 1733928021866 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 +md5: daddf757c3ecd6067b9af1df1f25d89e +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 67994 +timestamp: 1766267728652 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 +md5: 8e6923fc12f1fe8f8c4e5c9f343256ac +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 17397 +timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda +sha256: 49ba6aed2c6b482bb0ba41078057555d29764299bc947b990708617712ef6406 +md5: 546da38c2fa9efacf203e2ad3f987c59 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: MIT +license_family: MIT +size: 12837286 +timestamp: 1773822650615 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda +sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 +md5: 53abe63df7e10a6ba605dc5f9f961d36 +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 50721 +timestamp: 1760286526795 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda +sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 +md5: 080594bf4493e6bae2607e65390c520a +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +license_family: APACHE +size: 34387 +timestamp: 1773931568510 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b +md5: 04558c96691bed63104678757beb4f8d +depends: +- markupsafe >=2.0 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 120685 +timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 +md5: ada41c863af263cc4c5fcbaff7c3e4dc +depends: +- attrs >=22.2.0 +- jsonschema-specifications >=2023.3.6 +- python >=3.10 +- referencing >=0.28.4 +- rpds-py >=0.25.0 +- python +license: MIT +license_family: MIT +size: 82356 +timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 +md5: 439cd0f567d697b20a8f45cb70a1005a +depends: +- python >=3.10 +- referencing >=0.31.0 +- python +license: MIT +license_family: MIT +size: 19236 +timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 +sha256: d3c7f4797566e6f983d16c2a87063a18e4b2d819a66230190a21584d70042755 +md5: 4f0d284f5d11e04277b552eb1c172c7f +depends: +- __glibc >=2.17,<3.0.a0 +- expat >=2.2.10,<3.0.0a0 +- fontconfig +- fonts-conda-forge +- libgcc-ng >=9.3.0 +- mathjax 2.7.* +- nspr >=4.29,<5.0a0 +- nss >=3.62,<4.0a0 +- sqlite >=3.34.0,<4.0a0 +license: MIT +license_family: MIT +size: 65750397 +timestamp: 1615199465742 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda +sha256: 379ef5e91a587137391a6149755d0e929f1a007d2dcb211318ac670a46c8596f +md5: bb960f01525b5e001608afef9d47b79c +depends: +- libgcc >=14 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 293039 +timestamp: 1768184778398 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda +sha256: 7abd913d81a9bf00abb699e8987966baa2065f5132e37e815f92d90fc6bba530 +md5: a21644fc4a83da26452a718dc9468d5f +depends: +- zstd >=1.5.7,<1.6.0a0 +constrains: +- binutils_impl_linux-aarch64 2.45.1 +license: GPL-3.0-only +license_family: GPL +size: 875596 +timestamp: 1774197520746 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +sha256: 8957fd460c1c132c8031f65fd5f56ec3807fd71b7cab2c5e2b0937b13404ab36 +md5: d13423b06447113a90b5b1366d4da171 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 240444 +timestamp: 1773114901155 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda +build_number: 5 +sha256: 700f3c03d0fba8e687a345404a45fbabe781c1cf92242382f62cef2948745ec4 +md5: 5afcea37a46f76ec1322943b3c4dfdc0 +depends: +- libopenblas >=0.3.30,<0.3.31.0a0 +- libopenblas >=0.3.30,<1.0a0 +constrains: +- mkl <2026 +- libcblas 3.11.0 5*_openblas +- liblapack 3.11.0 5*_openblas +- liblapacke 3.11.0 5*_openblas +- blas 2.305 openblas +license: BSD-3-Clause +license_family: BSD +size: 18369 +timestamp: 1765818610617 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda +build_number: 5 +sha256: 3fad5c9de161dccb4e42c8b1ae8eccb33f4ed56bccbcced9cbb0956ae7869e61 +md5: 0b2f1143ae2d0aa4c991959d0daaf256 +depends: +- libblas 3.11.0 5_haddc8a3_openblas +constrains: +- liblapack 3.11.0 5*_openblas +- liblapacke 3.11.0 5*_openblas +- blas 2.305 openblas +license: BSD-3-Clause +license_family: BSD +size: 18371 +timestamp: 1765818618899 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +sha256: 48814b73bd462da6eed2e697e30c060ae16af21e9fbed30d64feaf0aad9da392 +md5: a9138815598fe6b91a1d6782ca657b0c +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 71117 +timestamp: 1761979776756 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda +sha256: 995ce3ad96d0f4b5ed6296b051a0d7b6377718f325bc0e792fbb96b0e369dad7 +md5: 57f3b3da02a50a1be2a6fe847515417d +depends: +- libgcc >=14 +constrains: +- expat 2.7.4.* +license: MIT +license_family: MIT +size: 76564 +timestamp: 1771259530958 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +sha256: 3df4c539449aabc3443bbe8c492c01d401eea894603087fca2917aa4e1c2dea9 +md5: 2f364feefb6a7c00423e80dcb12db62a +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 55952 +timestamp: 1769456078358 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +sha256: 752e4f66283d7deb4c6fd47d88df644d8daa2aaa825a54f3bf350a625190192a +md5: a229e22d4d8814a07702b0919d8e6701 +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8125 +timestamp: 1774301094057 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +sha256: 8e6b27fe4eec4c2fa7b7769a21973734c8dba1de80086fb0213e58375ac09f4c +md5: b99ed99e42dafb27889483b3098cace7 +depends: +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 422941 +timestamp: 1774301093473 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda +sha256: 43df385bedc1cab11993c4369e1f3b04b4ca5d0ea16cba6a0e7f18dbc129fcc9 +md5: 552567ea2b61e3a3035759b2fdb3f9a6 +depends: +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_18 +- libgomp 15.2.0 h8acb6b2_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 622900 +timestamp: 1771378128706 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda +sha256: 83bb0415f59634dccfa8335d4163d1f6db00a27b36666736f9842b650b92cf2f +md5: 4feebd0fbf61075a1a9c2e9b3936c257 +depends: +- libgcc 15.2.0 h8acb6b2_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27568 +timestamp: 1771378136019 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda +sha256: 7dcd7dff2505d56fd5272a6e712ec912f50a46bf07dc6873a7e853694304e6e4 +md5: 41f261f5e4e2e8cbd236c2f1f15dae1b +depends: +- libgfortran5 15.2.0 h1b7bec0_18 +constrains: +- libgfortran-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27587 +timestamp: 1771378169244 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda +sha256: 85347670dfb4a8d4c13cd7cae54138dcf2b1606b6bede42eef5507bf5f9660c6 +md5: 574d88ce3348331e962cfa5ed451b247 +depends: +- libgcc >=15.2.0 +constrains: +- libgfortran 15.2.0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1486341 +timestamp: 1771378148102 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda +sha256: fc716f11a6a8525e27a5d332ef6a689210b0d2a4dd1133edc0f530659aa9faa6 +md5: 4faa39bf919939602e594253bd673958 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 588060 +timestamp: 1771378040807 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda +sha256: 84064c7c53a64291a585d7215fe95ec42df74203a5bf7615d33d49a3b0f08bb6 +md5: 5109d7f837a3dfdf5c60f60e311b041f +depends: +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 691818 +timestamp: 1762094728337 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda +build_number: 5 +sha256: 692222d186d3ffbc99eaf04b5b20181fd26aee1edec1106435a0a755c57cce86 +md5: 88d1e4133d1182522b403e9ba7435f04 +depends: +- libblas 3.11.0 5_haddc8a3_openblas +constrains: +- liblapacke 3.11.0 5*_openblas +- blas 2.305 openblas +- libcblas 3.11.0 5*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18392 +timestamp: 1765818627104 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda +sha256: 843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3 +md5: 96944e3c92386a12755b94619bae0b35 +depends: +- libgcc >=14 +constrains: +- xz 5.8.2.* +license: 0BSD +size: 125916 +timestamp: 1768754941722 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda +sha256: 57c0dd12d506e84541c4e877898bd2a59cca141df493d34036f18b2751e0a453 +md5: 7b9813e885482e3ccb1fa212b86d7fd0 +depends: +- libgcc >=14 +license: BSD-2-Clause +license_family: BSD +size: 114056 +timestamp: 1769482343003 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda +sha256: 794a7270ea049ec931537874cd8d2de0ef4b3cef71c055cfd8b4be6d2f4228b0 +md5: 11d7d57b7bdd01da745bbf2b67020b2e +depends: +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.30,<0.3.31.0a0 +license: BSD-3-Clause +license_family: BSD +size: 4959359 +timestamp: 1763114173544 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda +sha256: c7378c6b79de4d571d00ad1caf0a4c19d43c9c94077a761abb6ead44d891f907 +md5: be4088903b94ea297975689b3c3aeb27 +depends: +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: zlib-acknowledgement +size: 340156 +timestamp: 1770691477245 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda +sha256: 1ddaf91b44fae83856276f4cb7ce544ffe41d4b55c1e346b504c6b45f19098d6 +md5: 77891484f18eca74b8ad83694da9815e +depends: +- icu >=78.2,<79.0a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +license: blessing +size: 952296 +timestamp: 1772818881550 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda +sha256: 31fdb9ffafad106a213192d8319b9f810e05abca9c5436b60e507afb35a6bc40 +md5: f56573d05e3b735cb03efeb64a15f388 +depends: +- libgcc 15.2.0 h8acb6b2_18 +constrains: +- libstdcxx-ng ==15.2.0=*_18 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5541411 +timestamp: 1771378162499 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +sha256: 7ff79470db39e803e21b8185bc8f19c460666d5557b1378d1b1e857d929c6b39 +md5: 8c6fd84f9c87ac00636007c6131e457d +depends: +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 488407 +timestamp: 1762022048105 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda +sha256: c37a8e89b700646f3252608f8368e7eb8e2a44886b92776e57ad7601fc402a11 +md5: cf2861212053d05f27ec49c3784ff8bb +depends: +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 43453 +timestamp: 1766271546875 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +sha256: b03700a1f741554e8e5712f9b06dd67e76f5301292958cd3cb1ac8c6fdd9ed25 +md5: 24e92d0942c799db387f5c9d7b81f1af +depends: +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 359496 +timestamp: 1752160685488 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +sha256: 461cab3d5650ac6db73a367de5c8eca50363966e862dcf60181d693236b1ae7b +md5: cd14ee5cca2464a425b1dbfc24d90db2 +depends: +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 397493 +timestamp: 1727280745441 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +sha256: eb111e32e5a7313a5bf799c7fb2419051fa2fe7eff74769fac8d5a448b309f7f +md5: 502006882cf5461adced436e410046d1 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 69833 +timestamp: 1774072605429 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b +md5: ba0a9221ce1063f31692c07370d062f3 +depends: +- importlib-metadata >=4.4 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 85893 +timestamp: 1770694658918 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda +sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e +md5: 5b5203189eb668f042ac2b0826244964 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 64736 +timestamp: 1754951288511 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda +sha256: 383c188496d13a55658c06e61e7d4cdff2c9f9d5a0648769fca8250bece7e0ef +md5: e5de3c36dd548b35ff2a8aa49208dcb3 +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- jinja2 >=3.0.0 +license: BSD-3-Clause +license_family: BSD +size: 27913 +timestamp: 1772446407659 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 +sha256: 8fd4c79d6eda3d4cba73783114305a53a154ada4d1e334d4e02cb3521429599b +md5: 7b08314a6867a9d5648a1c3265e9eb8e +license: Apache-2.0 +license_family: Apache +size: 22257008 +timestamp: 1662784555011 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 +md5: 592132998493b3ff25fd7479396e8351 +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 14465 +timestamp: 1733255681319 +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda +sha256: f005760b13093362fc9c997d603dd487de32ab2e821a3cbce52a42bcb8136517 +md5: 698a8a27c2b9d8a542c70cb47099a75e +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars-lts-cpu +- pyaml-env +- pydantic >=2.7.1 +- python >=3.8,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard +license: GPL-3.0-or-later +license_family: GPL3 +size: 4198799 +timestamp: 1765300743879 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda +sha256: 541fd4390a0687228b8578247f1536a821d9261389a65585af9d1a6f2a14e1e0 +md5: 30bec5e8f4c3969e2b1bd407c5e52afb +depends: +- python >=3.10 +- python +license: MIT +size: 280459 +timestamp: 1774380620329 +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 +md5: e941e85e273121222580723010bd4fa2 +depends: +- python >=3.9 +- python +license: MIT +license_family: MIT +size: 39262 +timestamp: 1770905275632 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda +sha256: 91cfb655a68b0353b2833521dc919188db3d8a7f4c64bea2c6a7557b24747468 +md5: 182afabe009dc78d8b73100255ee6868 +depends: +- libgcc >=13 +license: X11 AND BSD-3-Clause +size: 926034 +timestamp: 1738196018799 +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 +md5: a2c1eeadae7a309daed9d62c96012a2b +depends: +- python >=3.11 +- python +constrains: +- numpy >=1.25 +- scipy >=1.11.2 +- matplotlib-base >=3.8 +- pandas >=2.0 +license: BSD-3-Clause +license_family: BSD +size: 1587439 +timestamp: 1765215107045 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda +sha256: 78a06e89285fef242e272998b292c1e621e3ee3dd4fba62ec014e503c7ec118f +md5: 6dd4f07147774bf720075a210f8026b9 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: MPL-2.0 +license_family: MOZILLA +size: 235140 +timestamp: 1762350120355 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda +sha256: 48942696889367ffd448f8dccfc080fb7e130b9938a4a3b6b20ef8e6af856463 +md5: 4540f9570d12db2150f42ba036154552 +depends: +- libgcc >=14 +- libsqlite >=3.51.0,<4.0a0 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +- nspr >=4.38,<5.0a0 +license: MPL-2.0 +license_family: MOZILLA +size: 2061869 +timestamp: 1763490303490 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda +sha256: a6d42fd88afc57c3b0a57b21a12eff7492dfc419bb61ee3f74e9ba6261dabc88 +md5: 25d896c331481145720a21e5145fad65 +depends: +- python +- libgcc >=14 +- python 3.14.* *_cp314 +- libstdcxx >=14 +- libcblas >=3.9.0,<4.0a0 +- liblapack >=3.9.0,<4.0a0 +- python_abi 3.14.* *_cp314 +- libblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8008045 +timestamp: 1773839355275 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda +sha256: bd1bc8bdde5e6c5cbac42d462b939694e40b59be6d0698f668515908640c77b8 +md5: cea962410e327262346d48d01f05936c +depends: +- libgcc >=14 +- libpng >=1.6.50,<1.7.0a0 +- libstdcxx >=14 +- libtiff >=4.7.1,<4.8.0a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-2-Clause +license_family: BSD +size: 392636 +timestamp: 1758489353577 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda +sha256: 7f8048c0e75b2620254218d72b4ae7f14136f1981c5eb555ef61645a9344505f +md5: 25f5885f11e8b1f075bccf4a2da91c60 +depends: +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3692030 +timestamp: 1769557678657 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda +sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 +md5: b76541e68fea4d511b1ac46a28dcd2c6 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 72010 +timestamp: 1769093650580 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py314hac3e5ec_0.conda +sha256: 1ca2d1616baad9bccb7ebc425ef2dcd6cebe742fbe91edf226fb606ad371ca0f +md5: d3c959c7efe560b2d7da459d69121fe9 +depends: +- python +- python 3.14.* *_cp314 +- libgcc >=14 +- zlib-ng >=2.3.3,<2.4.0a0 +- libwebp-base >=1.6.0,<2.0a0 +- tk >=8.6.13,<8.7.0a0 +- libfreetype >=2.14.1 +- libfreetype6 >=2.14.1 +- libtiff >=4.7.1,<4.8.0a0 +- lcms2 >=2.18,<3.0a0 +- python_abi 3.14.* *_cp314 +- openjpeg >=2.5.4,<3.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libxcb >=1.17.0,<2.0a0 +license: HPND +size: 1051828 +timestamp: 1770794010335 +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 +md5: 3e9427ee186846052e81fadde8ebe96a +depends: +- narwhals >=1.15.1 +- packaging +- python >=3.10 +constrains: +- ipywidgets >=7.6 +license: MIT +license_family: MIT +size: 5251872 +timestamp: 1772628857717 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda +sha256: d332c2d5002fc440ae37ed9679ffc21b552f18d20232390005d1dd3bce0888d3 +md5: d5a4e013a30dd8dfde9ab39f45aaf9c1 +depends: +- polars-runtime-32 ==1.39.3 +- python >=3.10 +- python +constrains: +- numpy >=1.16.0 +- pyarrow >=7.0.0 +- fastexcel >=0.9 +- openpyxl >=3.0.0 +- xlsx2csv >=0.8.0 +- connectorx >=0.3.2 +- deltalake >=1.0.0 +- pyiceberg >=0.7.1 +- altair >=5.4.0 +- great_tables >=0.8.0 +- polars-runtime-32 ==1.39.3 +- polars-runtime-64 ==1.39.3 +- polars-runtime-compat ==1.39.3 +license: MIT +license_family: MIT +size: 533495 +timestamp: 1774207987966 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda +sha256: e466fb31f67ba9bde18deafeb34263ca5eb25807f39ead0e9d753a8e82c4c4f4 +md5: ef0340e75068ac8ff96462749b5c98e7 +depends: +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +license: MIT +license_family: MIT +size: 3902 +timestamp: 1760206808444 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.39.3-py310hff09b76_1.conda +noarch: python +sha256: c070be507c5a90df397a47ae0299660be437d5546d68f1bc0fa4402c9f07d59e +md5: 3c1a7c6b4ba8b9fb773ace9723f8a5db +depends: +- python +- libgcc >=14 +- libstdcxx >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 34785466 +timestamp: 1774207998285 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.39.3-py310hf00a4a2_1.conda +noarch: python +sha256: 683315f1a49e47ce72bf9462419733b40b588b2b3106552d95fd4cd994e174de +md5: dd3464e2132dc3a783e76e5078870c76 +depends: +- python +- libgcc >=14 +- libstdcxx >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 34652491 +timestamp: 1774207996879 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +sha256: e9cbcbc94e151ada3d6dc365380aaaf591f65012c16d9a2abaea4b9b90adc402 +md5: ab7288cc39545556d1bc5e71ab2df9a9 +depends: +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 636733 +timestamp: 1769712412683 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +sha256: 977dfb0cb3935d748521dd80262fe7169ab82920afd38ed14b7fee2ea5ec01ba +md5: bb5a90c93e3bac3d5690acf76b4a6386 +depends: +- libgcc >=13 +license: MIT +license_family: MIT +size: 8342 +timestamp: 1726803319942 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 +md5: e17be1016bcc3516827b836cd3e4d9dc +depends: +- python >=3.9 +- pyyaml >=5.0,<=7.0 +license: MIT +license_family: MIT +size: 14645 +timestamp: 1736766960536 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda +sha256: 868569d9505b7fe246c880c11e2c44924d7613a8cdcc1f6ef85d5375e892f13d +md5: c3946ed24acdb28db1b5d63321dbca7d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- typing-extensions >=4.6.1 +- annotated-types >=0.6.0 +- pydantic-core ==2.41.5 +- python +license: MIT +license_family: MIT +size: 340482 +timestamp: 1764434463101 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.41.5-py314h451b6cc_1.conda +sha256: f8acb2d03ebe80fed0032b9a989fc9acfb6735e3cd3f8c704b72728cb31868f6 +md5: 28f5027a1e04d67aa13fac1c5ba79693 +depends: +- python +- typing-extensions >=4.6.0,!=4.7.0 +- libgcc >=14 +- python 3.14.* *_cp314 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 1828339 +timestamp: 1762989038561 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda +sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a +md5: 6b6ece66ebcae2d5f326c77ef2c5a066 +depends: +- python >=3.9 +license: BSD-2-Clause +license_family: BSD +size: 889287 +timestamp: 1750615908735 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 +md5: 461219d1a5bd61342293efa2c0c90eac +depends: +- __unix +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 21085 +timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda +build_number: 101 +sha256: 87e9dff5646aba87cecfbc08789634c855871a7325169299d749040b0923a356 +md5: 205011b36899ff0edf41b3db0eda5a44 +depends: +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-aarch64 >=2.36.1 +- libexpat >=2.7.3,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.2,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.51.2,<4.0a0 +- libuuid >=2.41.3,<3.0a0 +- libzlib >=1.3.1,<2.0a0 +- ncurses >=6.5,<7.0a0 +- openssl >=3.5.5,<4.0a0 +- python_abi 3.14.* *_cp314 +- readline >=8.3,<9.0a0 +- tk >=8.6.13,<8.7.0a0 +- tzdata +- zstd >=1.5.7,<1.6.0a0 +license: Python-2.0 +size: 37305578 +timestamp: 1770674395875 +python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 +md5: 130584ad9f3a513cdd71b1fdc1244e9c +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 27848 +timestamp: 1772388605021 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda +sha256: 233aebd94c704ac112afefbb29cf4170b7bc606e22958906f2672081bc50638a +md5: 235765e4ea0d0301c75965985163b5a1 +depends: +- cpython 3.14.3.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50062 +timestamp: 1770674497152 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 +md5: 310259a5b03ff02289d7705f39e2b1d2 +depends: +- kaleido-core 0.2.1.* +- python >=3.5 +license: MIT +license_family: MIT +size: 18320 +timestamp: 1615204747600 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +build_number: 8 +sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 +md5: 0539938c55b6b1a59b560e843ad864a4 +constrains: +- python 3.14.* *_cp314 +license: BSD-3-Clause +license_family: BSD +size: 6989 +timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda +sha256: 496b5e65dfdd0aaaaa5de0dcaaf3bceea00fcb4398acf152f89e567c82ec1046 +md5: 9ae2c92975118058bd720e9ba2bb7c58 +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +- yaml >=0.2.5,<0.3.0a0 +license: MIT +license_family: MIT +size: 195678 +timestamp: 1770223441816 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda +sha256: fe695f9d215e9a2e3dd0ca7f56435ab4df24f5504b83865e3d295df36e88d216 +md5: 3d49cad61f829f4f0e0611547a9cda12 +depends: +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-3.0-only +license_family: GPL +size: 357597 +timestamp: 1765815673644 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 +md5: 870293df500ca7e18bedefa5838a22ab +depends: +- attrs >=22.2.0 +- python >=3.10 +- rpds-py >=0.7.0 +- typing_extensions >=4.4.0 +- python +license: MIT +license_family: MIT +size: 51788 +timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.2.28-py314h51f160d_0.conda +sha256: 2080ecea825e1ef91a2422cc0bc63e85db9e38908ed17657fb8f41de7a6eee71 +md5: 818aa2c9f6b3c808da5e7be22a9a424c +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +license: Apache-2.0 AND CNRI-Python +license_family: PSF +size: 408097 +timestamp: 1772255205521 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda +sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 +md5: c65df89a0b2e321045a9e01d1337b182 +depends: +- python >=3.10 +- certifi >=2017.4.17 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.21.1,<3 +- python +constrains: +- chardet >=3.0.2,<6 +license: Apache-2.0 +license_family: APACHE +size: 63602 +timestamp: 1766926974520 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda +sha256: b06ce84d6a10c266811a7d3adbfa1c11f13393b91cc6f8a5b468277d90be9590 +md5: 7a6289c50631d620652f5045a63eb573 +depends: +- markdown-it-py >=2.2.0 +- pygments >=2.13.0,<3.0.0 +- python >=3.10 +- typing_extensions >=4.0.0,<5.0.0 +- python +license: MIT +license_family: MIT +size: 208472 +timestamp: 1771572730357 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 +md5: 0c20a8ebcddb24a45da89d5e917e6cb9 +depends: +- python >=3.10 +- rich >=12 +- click >=8 +- typing-extensions >=4 +- __unix +- python +license: MIT +license_family: MIT +size: 64356 +timestamp: 1769850479089 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda +sha256: a587240f16eac7c6a80f9585cef679cd1cb9a287b8dfcdd36dcef1f7e7db15dc +md5: e7f6ed9e60043bb5cbcc527764897f0d +depends: +- python +- libgcc >=14 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 376332 +timestamp: 1764543345455 +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 +md5: 472239e4eb7b5a84bb96b3ed7e3a596a +depends: +- colormath >=3.0.0 +- python >=3.9 +license: MIT +license_family: MIT +size: 22284 +timestamp: 1735770589188 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.52.0-hf1c7be2_0.conda +sha256: 4f8523f5341f0d9e1547085206c6c1f71f9fc7c277443ca363a8cf98add8fc01 +md5: d9634079df93a65ee045b3c75f35cae1 +depends: +- icu >=78.2,<79.0a0 +- libgcc >=14 +- libsqlite 3.52.0 h10b116e_0 +- libzlib >=1.3.1,<2.0a0 +- ncurses >=6.5,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 209416 +timestamp: 1772818891689 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda +sha256: c1da41c79262b27efa168407cfecc47b20270e5fc071a8307f95a2c85fb94170 +md5: 55bf7b559202236157b14323b40f19e6 +depends: +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- regex >=2022.1.18 +- requests >=2.26.0 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 914402 +timestamp: 1764030357702 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda +sha256: e25c314b52764219f842b41aea2c98a059f06437392268f09b03561e4f6e5309 +md5: 7fc6affb9b01e567d2ef1d05b84aa6ed +depends: +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +constrains: +- xorg-libx11 >=1.8.12,<2.0a0 +license: TCL +license_family: BSD +size: 3368666 +timestamp: 1769464148928 +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 +md5: e5ce43272193b38c2e9037446c1d9206 +depends: +- python >=3.10 +- __unix +- python +license: MPL-2.0 and MIT +size: 94132 +timestamp: 1770153424136 +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda +sha256: 39d8ae33c43cdb8f771373e149b0b4fae5a08960ac58dcca95b2f1642bb17448 +md5: 260af1b0a94f719de76b4e14094e9a3b +depends: +- importlib-metadata >=3.6 +- python >=3.10 +- typing-extensions >=4.10.0 +- typing_extensions >=4.14.0 +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 36838 +timestamp: 1771532971545 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c +md5: edd329d7d3a4ab45dcf905899a7a6115 +depends: +- typing_extensions ==4.15.0 pyhcf101f3_0 +license: PSF-2.0 +license_family: PSF +size: 91383 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda +sha256: 70db27de58a97aeb7ba7448366c9853f91b21137492e0b4430251a1870aa8ff4 +md5: a0a4a3035667fc34f29bfbd5c190baa6 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +license: MIT +license_family: MIT +size: 18923 +timestamp: 1764158430324 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 +md5: 0caa1af407ecff61170c9437a808404d +depends: +- python >=3.10 +- python +license: PSF-2.0 +license_family: PSF +size: 51692 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c +md5: ad659d0a2b3e47e38d829aa8cad2d610 +license: LicenseRef-Public-Domain +size: 119135 +timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda +sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a +md5: 9272daa869e03efe68833e3dc7a02130 +depends: +- backports.zstd >=1.0.0 +- brotli-python >=1.2.0 +- h2 >=4,<5 +- pysocks >=1.5.6,<2.0,!=1.5.7 +- python >=3.10 +license: MIT +license_family: MIT +size: 103172 +timestamp: 1767817860341 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +sha256: e9f6e931feeb2f40e1fdbafe41d3b665f1ab6cb39c5880a1fcf9f79a3f3c84a5 +md5: 1c246e1105000c3660558459e2fd6d43 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 16317 +timestamp: 1762977521691 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +sha256: 128d72f36bcc8d2b4cdbec07507542e437c7d67f677b7d77b71ed9eeac7d6df1 +md5: bff06dcde4a707339d66d45d96ceb2e2 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 21039 +timestamp: 1762979038025 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda +sha256: 66265e943f32ce02396ad214e27cb35f5b0490b3bd4f064446390f9d67fa5d88 +md5: 032d8030e4a24fe1f72c74423a46fb88 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 88088 +timestamp: 1753484092643 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda +sha256: b4533f7d9efc976511a73ef7d4a2473406d7f4c750884be8e8620b0ce70f4dae +md5: 30cd29cb87d819caead4d55184c1d115 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24194 +timestamp: 1764460141901 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda +sha256: 638a3a41a4fbfed52d3c60c8ef5a3693b3f12a5b1a3f58fa29f5698d0a0702e2 +md5: f731af71c723065d91b4c01bb822641b +depends: +- libgcc >=14 +- libstdcxx >=14 +license: Zlib +license_family: Other +size: 121046 +timestamp: 1770167944449 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +sha256: 569990cf12e46f9df540275146da567d9c618c1e9c7a0bc9d9cfefadaed20b75 +md5: c3655f82dcea2aa179b291e7099c1fcc +depends: +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 614429 +timestamp: 1764777145593 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt new file mode 100644 index 000000000..f787dbe1e --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt @@ -0,0 +1,125 @@ + +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-aarch64 +@EXPLICIT +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda#4faa39bf919939602e594253bd673958 +https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda#552567ea2b61e3a3035759b2fdb3f9a6 +https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda#840d8fc0d7b3209be93080bc20e07f2d +https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda#502006882cf5461adced436e410046d1 +https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc +https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda#a21644fc4a83da26452a718dc9468d5f +https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda#05d1e0b30acd816a192c03dc6e164f4d +https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a +https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda#76298a9e6d71ee6e832a8d0d7373b261 +https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda#7b9813e885482e3ccb1fa212b86d7fd0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0.conda#86db4036fd08bf34e991bf48a8af405d +https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab +https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 +https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda#3b129669089e4d6a5c6871dbb4669b99 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 +https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda#3d49cad61f829f4f0e0611547a9cda12 +https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.4-hfd9ac0a_100_cp314.conda#3cfbe780f0f51cc8cba41db9f8a28bfe +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 +https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda#2934f256a8acfe48f6ebb4fce6cde29c +https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 +https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda#a1b5c571a0923a205d663d8678df4792 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c +https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda#7fe569c10905402ed47024fc481bb371 +https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda#b866ff7007b934d564961066c8195983 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b +https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.32-pthreads_h9d3fd7e_0.conda#5d2ce5cf40443d055ec6d33840192265 +https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce +https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda#25d896c331481145720a21e5145fad65 +https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda#071cf7b0ce333c81718b054066c15102 +https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.5-hfae3067_0.conda#d2bb0c889d94f2fdc5856392c3002976 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb +https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda#f51503ac45a4888bce71af9027a2ecc9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda#b99ed99e42dafb27889483b3098cace7 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 +https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 +https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e +https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac +https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 +https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda#daddf757c3ecd6067b9af1df1f25d89e +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a +https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda#e5de3c36dd548b35ff2a8aa49208dcb3 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d +https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda#e7f6ed9e60043bb5cbcc527764897f0d +https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab +https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 +https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2#7b08314a6867a9d5648a1c3265e9eb8e +https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda#6dd4f07147774bf720075a210f8026b9 +https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda#4540f9570d12db2150f42ba036154552 +https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.53.0-he8854b5_0.conda#ad8164bdeece883b825c50639c0c4725 +https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2#4f0d284f5d11e04277b552eb1c172c7f +https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda#a85ba48648f6868016f2741fd9170250 +https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda#d13423b06447113a90b5b1366d4da171 +https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c +https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af +https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d +https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c +https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 +https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda#ba0a9221ce1063f31692c07370d062f3 +https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 +https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 +https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda#e941e85e273121222580723010bd4fa2 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c +https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py314hac3e5ec_0.conda#87d58d103b47c4a8567b3d7666647684 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a +https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.40.0-py310hff09b76_0.conda#d5628a33ce7652511e38fc98643dc910 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 +https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.40.0-py310hf00a4a2_0.conda#a82af0fcbb72db253dc89a7a45279372 +https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda#ef0340e75068ac8ff96462749b5c98e7 +https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda#032d8030e4a24fe1f72c74423a46fb88 +https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda#9ae2c92975118058bd720e9ba2bb7c58 +https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda#e17be1016bcc3516827b836cd3e4d9dc +https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.3-py314h451b6cc_0.conda#1a2cb55be9a153ad6203bff6b787c240 +https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda#a0a4a3035667fc34f29bfbd5c190baa6 +https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.3-pyhcf101f3_0.conda#f690e6f204efd2e5c06b57518a383d98 +https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda#130584ad9f3a513cdd71b1fdc1244e9c +https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2#310259a5b03ff02289d7705f39e2b1d2 +https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 +https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda#0242025a3c804966bf71aa04eee82f66 +https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda#0c20a8ebcddb24a45da89d5e917e6cb9 +https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda#472239e4eb7b5a84bb96b3ed7e3a596a +https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.4.4-py314h51f160d_0.conda#88a3dbd279e6b1faf0cddb8397866864 +https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda#55bf7b559202236157b14323b40f19e6 +https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda#e5ce43272193b38c2e9037446c1d9206 +https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda#260af1b0a94f719de76b4e14094e9a3b +https://conda.anaconda.org/bioconda/noarch/multiqc-1.34-pyhdfd78af_0.conda#a7111ab9a6a6146b40cbce16655ac873 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda#ab7288cc39545556d1bc5e71ab2df9a9 diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index a27122ce1..37e7612d4 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.27 + - bioconda::multiqc=1.34 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 58d9313c6..e80e8cd8d 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,24 +1,21 @@ process MULTIQC { + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.27--pyhdfd78af_0' : - 'biocontainers/multiqc:1.27--pyhdfd78af_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/1b/1bef8af6be88c5733461959c46ac8ef73d18f65277f62a1695d0e1633054f9c2/data' + : 'community.wave.seqera.io/library/multiqc:1.34--db7c73dae76bc9e6'}" input: - path multiqc_files, stageAs: "?/*" - path(multiqc_config) - path(extra_multiqc_config) - path(multiqc_logo) - path(replace_names) - path(sample_names) + tuple val(meta), path(multiqc_files, stageAs: "?/*"), path(multiqc_config, stageAs: "?/*"), path(multiqc_logo), path(replace_names), path(sample_names) output: - path "*multiqc_report.html", emit: report - path "*_data" , emit: data - path "*_plots" , optional:true, emit: plots - path "versions.yml" , emit: versions + tuple val(meta), path("*.html"), emit: report + tuple val(meta), path("*_data"), emit: data + tuple val(meta), path("*_plots"), emit: plots, optional: true + // MultiQC should not push its versions to the `versions` topic. Its input depends on the versions topic to be resolved thus outputting to the topic will let the pipeline hang forever + tuple val("${task.process}"), val('multiqc'), eval('multiqc --version | sed "s/.* //g"'), emit: versions when: task.ext.when == null || task.ext.when @@ -26,38 +23,28 @@ process MULTIQC { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' - def config = multiqc_config ? "--config $multiqc_config" : '' - def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' + def config = multiqc_config ? multiqc_config instanceof List ? "--config ${multiqc_config.join(' --config ')}" : "--config ${multiqc_config}" : "" def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' def replace = replace_names ? "--replace-names ${replace_names}" : '' def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ - $args \\ - $config \\ - $prefix \\ - $extra_config \\ - $logo \\ - $replace \\ - $samples \\ + ${args} \\ + ${config} \\ + ${prefix} \\ + ${logo} \\ + ${replace} \\ + ${samples} \\ . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ stub: """ mkdir multiqc_data + touch multiqc_data/.stub mkdir multiqc_plots + touch multiqc_plots/.stub touch multiqc_report.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ } diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index b16c18792..2facc627b 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,6 +1,6 @@ name: multiqc -description: Aggregate results from bioinformatics analyses across many samples into - a single report +description: Aggregate results from bioinformatics analyses across many samples + into a single report keywords: - QC - bioinformatics tools @@ -12,60 +12,91 @@ tools: It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ - licence: ["GPL-3.0-or-later"] + licence: + - "GPL-3.0-or-later" identifier: biotools:multiqc input: - - - multiqc_files: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - multiqc_files: type: file description: | List of reports / files recognised by MultiQC, for example the html and zip output of FastQC - - - multiqc_config: + ontologies: [] + - multiqc_config: type: file description: Optional config yml for MultiQC pattern: "*.{yml,yaml}" - - - extra_multiqc_config: - type: file - description: Second optional config yml for MultiQC. Will override common sections - in multiqc_config. - pattern: "*.{yml,yaml}" - - - multiqc_logo: + ontologies: + - edam: http://edamontology.org/format_3750 + - multiqc_logo: type: file description: Optional logo file for MultiQC pattern: "*.{png}" - - - replace_names: + ontologies: [] + - replace_names: type: file description: | Optional two-column sample renaming file. First column a set of patterns, second column a set of corresponding replacements. Passed via MultiQC's `--replace-names` option. pattern: "*.{tsv}" - - - sample_names: + ontologies: + - edam: http://edamontology.org/format_3475 + - sample_names: type: file description: | Optional TSV file with headers, passed to the MultiQC --sample_names argument. pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 output: - - report: - - "*multiqc_report.html": + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*.html": type: file description: MultiQC report file - pattern: "multiqc_report.html" - - data: + pattern: ".html" + ontologies: [] + data: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] - "*_data": type: directory description: MultiQC data dir pattern: "multiqc_data" - - plots: + plots: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] - "*_plots": type: file description: Plots created by MultiQC - pattern: "*_data" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + pattern: "*_plots" + ontologies: [] + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - multiqc: + type: string + description: The tool name + - multiqc --version | sed "s/.* //g": + type: eval + description: The expression to obtain the version of the tool authors: - "@abhi18av" - "@bunop" @@ -76,3 +107,27 @@ maintainers: - "@bunop" - "@drpatelh" - "@jfy133" +containers: + conda: + linux/amd64: + lock_file: modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt + linux/arm64: + lock_file: modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt + docker: + linux/amd64: + name: community.wave.seqera.io/library/multiqc:1.34--db7c73dae76bc9e6 + build_id: bd-db7c73dae76bc9e6_1 + scan_id: sc-66fc7138dbf1cf48_1 + linux/arm64: + name: community.wave.seqera.io/library/multiqc:1.34--d167b8012595a136 + build_id: bd-d167b8012595a136_1 + scan_id: sc-ac701dfa631a2af9_1 + singularity: + linux/amd64: + name: oras://community.wave.seqera.io/library/multiqc:1.34--4fc8657c816047c0 + build_id: bd-4fc8657c816047c0_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/1b/1bef8af6be88c5733461959c46ac8ef73d18f65277f62a1695d0e1633054f9c2/data + linux/arm64: + name: oras://community.wave.seqera.io/library/multiqc:1.34--7fbd82d945c06726 + build_id: bd-7fbd82d945c06726_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9a/9a1fec9662a152683e6fcae440d0ce20920b3b89dc62d1e3a52e73f92eba0969/data diff --git a/modules/nf-core/multiqc/tests/custom_prefix.config b/modules/nf-core/multiqc/tests/custom_prefix.config new file mode 100644 index 000000000..b30b1358b --- /dev/null +++ b/modules/nf-core/multiqc/tests/custom_prefix.config @@ -0,0 +1,5 @@ +process { + withName: 'MULTIQC' { + ext.prefix = "custom_prefix" + } +} diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test index 33316a7dd..4cbdb95d4 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test +++ b/modules/nf-core/multiqc/tests/main.nf.test @@ -15,25 +15,84 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] - input[5] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) """ } } then { - assertAll( - { assert process.success }, - { assert process.out.report[0] ==~ ".*/multiqc_report.html" }, - { assert process.out.data[0] ==~ ".*/multiqc_data" }, - { assert snapshot(process.out.versions).match("multiqc_versions_single") } - ) + assert process.success + assert snapshot( + sanitizeOutput(process.out).collectEntries { key, val -> + if (key == "data") { + return [key, val.collect { [path(it[1]).list().collect { file(it.toString()).name }] }] + } + else if (key == "plots") { + return [key, val.collect { [ + "pdf", + path("${it[1]}/pdf").list().collect { file(it.toString()).name }, + "png", + path("${it[1]}/png").list().collect { file(it.toString()).name }, + "svg", + path("${it[1]}/svg").list().collect { file(it.toString()).name }] }] + } + else if (key == "report") { + return [key, file(val[0][1].toString()).name] + } + return [key, val] + } + ).match() + } + } + + test("sarscov2 single-end [fastqc] - custom prefix") { + config "./custom_prefix.config" + + when { + process { + """ + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) + """ + } } + then { + assert process.success + assert snapshot( + sanitizeOutput(process.out).collectEntries { key, val -> + if (key == "data") { + return [key, val.collect { [path(it[1]).list().collect { file(it.toString()).name }] }] + } + else if (key == "plots") { + return [key, val.collect { [ + "pdf", + path("${it[1]}/pdf").list().collect { file(it.toString()).name }, + "png", + path("${it[1]}/png").list().collect { file(it.toString()).name }, + "svg", + path("${it[1]}/svg").list().collect { file(it.toString()).name }] }] + } + else if (key == "report") { + return [key, file(val[0][1].toString()).name] + } + return [key, val] + } + ).match() + } } test("sarscov2 single-end [fastqc] [config]") { @@ -41,23 +100,85 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - input[1] = Channel.of(file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true)) - input[2] = [] - input[3] = [] - input[4] = [] - input[5] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + file("https://raw.githubusercontent.com/nf-core/seqinspector/1.0.0/assets/multiqc_config.yml", checkIfExists: true), + [], + [], + [] + ]) """ } } then { - assertAll( - { assert process.success }, - { assert process.out.report[0] ==~ ".*/multiqc_report.html" }, - { assert process.out.data[0] ==~ ".*/multiqc_data" }, - { assert snapshot(process.out.versions).match("multiqc_versions_config") } - ) + assert process.success + assert snapshot( + sanitizeOutput(process.out).collectEntries { key, val -> + if (key == "data") { + return [key, val.collect { [path(it[1]).list().collect { file(it.toString()).name }] }] + } + else if (key == "plots") { + return [key, val.collect { [ + "pdf", + path("${it[1]}/pdf").list().collect { file(it.toString()).name }, + "png", + path("${it[1]}/png").list().collect { file(it.toString()).name }, + "svg", + path("${it[1]}/svg").list().collect { file(it.toString()).name }] }] + } + else if (key == "report") { + return [key, file(val[0][1].toString()).name] + } + return [key, val] + } + ).match() + } + } + + test("sarscov2 single-end [fastqc] [multiple configs]") { + + when { + process { + """ + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [ + file("https://raw.githubusercontent.com/nf-core/seqinspector/1.0.0/assets/multiqc_config.yml", checkIfExists: true), + file("https://raw.githubusercontent.com/nf-core/seqinspector/1.0.0/assets/multiqc_config.yml", checkIfExists: true) + ], + [], + [], + [] + ]) + """ + } + } + + then { + assert process.success + assert snapshot( + sanitizeOutput(process.out).collectEntries { key, val -> + if (key == "data") { + return [key, val.collect { [path(it[1]).list().collect { file(it.toString()).name }] }] + } + else if (key == "plots") { + return [key, val.collect { [ + "pdf", + path("${it[1]}/pdf").list().collect { file(it.toString()).name }, + "png", + path("${it[1]}/png").list().collect { file(it.toString()).name }, + "svg", + path("${it[1]}/svg").list().collect { file(it.toString()).name }] }] + } + else if (key == "report") { + return [key, file(val[0][1].toString()).name] + } + return [key, val] + } + ).match() } } @@ -68,25 +189,23 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] - input[5] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out.report.collect { file(it).getName() } + - process.out.data.collect { file(it).getName() } + - process.out.plots.collect { file(it).getName() } + - process.out.versions ).match("multiqc_stub") } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } } diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index 7b7c13220..7c2f370f3 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -1,41 +1,422 @@ { - "multiqc_versions_single": { + "sarscov2 single-end [fastqc] [multiple configs]": { "content": [ - [ - "versions.yml:md5,8f3b8c1cec5388cf2708be948c9fa42f" - ] + { + "data": [ + [ + [ + "fastqc-status-check-heatmap.txt", + "fastqc_overrepresented_sequences_plot.txt", + "fastqc_per_base_n_content_plot.txt", + "fastqc_per_base_sequence_quality_plot.txt", + "fastqc_per_sequence_gc_content_plot_Counts.txt", + "fastqc_per_sequence_gc_content_plot_Percentages.txt", + "fastqc_per_sequence_quality_scores_plot.txt", + "fastqc_sequence_counts_plot.txt", + "fastqc_sequence_duplication_levels_plot.txt", + "fastqc_sequence_length_distribution_plot.txt", + "fastqc_top_overrepresented_sequences_table.txt", + "llms-full.txt", + "multiqc.log", + "multiqc.parquet", + "multiqc_citations.txt", + "multiqc_data.json", + "multiqc_fastqc.txt", + "multiqc_general_stats.txt", + "multiqc_sources.txt" + ] + ] + ], + "plots": [ + [ + "pdf", + [ + "fastqc-status-check-heatmap.pdf", + "fastqc_overrepresented_sequences_plot.pdf", + "fastqc_per_base_n_content_plot.pdf", + "fastqc_per_base_sequence_quality_plot.pdf", + "fastqc_per_sequence_gc_content_plot_Counts.pdf", + "fastqc_per_sequence_gc_content_plot_Percentages.pdf", + "fastqc_per_sequence_quality_scores_plot.pdf", + "fastqc_sequence_counts_plot-cnt.pdf", + "fastqc_sequence_counts_plot-pct.pdf", + "fastqc_sequence_duplication_levels_plot.pdf", + "fastqc_sequence_length_distribution_plot.pdf", + "fastqc_top_overrepresented_sequences_table.pdf" + ], + "png", + [ + "fastqc-status-check-heatmap.png", + "fastqc_overrepresented_sequences_plot.png", + "fastqc_per_base_n_content_plot.png", + "fastqc_per_base_sequence_quality_plot.png", + "fastqc_per_sequence_gc_content_plot_Counts.png", + "fastqc_per_sequence_gc_content_plot_Percentages.png", + "fastqc_per_sequence_quality_scores_plot.png", + "fastqc_sequence_counts_plot-cnt.png", + "fastqc_sequence_counts_plot-pct.png", + "fastqc_sequence_duplication_levels_plot.png", + "fastqc_sequence_length_distribution_plot.png", + "fastqc_top_overrepresented_sequences_table.png" + ], + "svg", + [ + "fastqc-status-check-heatmap.svg", + "fastqc_overrepresented_sequences_plot.svg", + "fastqc_per_base_n_content_plot.svg", + "fastqc_per_base_sequence_quality_plot.svg", + "fastqc_per_sequence_gc_content_plot_Counts.svg", + "fastqc_per_sequence_gc_content_plot_Percentages.svg", + "fastqc_per_sequence_quality_scores_plot.svg", + "fastqc_sequence_counts_plot-cnt.svg", + "fastqc_sequence_counts_plot-pct.svg", + "fastqc_sequence_duplication_levels_plot.svg", + "fastqc_sequence_length_distribution_plot.svg", + "fastqc_top_overrepresented_sequences_table.svg" + ] + ] + ], + "report": "multiqc_report.html", + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.34" + ] + ] + } ], + "timestamp": "2026-03-17T16:15:42.577775492", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-01-27T09:29:57.631982377" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, - "multiqc_stub": { + "sarscov2 single-end [fastqc]": { "content": [ - [ - "multiqc_report.html", - "multiqc_data", - "multiqc_plots", - "versions.yml:md5,8f3b8c1cec5388cf2708be948c9fa42f" - ] + { + "data": [ + [ + [ + "fastqc-status-check-heatmap.txt", + "fastqc_overrepresented_sequences_plot.txt", + "fastqc_per_base_n_content_plot.txt", + "fastqc_per_base_sequence_quality_plot.txt", + "fastqc_per_sequence_gc_content_plot_Counts.txt", + "fastqc_per_sequence_gc_content_plot_Percentages.txt", + "fastqc_per_sequence_quality_scores_plot.txt", + "fastqc_sequence_counts_plot.txt", + "fastqc_sequence_duplication_levels_plot.txt", + "fastqc_sequence_length_distribution_plot.txt", + "fastqc_top_overrepresented_sequences_table.txt", + "llms-full.txt", + "multiqc.log", + "multiqc.parquet", + "multiqc_citations.txt", + "multiqc_data.json", + "multiqc_fastqc.txt", + "multiqc_general_stats.txt", + "multiqc_software_versions.txt", + "multiqc_sources.txt" + ] + ] + ], + "plots": [ + [ + "pdf", + [ + "fastqc-status-check-heatmap.pdf", + "fastqc_overrepresented_sequences_plot.pdf", + "fastqc_per_base_n_content_plot.pdf", + "fastqc_per_base_sequence_quality_plot.pdf", + "fastqc_per_sequence_gc_content_plot_Counts.pdf", + "fastqc_per_sequence_gc_content_plot_Percentages.pdf", + "fastqc_per_sequence_quality_scores_plot.pdf", + "fastqc_sequence_counts_plot-cnt.pdf", + "fastqc_sequence_counts_plot-pct.pdf", + "fastqc_sequence_duplication_levels_plot.pdf", + "fastqc_sequence_length_distribution_plot.pdf", + "fastqc_top_overrepresented_sequences_table.pdf" + ], + "png", + [ + "fastqc-status-check-heatmap.png", + "fastqc_overrepresented_sequences_plot.png", + "fastqc_per_base_n_content_plot.png", + "fastqc_per_base_sequence_quality_plot.png", + "fastqc_per_sequence_gc_content_plot_Counts.png", + "fastqc_per_sequence_gc_content_plot_Percentages.png", + "fastqc_per_sequence_quality_scores_plot.png", + "fastqc_sequence_counts_plot-cnt.png", + "fastqc_sequence_counts_plot-pct.png", + "fastqc_sequence_duplication_levels_plot.png", + "fastqc_sequence_length_distribution_plot.png", + "fastqc_top_overrepresented_sequences_table.png" + ], + "svg", + [ + "fastqc-status-check-heatmap.svg", + "fastqc_overrepresented_sequences_plot.svg", + "fastqc_per_base_n_content_plot.svg", + "fastqc_per_base_sequence_quality_plot.svg", + "fastqc_per_sequence_gc_content_plot_Counts.svg", + "fastqc_per_sequence_gc_content_plot_Percentages.svg", + "fastqc_per_sequence_quality_scores_plot.svg", + "fastqc_sequence_counts_plot-cnt.svg", + "fastqc_sequence_counts_plot-pct.svg", + "fastqc_sequence_duplication_levels_plot.svg", + "fastqc_sequence_length_distribution_plot.svg", + "fastqc_top_overrepresented_sequences_table.svg" + ] + ] + ], + "report": "multiqc_report.html", + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.34" + ] + ] + } ], + "timestamp": "2026-03-17T16:21:17.072841555", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-01-27T09:30:34.743726958" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, - "multiqc_versions_config": { + "sarscov2 single-end [fastqc] - stub": { "content": [ - [ - "versions.yml:md5,8f3b8c1cec5388cf2708be948c9fa42f" - ] + { + "data": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "plots": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "report": [ + [ + { + "id": "FASTQC" + }, + "multiqc_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.34" + ] + ] + } ], + "timestamp": "2026-02-26T15:14:39.789193051", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-01-27T09:30:21.44383553" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 single-end [fastqc] [config]": { + "content": [ + { + "data": [ + [ + [ + "fastqc-status-check-heatmap.txt", + "fastqc_overrepresented_sequences_plot.txt", + "fastqc_per_base_n_content_plot.txt", + "fastqc_per_base_sequence_quality_plot.txt", + "fastqc_per_sequence_gc_content_plot_Counts.txt", + "fastqc_per_sequence_gc_content_plot_Percentages.txt", + "fastqc_per_sequence_quality_scores_plot.txt", + "fastqc_sequence_counts_plot.txt", + "fastqc_sequence_duplication_levels_plot.txt", + "fastqc_sequence_length_distribution_plot.txt", + "fastqc_top_overrepresented_sequences_table.txt", + "llms-full.txt", + "multiqc.log", + "multiqc.parquet", + "multiqc_citations.txt", + "multiqc_data.json", + "multiqc_fastqc.txt", + "multiqc_general_stats.txt", + "multiqc_sources.txt" + ] + ] + ], + "plots": [ + [ + "pdf", + [ + "fastqc-status-check-heatmap.pdf", + "fastqc_overrepresented_sequences_plot.pdf", + "fastqc_per_base_n_content_plot.pdf", + "fastqc_per_base_sequence_quality_plot.pdf", + "fastqc_per_sequence_gc_content_plot_Counts.pdf", + "fastqc_per_sequence_gc_content_plot_Percentages.pdf", + "fastqc_per_sequence_quality_scores_plot.pdf", + "fastqc_sequence_counts_plot-cnt.pdf", + "fastqc_sequence_counts_plot-pct.pdf", + "fastqc_sequence_duplication_levels_plot.pdf", + "fastqc_sequence_length_distribution_plot.pdf", + "fastqc_top_overrepresented_sequences_table.pdf" + ], + "png", + [ + "fastqc-status-check-heatmap.png", + "fastqc_overrepresented_sequences_plot.png", + "fastqc_per_base_n_content_plot.png", + "fastqc_per_base_sequence_quality_plot.png", + "fastqc_per_sequence_gc_content_plot_Counts.png", + "fastqc_per_sequence_gc_content_plot_Percentages.png", + "fastqc_per_sequence_quality_scores_plot.png", + "fastqc_sequence_counts_plot-cnt.png", + "fastqc_sequence_counts_plot-pct.png", + "fastqc_sequence_duplication_levels_plot.png", + "fastqc_sequence_length_distribution_plot.png", + "fastqc_top_overrepresented_sequences_table.png" + ], + "svg", + [ + "fastqc-status-check-heatmap.svg", + "fastqc_overrepresented_sequences_plot.svg", + "fastqc_per_base_n_content_plot.svg", + "fastqc_per_base_sequence_quality_plot.svg", + "fastqc_per_sequence_gc_content_plot_Counts.svg", + "fastqc_per_sequence_gc_content_plot_Percentages.svg", + "fastqc_per_sequence_quality_scores_plot.svg", + "fastqc_sequence_counts_plot-cnt.svg", + "fastqc_sequence_counts_plot-pct.svg", + "fastqc_sequence_duplication_levels_plot.svg", + "fastqc_sequence_length_distribution_plot.svg", + "fastqc_top_overrepresented_sequences_table.svg" + ] + ] + ], + "report": "multiqc_report.html", + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.34" + ] + ] + } + ], + "timestamp": "2026-03-17T16:15:30.372239611", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 single-end [fastqc] - custom prefix": { + "content": [ + { + "data": [ + [ + [ + "fastqc-status-check-heatmap.txt", + "fastqc_overrepresented_sequences_plot.txt", + "fastqc_per_base_n_content_plot.txt", + "fastqc_per_base_sequence_quality_plot.txt", + "fastqc_per_sequence_gc_content_plot_Counts.txt", + "fastqc_per_sequence_gc_content_plot_Percentages.txt", + "fastqc_per_sequence_quality_scores_plot.txt", + "fastqc_sequence_counts_plot.txt", + "fastqc_sequence_duplication_levels_plot.txt", + "fastqc_sequence_length_distribution_plot.txt", + "fastqc_top_overrepresented_sequences_table.txt", + "llms-full.txt", + "multiqc.log", + "multiqc.parquet", + "multiqc_citations.txt", + "multiqc_data.json", + "multiqc_fastqc.txt", + "multiqc_general_stats.txt", + "multiqc_software_versions.txt", + "multiqc_sources.txt" + ] + ] + ], + "plots": [ + [ + "pdf", + [ + "fastqc-status-check-heatmap.pdf", + "fastqc_overrepresented_sequences_plot.pdf", + "fastqc_per_base_n_content_plot.pdf", + "fastqc_per_base_sequence_quality_plot.pdf", + "fastqc_per_sequence_gc_content_plot_Counts.pdf", + "fastqc_per_sequence_gc_content_plot_Percentages.pdf", + "fastqc_per_sequence_quality_scores_plot.pdf", + "fastqc_sequence_counts_plot-cnt.pdf", + "fastqc_sequence_counts_plot-pct.pdf", + "fastqc_sequence_duplication_levels_plot.pdf", + "fastqc_sequence_length_distribution_plot.pdf", + "fastqc_top_overrepresented_sequences_table.pdf" + ], + "png", + [ + "fastqc-status-check-heatmap.png", + "fastqc_overrepresented_sequences_plot.png", + "fastqc_per_base_n_content_plot.png", + "fastqc_per_base_sequence_quality_plot.png", + "fastqc_per_sequence_gc_content_plot_Counts.png", + "fastqc_per_sequence_gc_content_plot_Percentages.png", + "fastqc_per_sequence_quality_scores_plot.png", + "fastqc_sequence_counts_plot-cnt.png", + "fastqc_sequence_counts_plot-pct.png", + "fastqc_sequence_duplication_levels_plot.png", + "fastqc_sequence_length_distribution_plot.png", + "fastqc_top_overrepresented_sequences_table.png" + ], + "svg", + [ + "fastqc-status-check-heatmap.svg", + "fastqc_overrepresented_sequences_plot.svg", + "fastqc_per_base_n_content_plot.svg", + "fastqc_per_base_sequence_quality_plot.svg", + "fastqc_per_sequence_gc_content_plot_Counts.svg", + "fastqc_per_sequence_gc_content_plot_Percentages.svg", + "fastqc_per_sequence_quality_scores_plot.svg", + "fastqc_sequence_counts_plot-cnt.svg", + "fastqc_sequence_counts_plot-pct.svg", + "fastqc_sequence_duplication_levels_plot.svg", + "fastqc_sequence_length_distribution_plot.svg", + "fastqc_top_overrepresented_sequences_table.svg" + ] + ] + ], + "report": "custom_prefix.html", + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.34" + ] + ] + } + ], + "timestamp": "2026-03-17T16:15:18.189023981", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/multiqc/tests/nextflow.config b/modules/nf-core/multiqc/tests/nextflow.config index c537a6a3e..374dfef2c 100644 --- a/modules/nf-core/multiqc/tests/nextflow.config +++ b/modules/nf-core/multiqc/tests/nextflow.config @@ -1,5 +1,6 @@ process { withName: 'MULTIQC' { ext.prefix = null + ext.args = '-p' } } diff --git a/modules/nf-core/multiqc/tests/tags.yml b/modules/nf-core/multiqc/tests/tags.yml deleted file mode 100644 index bea6c0d37..000000000 --- a/modules/nf-core/multiqc/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -multiqc: - - modules/nf-core/multiqc/** diff --git a/modules/nf-core/ngsbits/samplegender/environment.yml b/modules/nf-core/ngsbits/samplegender/environment.yml index 932d1556a..b8793f52a 100644 --- a/modules/nf-core/ngsbits/samplegender/environment.yml +++ b/modules/nf-core/ngsbits/samplegender/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::ngs-bits=2023_02 + # renovate: datasource=conda depName=bioconda/ngs-bits + - bioconda::ngs-bits=2025_12 diff --git a/modules/nf-core/ngsbits/samplegender/main.nf b/modules/nf-core/ngsbits/samplegender/main.nf index 3562238df..39ab69b4c 100644 --- a/modules/nf-core/ngsbits/samplegender/main.nf +++ b/modules/nf-core/ngsbits/samplegender/main.nf @@ -4,18 +4,18 @@ process NGSBITS_SAMPLEGENDER { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ngs-bits:2023_02--py311ha0b7adc_2': - 'biocontainers/ngs-bits:2023_02--py311ha0b7adc_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/fb/fbf8cfd89c36e9a18a895066bb1da04b93ef585a593b0821ec7037aba6c03474/data': + 'community.wave.seqera.io/library/ngs-bits:2025_12--958625b0e620100a' }" input: tuple val(meta), path(bam), path(bai) tuple val(meta2), path(fasta) - tuple val(meta2), path(fai) + tuple val(meta3), path(fai) val method output: tuple val(meta), path("*.tsv"), emit: tsv - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('ngsbits'), eval("SampleGender --version 2>&1 | sed 's/SampleGender //'"), topic: versions, emit: versions_ngsbits when: task.ext.when == null || task.ext.when @@ -31,21 +31,11 @@ process NGSBITS_SAMPLEGENDER { -out ${prefix}.tsv \\ ${ref} \\ ${args} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ngs-bits: \$(echo \$(SampleGender --version 2>&1) | sed 's/SampleGender //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ngs-bits: \$(echo \$(SampleGender --version 2>&1) | sed 's/SampleGender //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/ngsbits/samplegender/meta.yml b/modules/nf-core/ngsbits/samplegender/meta.yml index 54a611812..8d4773efe 100644 --- a/modules/nf-core/ngsbits/samplegender/meta.yml +++ b/modules/nf-core/ngsbits/samplegender/meta.yml @@ -11,7 +11,8 @@ tools: homepage: "https://github.com/imgag/ngs-bits" documentation: "https://github.com/imgag/ngs-bits" tool_dev_url: "https://github.com/imgag/ngs-bits" - licence: ["MIT"] + licence: + - "MIT" identifier: "" input: - - meta: @@ -23,10 +24,12 @@ input: type: file description: One or more BAM/CRAM files to determine the gender of pattern: "*.{bam,cram}" + ontologies: [] - bai: type: file description: The index file(s) from the input BAM/CRAM file(s) pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -34,9 +37,11 @@ input: e.g. [ id:'test' ] - fasta: type: file - description: The reference FASTA to use (mandatory when CRAM files are used) + description: The reference FASTA to use (mandatory when CRAM files are + used) pattern: "*.{fasta,fa,fna}" - - - meta2: + ontologies: [] + - - meta3: type: map description: | Groovy Map containing reference fasta information @@ -45,27 +50,47 @@ input: type: file description: The index file from the reference FASTA pattern: "*.fai" - - - method: - type: string - description: The method to use to define the gender (posibilities are 'xy', - 'hetx' and 'sry') - pattern: "(xy|hetx|sry)" + ontologies: [] + - method: + type: string + description: The method to use to define the gender (possibilities are 'xy', + 'hetx' and 'sry') + pattern: "(xy|hetx|sry)" output: - - tsv: - - meta: + tsv: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.tsv": type: file - description: An output TSV file containing the results of the gender prediction + description: An output TSV file containing the results of the gender + prediction pattern: "*.tsv" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 + versions_ngsbits: + - - ${task.process}: + type: string + description: The name of the process + - ngsbits: + type: string + description: The name of the tool + - SampleGender --version 2>&1 | sed 's/SampleGender //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - ngsbits: + type: string + description: The name of the tool + - SampleGender --version 2>&1 | sed 's/SampleGender //': + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" maintainers: diff --git a/modules/nf-core/ngsbits/samplegender/tests/main.nf.test b/modules/nf-core/ngsbits/samplegender/tests/main.nf.test index 4f8379b40..0917b7dde 100644 --- a/modules/nf-core/ngsbits/samplegender/tests/main.nf.test +++ b/modules/nf-core/ngsbits/samplegender/tests/main.nf.test @@ -9,7 +9,7 @@ nextflow_process { tag "ngsbits" tag "ngsbits/samplegender" - // Only a stub test here because the modules needs the full chrX and chrY + // Only a stub test here because the module needs the full chrX and chrY test("homo_sapiens - bam, bai, [], [], sry - stub") { options "-stub" diff --git a/modules/nf-core/ngsbits/samplegender/tests/main.nf.test.snap b/modules/nf-core/ngsbits/samplegender/tests/main.nf.test.snap index 48fd8af9c..f6343474d 100644 --- a/modules/nf-core/ngsbits/samplegender/tests/main.nf.test.snap +++ b/modules/nf-core/ngsbits/samplegender/tests/main.nf.test.snap @@ -11,7 +11,11 @@ ] ], "1": [ - "versions.yml:md5,72f3e70be3e6a734bf39d1a6bf6d604b" + [ + "NGSBITS_SAMPLEGENDER", + "ngsbits", + "2025_12" + ] ], "tsv": [ [ @@ -21,15 +25,19 @@ "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,72f3e70be3e6a734bf39d1a6bf6d604b" + "versions_ngsbits": [ + [ + "NGSBITS_SAMPLEGENDER", + "ngsbits", + "2025_12" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.02.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-18T15:36:37.639882564" + "timestamp": "2026-02-16T09:21:42.78314623" } } \ No newline at end of file diff --git a/modules/nf-core/ngsbits/samplegender/tests/tags.yml b/modules/nf-core/ngsbits/samplegender/tests/tags.yml deleted file mode 100644 index 8b7a0da9e..000000000 --- a/modules/nf-core/ngsbits/samplegender/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -ngsbits/samplegender: - - "modules/nf-core/ngsbits/samplegender/**" diff --git a/modules/nf-core/peddy/environment.yml b/modules/nf-core/peddy/environment.yml index 8d7fa2b6a..6deea82ac 100644 --- a/modules/nf-core/peddy/environment.yml +++ b/modules/nf-core/peddy/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - bioconda::peddy=0.4.8 + - conda-forge::numpy=1.26.4 diff --git a/modules/nf-core/peddy/main.nf b/modules/nf-core/peddy/main.nf index 0e533ec3b..ba91db235 100644 --- a/modules/nf-core/peddy/main.nf +++ b/modules/nf-core/peddy/main.nf @@ -4,26 +4,35 @@ process PEDDY { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/peddy:0.4.8--pyh5e36f6f_0' : - 'biocontainers/peddy:0.4.8--pyh5e36f6f_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4d/4db23bec88305fd6ded604f143d6292303a9822677e007fbdc14f9a763e097ec/data' : + 'community.wave.seqera.io/library/peddy_numpy:a2456db0b53651ad' }" input: tuple val(meta), path(vcf), path(vcf_tbi) - path ped + tuple val(meta2), path(ped) + tuple val(meta3), path(sites) output: - tuple val(meta), path("*.html") , emit: html - tuple val(meta), path("*.csv") , emit: csv - tuple val(meta), path("*.peddy.ped"), emit: ped - tuple val(meta), path("*.png") , optional: true, emit: png - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.vs.html") , emit: vs_html + tuple val(meta), path("${prefix}.html") , emit: html + tuple val(meta), path("${prefix}.peddy.ped") , emit: ped + tuple val(meta), path("${prefix}.het_check.png") , optional: true, emit: het_check_png + tuple val(meta), path("${prefix}.ped_check.png") , optional: true, emit: ped_check_png + tuple val(meta), path("${prefix}.sex_check.png") , optional: true, emit: sex_check_png + tuple val(meta), path("${prefix}.het_check.csv") , optional: true, emit: het_check_csv + tuple val(meta), path("${prefix}.ped_check.csv") , optional: true, emit: ped_check_csv + tuple val(meta), path("${prefix}.sex_check.csv") , optional: true, emit: sex_check_csv + tuple val(meta), path("${prefix}.ped_check.rel-difference.csv") , optional: true, emit: ped_check_rel_difference_csv + tuple val("${task.process}"), val("peddy"), eval("peddy --version | sed 's/peddy, version //'"), topic: versions, emit: versions_peddy when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" + def sites_arg = sites ? "--sites $sites" : '' + if (sites && args.contains('--sites')) error "Double definition of --sites (in sites channel and in ext.args)" """ peddy \\ $args \\ @@ -31,27 +40,24 @@ process PEDDY { --plot \\ -p $task.cpus \\ $vcf \\ + $sites_arg \\ $ped - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - peddy: \$( peddy --version 2>&1 | tail -1 | sed 's/peddy, version //' ) - END_VERSIONS """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + if (sites && args.contains('--sites')) error "Double definition of --sites (in sites channel and in ext.args)" """ - touch ${prefix}.ped_check.csv touch ${prefix}.vs.html + touch ${prefix}.html + touch ${prefix}.peddy.ped touch ${prefix}.het_check.csv + touch ${prefix}.ped_check.csv touch ${prefix}.sex_check.csv - touch ${prefix}.peddy.ped - touch ${prefix}.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - peddy: \$( peddy --version 2>&1 | tail -1 | sed 's/peddy, version //' ) - END_VERSIONS + touch ${prefix}.het_check.png + touch ${prefix}.ped_check.png + touch ${prefix}.sex_check.png + touch ${prefix}.ped_check.rel-difference.csv """ } diff --git a/modules/nf-core/peddy/meta.yml b/modules/nf-core/peddy/meta.yml index 6b6b7347d..b503b76b9 100644 --- a/modules/nf-core/peddy/meta.yml +++ b/modules/nf-core/peddy/meta.yml @@ -6,13 +6,14 @@ keywords: - family tools: - peddy: - description: genotype, ped correspondence check, ancestry check, sex check. directly, - quickly on VCF + description: genotype, ped correspondence check, ancestry check, sex check. + directly, quickly on VCF homepage: https://github.com/brentp/peddy documentation: https://peddy.readthedocs.io/en/latest/ tool_dev_url: https://github.com/brentp/peddy doi: "10.1016/j.ajhg.2017.01.017" - licence: ["MIT"] + licence: + - "MIT" identifier: "" input: - - meta: @@ -23,61 +24,195 @@ input: - vcf: type: file description: VCF file - pattern: "*.{vcf.gz}" + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 - vcf_tbi: type: file description: TBI file - pattern: "*.{vcf.gz.tbi}" - - - ped: + pattern: "*.vcf.gz.tbi" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ped: type: file description: PED/FAM file pattern: "*.{ped,fam}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - sites: + type: file + description: sites file. By defaults peddy uses hg19/GRCh37, "--sites + hg38" can be specified in the process argument or a custom file + following syntax + https://github.com/brentp/peddy/blob/master/peddy/GRCH37.sites can be + provided + pattern: "*.sites" + ontologies: [] output: - - html: - - meta: + vs_html: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.html": + - ${prefix}.vs.html: type: file - description: HTML file - pattern: "*.{html}" - - csv: - - meta: + description: HTML file comparison between reported and inferred sex + pattern: "*.vs.html" + ontologies: [] + html: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.csv": + - ${prefix}.html: type: file - description: CSV file - pattern: "*.{csv}" - - ped: - - meta: + description: HTML report + pattern: "*.html" + ontologies: [] + ped: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.peddy.ped": + - ${prefix}.peddy.ped: type: file - description: PED/FAM file - pattern: "*.peddy.{ped}" - - png: - - meta: + description: Inferred PED file + pattern: "*.peddy.ped" + ontologies: [] + het_check_png: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.png": + - ${prefix}.het_check.png: type: file - description: PNG file - pattern: "*.{png}" - - versions: - - versions.yml: + description: | + PNG file containing heterozygosity check. + Rate of het calls, allele-balance at het calls, + mean and median depth, and a PCA projection onto thousand + genomes. + pattern: "*.het_check.png" + ontologies: [] + ped_check_png: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.ped_check.png: type: file - description: File containing software versions - pattern: "versions.yml" + description: | + PNG file containing pedigree check between reported + and inferred sex + pattern: "*.het_check.png" + ontologies: [] + sex_check_png: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.sex_check.png: + type: file + description: | + PNG file with sex check performs a comparison + between the sex reported in the ped file and that + inferred from the genotypes on the non-PAR regions + of the X chromosome. + pattern: "*.sex_check.png" + ontologies: [] + het_check_csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.het_check.csv: + type: file + description: | + CSV file containing heterozygosity check. + Rate of het calls, allele-balance at het calls, + mean and median depth, and a PCA projection onto thousand + genomes. + pattern: "*.het_check.csv" + ontologies: + - edam: http://edamontology.org/format_3752 + ped_check_csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.ped_check.csv: + type: file + description: | + CSV file containing pedigree check between reported + and inferred sex + pattern: "*.het_check.csv" + ontologies: + - edam: http://edamontology.org/format_3752 + sex_check_csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.sex_check.csv: + type: file + description: | + CSV file with sex check performs a comparison + between the sex reported in the ped file and that + inferred from the genotypes on the non-PAR regions + of the X chromosome. + pattern: "*.sex_check.csv" + ontologies: + - edam: http://edamontology.org/format_3752 + ped_check_rel_difference_csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.ped_check.rel-difference.csv: + type: file + description: | + CSV file with the comparison between inferred and given relatedness + pattern: "*.ped_check.rel-difference.csv" + ontologies: + - edam: http://edamontology.org/format_3752 + versions_peddy: + - - ${task.process}: + type: string + description: The name of the process + - peddy: + type: string + description: The name of the tool + - peddy --version | sed 's/peddy, version //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - peddy: + type: string + description: The name of the tool + - peddy --version | sed 's/peddy, version //': + type: eval + description: The expression to obtain the version of the tool authors: - "@rannick" maintainers: diff --git a/modules/nf-core/peddy/tests/main.nf.test b/modules/nf-core/peddy/tests/main.nf.test index 21ff538d1..f52d22919 100644 --- a/modules/nf-core/peddy/tests/main.nf.test +++ b/modules/nf-core/peddy/tests/main.nf.test @@ -8,6 +8,70 @@ nextflow_process { tag "modules_nfcore" tag "peddy" + test("test - peddy") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ + [ id:'ped_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM.ped', checkIfExists: true) + ] + input[2] = [ + [ id:'sites_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/peddy.sites', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + + ) + } + + } + + test("test - peddy - double_sites") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ + [ id:'ped_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM.ped', checkIfExists: true) + ] + input[2] = [ + [ id:'sites_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/peddy.sites', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert !process.success }, + { assert process.exitStatus != 0 } + ) + } + } + test("test - peddy - stub") { options "-stub" @@ -17,19 +81,27 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/ped/justhusky_minimal.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/ped/justhusky_minimal.vcf.gz.tbi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM_snvs_annotated_ranked.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ + [ id:'ped_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/FAM.ped', checkIfExists: true) + ] + input[2] = [ + [ id:'sites_file' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/peddy.sites', checkIfExists: true) ] - input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/ped/justhusky.ped', checkIfExists: true) """ } } then { - assert process.success - assert snapshot(process.out).match() + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) } } - } diff --git a/modules/nf-core/peddy/tests/main.nf.test.snap b/modules/nf-core/peddy/tests/main.nf.test.snap index 5de593f1d..60551fd04 100644 --- a/modules/nf-core/peddy/tests/main.nf.test.snap +++ b/modules/nf-core/peddy/tests/main.nf.test.snap @@ -8,10 +8,7 @@ "id": "test", "single_end": false }, - [ - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vs.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vs.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ @@ -20,11 +17,14 @@ "id": "test", "single_end": false }, - [ - "test.het_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.ped_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sex_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + "PEDDY", + "peddy", + "0.4.8" ] ], "2": [ @@ -37,22 +37,84 @@ ] ], "3": [ - + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "4": [ - "versions.yml:md5,d3587e67aded68bcf24c47542efe012f" + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], - "csv": [ + "5": [ [ { "id": "test", "single_end": false }, - [ - "test.het_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.ped_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sex_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.sex_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.rel-difference.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "het_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "het_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "html": [ @@ -61,10 +123,7 @@ "id": "test", "single_end": false }, - [ - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vs.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "ped": [ @@ -76,18 +135,278 @@ "test.peddy.ped:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "png": [ - + "ped_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ped_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ped_check_rel_difference_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.rel-difference.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sex_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sex_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_peddy": [ + [ + "PEDDY", + "peddy", + "0.4.8" + ] + ], + "vs_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vs.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-03-24T11:53:32.465432", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test - peddy": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vs.html:md5,a749380edef4653dade663534ddcfbd6" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,e3af87096747a19966222a74242943b6" + ] + ], + "10": [ + [ + "PEDDY", + "peddy", + "0.4.8" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.peddy.ped:md5,8378f6599ee4ad6a9db42bfe226968a6" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.png:md5,ce21f5e727cc6b4346d407d2963b0442" + ] ], - "versions": [ - "versions.yml:md5,d3587e67aded68bcf24c47542efe012f" + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.png:md5,861d8b204d78a22a59b0cedafd8d4a16" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.png:md5,b2ff9afe9f596dee5a22431ba920980c" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.csv:md5,b8623fa750218dade5468542d459fafe" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.csv:md5,21dded6c03dab39859d2936d4820c426" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.csv:md5,763950d0eff48b64da29a6a883d6b11c" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.rel-difference.csv:md5,b59f50df00b5b3af6e71e774d8b99103" + ] + ], + "het_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.csv:md5,b8623fa750218dade5468542d459fafe" + ] + ], + "het_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.het_check.png:md5,ce21f5e727cc6b4346d407d2963b0442" + ] + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,e3af87096747a19966222a74242943b6" + ] + ], + "ped": [ + [ + { + "id": "test", + "single_end": false + }, + "test.peddy.ped:md5,8378f6599ee4ad6a9db42bfe226968a6" + ] + ], + "ped_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.csv:md5,21dded6c03dab39859d2936d4820c426" + ] + ], + "ped_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.png:md5,861d8b204d78a22a59b0cedafd8d4a16" + ] + ], + "ped_check_rel_difference_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ped_check.rel-difference.csv:md5,b59f50df00b5b3af6e71e774d8b99103" + ] + ], + "sex_check_csv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.csv:md5,763950d0eff48b64da29a6a883d6b11c" + ] + ], + "sex_check_png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sex_check.png:md5,b2ff9afe9f596dee5a22431ba920980c" + ] + ], + "versions_peddy": [ + [ + "PEDDY", + "peddy", + "0.4.8" + ] + ], + "vs_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vs.html:md5,a749380edef4653dade663534ddcfbd6" + ] ] } ], + "timestamp": "2026-03-24T11:53:24.822041", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-25T09:28:05.418978589" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/peddy/tests/nextflow.config b/modules/nf-core/peddy/tests/nextflow.config new file mode 100644 index 000000000..bca49c052 --- /dev/null +++ b/modules/nf-core/peddy/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'PEDDY' { + ext.args = '--sites --hg38' + } +} diff --git a/modules/nf-core/peddy/tests/tags.yml b/modules/nf-core/peddy/tests/tags.yml deleted file mode 100644 index d8324a74c..000000000 --- a/modules/nf-core/peddy/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -mosdepth: - - "modules/nf-core/peddy/**" diff --git a/modules/nf-core/picard/addorreplacereadgroups/environment.yml b/modules/nf-core/picard/addorreplacereadgroups/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/environment.yml +++ b/modules/nf-core/picard/addorreplacereadgroups/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/addorreplacereadgroups/main.nf b/modules/nf-core/picard/addorreplacereadgroups/main.nf index 5a71e085a..7261dc8e2 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/main.nf +++ b/modules/nf-core/picard/addorreplacereadgroups/main.nf @@ -4,8 +4,8 @@ process PICARD_ADDORREPLACEREADGROUPS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' : + 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6' }" input: tuple val(meta), path(reads) @@ -16,7 +16,7 @@ process PICARD_ADDORREPLACEREADGROUPS { tuple val(meta), path("*.bam") , emit: bam, optional: true tuple val(meta), path("*.bai") , emit: bai, optional: true tuple val(meta), path("*.cram"), emit: cram, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -34,7 +34,6 @@ process PICARD_ADDORREPLACEREADGROUPS { } if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" - """ picard \\ -Xmx${avail_mem}M \\ @@ -43,11 +42,6 @@ process PICARD_ADDORREPLACEREADGROUPS { $reference \\ --INPUT ${reads} \\ --OUTPUT ${prefix}.${suffix} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard AddOrReplaceReadGroups --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ stub: @@ -56,10 +50,5 @@ process PICARD_ADDORREPLACEREADGROUPS { if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ touch ${prefix}.${suffix} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard AddOrReplaceReadGroups --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/addorreplacereadgroups/meta.yml b/modules/nf-core/picard/addorreplacereadgroups/meta.yml index 77ce85035..b26a1c508 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/meta.yml +++ b/modules/nf-core/picard/addorreplacereadgroups/meta.yml @@ -25,6 +25,7 @@ input: type: file description: Sequence reads file, can be SAM/BAM/CRAM format pattern: "*.{bam,cram,sam}" + ontologies: [] - - meta2: type: map description: | @@ -34,6 +35,7 @@ input: type: file description: Reference genome file pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: [] - - meta3: type: map description: | @@ -43,9 +45,10 @@ input: type: file description: Reference genome index file pattern: "*.{fai,fasta.fai,fa.fai,fasta.gz.fai,fa.gz.fai}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -54,8 +57,9 @@ output: type: file description: Output BAM file pattern: "*.{bam}" - - bai: - - meta: + ontologies: [] + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -64,8 +68,9 @@ output: type: file description: An optional BAM index file pattern: "*.{bai}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -74,11 +79,29 @@ output: type: file description: Output CRAM file pattern: "*.{cram}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + authors: - "@sateeshperi" - "@mjcipriano" diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config b/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config index 3f37c2fd9..132cc0f7c 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config @@ -9,5 +9,4 @@ process { "-SM ${meta.id}" ].join(' ').trim()} } - } diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config b/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config index 966c14d79..be92e72bb 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config @@ -9,5 +9,4 @@ process { ].join(' ').trim()} ext.suffix = { "cram" } } - } diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test index 9c029354f..5586ab469 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test @@ -27,14 +27,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.bam[0][1]).name, - file(process.out.bai[0][1]).name, - process.out.versions - ).match() - }, + file(process.out.bam[0][1]).name, + file(process.out.bai[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("homo_sapiens - cram") { @@ -58,19 +56,16 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.cram[0][1]).name, - process.out.versions - ).match() - }, + file(process.out.cram[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("sarscov2 - bam - stub") { config "./bam.config" options "-stub" - when { process { """ @@ -84,10 +79,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } - } diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap index 3ae6b9171..7ec99fbb5 100644 --- a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap @@ -2,36 +2,25 @@ "homo_sapiens - cram": { "content": [ "test.replaced.cram", - [ - "versions.yml:md5,e82588e0fecbeafdff36e3b3001b3bca" - ] + { + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T09:36:16.966842212", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:13:23.115450366" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam - stub": { "content": [ { - "0": [ - [ - { - - }, - "null.replaced.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,e82588e0fecbeafdff36e3b3001b3bca" - ], "bai": [ ], @@ -46,29 +35,39 @@ "cram": [ ], - "versions": [ - "versions.yml:md5,e82588e0fecbeafdff36e3b3001b3bca" + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] ] } ], + "timestamp": "2026-02-19T17:34:40.3572859", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:13:47.23694937" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - bam": { "content": [ "null.replaced.bam", "null.replaced.bai", - [ - "versions.yml:md5,e82588e0fecbeafdff36e3b3001b3bca" - ] + { + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T09:36:00.935196996", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:12:53.083677142" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/tags.yml b/modules/nf-core/picard/addorreplacereadgroups/tests/tags.yml deleted file mode 100644 index 733010d62..000000000 --- a/modules/nf-core/picard/addorreplacereadgroups/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -picard/addorreplacereadgroups: - - "modules/nf-core/picard/addorreplacereadgroups/**" diff --git a/modules/nf-core/picard/collecthsmetrics/environment.yml b/modules/nf-core/picard/collecthsmetrics/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/collecthsmetrics/environment.yml +++ b/modules/nf-core/picard/collecthsmetrics/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index 1d017ef8d..96045b5dd 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -1,21 +1,22 @@ process PICARD_COLLECTHSMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "baits/*"), path(target_intervals, stageAs: 'targets/*') - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) - tuple val(meta4), path(dict) + tuple val(meta2), path(ref) + tuple val(meta3), path(ref_fai) + tuple val(meta4), path(ref_dict) + tuple val(meta5), path(ref_gzi) output: - tuple val(meta), path("*_metrics") , emit: metrics - path "versions.yml" , emit: versions + tuple val(meta), path("*_metrics"), emit: metrics + tuple val("${task.process}"), val('picard'), eval("picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -23,60 +24,47 @@ process PICARD_COLLECTHSMETRICS { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def reference = ref ? "--REFERENCE_SEQUENCE ${ref}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } def bait_interval_list = bait_intervals def bait_intervallist_cmd = "" - if (bait_intervals =~ /.(bed|bed.gz)$/){ + if (bait_intervals =~ /.(bed|bed.gz)$/) { bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${ref_dict} --TMP_DIR ." } def target_interval_list = target_intervals def target_intervallist_cmd = "" - if (target_intervals =~ /.(bed|bed.gz)$/){ + if (target_intervals =~ /.(bed|bed.gz)$/) { target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${ref_dict} --TMP_DIR ." } - - """ - - $bait_intervallist_cmd - $target_intervallist_cmd + ${bait_intervallist_cmd} + ${target_intervallist_cmd} picard \\ -Xmx${avail_mem}M \\ CollectHsMetrics \\ - $args \\ - $reference \\ - --BAIT_INTERVALS $bait_interval_list \\ - --TARGET_INTERVALS $target_interval_list \\ - --INPUT $bam \\ + ${args} \\ + ${reference} \\ + --BAIT_INTERVALS ${bait_interval_list} \\ + --TARGET_INTERVALS ${target_interval_list} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.CollectHsMetrics.coverage_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collecthsmetrics/meta.yml b/modules/nf-core/picard/collecthsmetrics/meta.yml index ea6deda3e..89bc502c9 100644 --- a/modules/nf-core/picard/collecthsmetrics/meta.yml +++ b/modules/nf-core/picard/collecthsmetrics/meta.yml @@ -28,51 +28,68 @@ input: type: file description: An aligned BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Optional aligned BAM/CRAM/SAM file index pattern: "*.{bai,crai,sai}" + ontologies: [] - bait_intervals: type: file description: An interval file that contains the locations of the baits used. pattern: "*.{interval_list,bed,bed.gz}" + ontologies: [] - target_intervals: type: file description: An interval file that contains the locations of the targets. pattern: "*.{interval_list,bed,bed.gz}" + ontologies: [] - - meta2: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - fasta: + - ref: type: file description: | A reference file to calculate dropout metrics measuring reduced representation of reads. Optional input. - pattern: "*.{fa,fasta,fna}" + pattern: "*.{fa,fa.gz,fasta,fasta.gz,fna,fna.gz}" + ontologies: [] - - meta3: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - fai: + - ref_fai: type: file - description: Index of FASTA file. Only needed when fasta is supplied. + description: Index of reference file. Only needed when reference is supplied. pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - dict: + - ref_dict: type: file description: Sequence dictionary of FASTA file. Only needed when bed interval lists are supplied. pattern: "*.dict" + ontologies: [] + - - meta5: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - ref_gzi: + type: file + description: Index of reference file. Only needed when gzipped reference is supplied. + pattern: "*.gzi" + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -81,11 +98,29 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@projectoriented" - "@matthdsm" diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test index 3bbbd8cf5..d73661111 100644 --- a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test @@ -24,6 +24,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -38,18 +39,50 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } + } + + test("sarscov2 - bam - gzippedfa") { + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/targets.interval_list', checkIfExists: true) + ] + input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true)] + input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz.fai', checkIfExists: true)] + input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz.gzi', checkIfExists: true)] + """ + } + } + + then { + def size = path(process.out.metrics[0][1]).size() + def lines = path(process.out.metrics[0][1]).readLines()[0..100] + lines.remove(3) // remove timestamp + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.metrics[0][1]).name, + size, + lines, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } } test("sarscov2 - bam - stub") { - options "-stub" - when { process { """ @@ -63,6 +96,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -70,10 +104,9 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } test("sarscov2 - bam - nofasta") { @@ -91,6 +124,7 @@ nextflow_process { input[1] = [[:],[]] input[2] = [[:],[]] input[3] = [[:],[]] + input[4] = [[:],[]] """ } } @@ -105,12 +139,10 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("sarscov2 - bam - bed") { @@ -129,6 +161,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -143,12 +176,10 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("sarscov2 - bam - samebed") { @@ -167,6 +198,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -181,11 +213,9 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } -} \ No newline at end of file +} diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap index 4d21710a0..43385314a 100644 --- a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap @@ -105,27 +105,170 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:03:29.566021877", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:55.291163084" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, - "versions": { + "sarscov2 - bam - stub": { "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectHsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-19T17:36:03.822502867", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - bam - gzippedfa": { + "content": [ + "test.CollectHsMetrics.coverage_metrics", + 3601, [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + "## htsjdk.samtools.metrics.StringHeader", + "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/targets.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --REFERENCE_SEQUENCE genome.fasta.gz --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", + "## htsjdk.samtools.metrics.StringHeader", + "", + "## METRICS CLASS\tpicard.analysis.directed.HsMetrics", + "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP", + "baits\t158\t0.594937\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.000181\t4.995204\t\t0\t0\t0\t0\t0\t0\t94\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t5\t1\t1\t0.985\t0.053191\t0\t1\t0\t0.75\t0\t0\t0.005438\t0.054487\t0.259516\t0.680377\t?\t0.053191\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t76.595745\t23.404255\t0.015734\t0\t\t\t", + "", + "## HISTOGRAM\tjava.lang.Integer", + "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count", + "0\t89\t0", + "1\t5\t0", + "2\t0\t0", + "3\t0\t0", + "4\t0\t0", + "5\t0\t0", + "6\t0\t0", + "7\t0\t0", + "8\t0\t0", + "9\t0\t0", + "10\t0\t0", + "11\t0\t0", + "12\t0\t0", + "13\t0\t0", + "14\t0\t5", + "15\t0\t0", + "16\t0\t0", + "17\t0\t0", + "18\t0\t0", + "19\t0\t0", + "20\t0\t0", + "21\t0\t1", + "22\t0\t0", + "23\t0\t0", + "24\t0\t0", + "25\t0\t0", + "26\t0\t0", + "27\t0\t0", + "28\t0\t0", + "29\t0\t0", + "30\t0\t0", + "31\t0\t0", + "32\t0\t1", + "33\t0\t0", + "34\t0\t0", + "35\t0\t0", + "36\t0\t3", + "37\t0\t0", + "38\t0\t0", + "39\t0\t0", + "40\t0\t0", + "41\t0\t0", + "42\t0\t0", + "43\t0\t0", + "44\t0\t0", + "45\t0\t0", + "46\t0\t0", + "47\t0\t0", + "48\t0\t0", + "49\t0\t0", + "50\t0\t0", + "51\t0\t0", + "52\t0\t0", + "53\t0\t0", + "54\t0\t0", + "55\t0\t0", + "56\t0\t0", + "57\t0\t0", + "58\t0\t0", + "59\t0\t0", + "60\t0\t0", + "61\t0\t0", + "62\t0\t0", + "63\t0\t0", + "64\t0\t0", + "65\t0\t0", + "66\t0\t0", + "67\t0\t0", + "68\t0\t0", + "69\t0\t0", + "70\t0\t0", + "71\t0\t0", + "72\t0\t0", + "73\t0\t0", + "74\t0\t0", + "75\t0\t0", + "76\t0\t0", + "77\t0\t0", + "78\t0\t0", + "79\t0\t0", + "80\t0\t0", + "81\t0\t0", + "82\t0\t0", + "83\t0\t0", + "84\t0\t0", + "85\t0\t0", + "86\t0\t0", + "87\t0\t0", + "88\t0\t0", + "89\t0\t0" + ], + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:03:04.382110367", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:30.748857589" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam - samebed": { "content": [ @@ -233,15 +376,21 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:13:22.872920293", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:52:43.803456585" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam": { "content": [ @@ -349,15 +498,21 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:02:47.615784738", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:01.881343611" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam - bed": { "content": [ @@ -465,14 +620,20 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:13:02.812282052", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:52:22.830749735" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/collecthsmetrics/tests/tags.yml b/modules/nf-core/picard/collecthsmetrics/tests/tags.yml deleted file mode 100644 index b353f95ec..000000000 --- a/modules/nf-core/picard/collecthsmetrics/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -picard/collecthsmetrics: - - "modules/nf-core/picard/collecthsmetrics/**" diff --git a/modules/nf-core/picard/collectmultiplemetrics/environment.yml b/modules/nf-core/picard/collectmultiplemetrics/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/environment.yml +++ b/modules/nf-core/picard/collectmultiplemetrics/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/collectmultiplemetrics/main.nf b/modules/nf-core/picard/collectmultiplemetrics/main.nf index cf1af40af..9de927e69 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/main.nf +++ b/modules/nf-core/picard/collectmultiplemetrics/main.nf @@ -1,21 +1,21 @@ process PICARD_COLLECTMULTIPLEMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: - tuple val(meta) , path(bam), path(bai) + tuple val(meta), path(bam), path(bai) tuple val(meta2), path(fasta) tuple val(meta3), path(fai) output: tuple val(meta), path("*_metrics"), emit: metrics - tuple val(meta), path("*.pdf") , emit: pdf, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.pdf"), emit: pdf, optional: true + tuple val("${task.process}"), val('picard'), eval("picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -26,23 +26,19 @@ process PICARD_COLLECTMULTIPLEMETRICS { def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CollectMultipleMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectMultipleMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ picard \\ -Xmx${avail_mem}M \\ CollectMultipleMetrics \\ - $args \\ - --INPUT $bam \\ + ${args} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectMultipleMetrics \\ - $reference - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectMultipleMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS + ${reference} """ stub: @@ -58,10 +54,5 @@ process PICARD_COLLECTMULTIPLEMETRICS { touch ${prefix}.CollectMultipleMetrics.quality_by_cycle.pdf touch ${prefix}.CollectMultipleMetrics.insert_size_histogram.pdf touch ${prefix}.CollectMultipleMetrics.quality_distribution_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectMultipleMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collectmultiplemetrics/meta.yml b/modules/nf-core/picard/collectmultiplemetrics/meta.yml index 2b7981ac6..213d600be 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/meta.yml +++ b/modules/nf-core/picard/collectmultiplemetrics/meta.yml @@ -26,10 +26,12 @@ input: type: file description: SAM/BAM/CRAM file pattern: "*.{sam,bam,cram}" + ontologies: [] - bai: type: file description: Optional SAM/BAM/CRAM file index pattern: "*.{sai,bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -38,6 +40,7 @@ input: - fasta: type: file description: Genome fasta file + ontologies: [] - - meta3: type: map description: | @@ -47,9 +50,10 @@ input: type: file description: Index of FASTA file. Only needed when fasta is supplied. pattern: "*.fai" + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -58,8 +62,9 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - pdf: - - meta: + ontologies: [] + pdf: + - - meta: type: map description: | Groovy Map containing sample information @@ -68,11 +73,30 @@ output: type: file description: PDF plots of metrics pattern: "*.{pdf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + authors: - "@drpatelh" maintainers: diff --git a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test index 5b67774f7..0037acab6 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test @@ -16,16 +16,15 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [[id:'genome'],[]] - + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [[id:'genome'],[]] """ } } @@ -36,9 +35,8 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -49,13 +47,12 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [[id:'genome'],[]] + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[id:'genome'],[]] input[2] = [[id:'genome'],[]] - """ } } @@ -66,9 +63,8 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -79,19 +75,18 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ] - + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] """ } } @@ -102,11 +97,90 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("test-picard-collectmultiplemetrics - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [[id:'genome'],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("test-picard-collectmultiplemetrics-nofasta - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[id:'genome'],[]] + input[2] = [[id:'genome'],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } + test("test-picard-collectmultiplemetrics-cram - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap index a76a32375..393ed1003 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap @@ -15,15 +15,117 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-02T10:22:21.230301646", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "test-picard-collectmultiplemetrics - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:32:38.701455244", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:05:12.591021247" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test-picard-collectmultiplemetrics-nofasta - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:32:48.923918624", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-picard-collectmultiplemetrics-cram": { "content": [ @@ -41,15 +143,21 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T10:23:52.23446844", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:06:08.499320579" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "test-picard-collectmultiplemetrics-nofasta": { "content": [ @@ -67,14 +175,68 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-02T10:23:27.387621193", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "test-picard-collectmultiplemetrics-cram - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:32:57.11686549", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:05:42.117033611" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/collectwgsmetrics/environment.yml b/modules/nf-core/picard/collectwgsmetrics/environment.yml index 13265842f..186d4a4bc 100644 --- a/modules/nf-core/picard/collectwgsmetrics/environment.yml +++ b/modules/nf-core/picard/collectwgsmetrics/environment.yml @@ -1,6 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 - conda-forge::r-base=4.4.1 diff --git a/modules/nf-core/picard/collectwgsmetrics/main.nf b/modules/nf-core/picard/collectwgsmetrics/main.nf index 39cf7d2b7..a5db512c0 100644 --- a/modules/nf-core/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/picard/collectwgsmetrics/main.nf @@ -1,60 +1,50 @@ process PICARD_COLLECTWGSMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(bam), path(bai) tuple val(meta2), path(fasta) tuple val(meta3), path(fai) - path intervallist + path intervallist output: tuple val(meta), path("*_metrics"), emit: metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def avail_mem = 3072 - def interval = intervallist ? "--INTERVALS ${intervallist}" : '' + def interval = intervallist ? "--INTERVALS ${intervallist}" : '' if (!task.memory) { - log.info '[Picard CollectWgsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectWgsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ picard \\ -Xmx${avail_mem}M \\ CollectWgsMetrics \\ - $args \\ - --INPUT $bam \\ + ${args} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectWgsMetrics.coverage_metrics \\ --REFERENCE_SEQUENCE ${fasta} \\ - $interval - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS + ${interval} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.CollectWgsMetrics.coverage_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml index bb7480809..c5afe2e7c 100644 --- a/modules/nf-core/picard/collectwgsmetrics/meta.yml +++ b/modules/nf-core/picard/collectwgsmetrics/meta.yml @@ -26,10 +26,12 @@ input: type: file description: Aligned reads file pattern: "*.{bam, cram}" + ontologies: [] - bai: type: file description: (Optional) Aligned reads file index pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -39,6 +41,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta,fna}" + ontologies: [] - - meta3: type: map description: | @@ -48,13 +51,15 @@ input: type: file description: Genome fasta file index pattern: "*.{fai}" - - - intervallist: - type: file - description: Picard Interval List. Defines which contigs to include. Can be - generated from a BED file with GATK BedToIntervalList. + ontologies: [] + - intervallist: + type: file + description: Picard Interval List. Defines which contigs to include. Can be generated + from a BED file with GATK BedToIntervalList. + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,11 +68,28 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@drpatelh" - "@flowuenne" diff --git a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test index a3984566d..1bda5980a 100644 --- a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test @@ -16,19 +16,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = [] - + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [] """ } } @@ -37,10 +36,9 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), - process.out.versions - ).match() - } + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -51,19 +49,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - [] - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) - + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) """ } } @@ -72,12 +69,70 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), - process.out.versions - ).match() - } + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } + test("test-picard-collectwgsmetrics - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("test-picard-collectwgsmetrics-with-interval - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap index 1958fcdeb..79f1145ff 100644 --- a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap @@ -1,28 +1,94 @@ { + "test-picard-collectwgsmetrics-with-interval - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:35:04.636691319", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, "test-picard-collectwgsmetrics-with-interval": { "content": [ - true, - [ - "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" - ] + false, + { + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:34:45.059411647", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test-picard-collectwgsmetrics - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:34:54.347278951", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:15:18.13771243" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-picard-collectwgsmetrics": { "content": [ - true, - [ - "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" - ] + false, + { + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:34:25.744978033", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:14:57.786056996" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/liftovervcf/environment.yml b/modules/nf-core/picard/liftovervcf/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/liftovervcf/environment.yml +++ b/modules/nf-core/picard/liftovervcf/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/liftovervcf/main.nf b/modules/nf-core/picard/liftovervcf/main.nf index 69feb624a..da025c9b6 100644 --- a/modules/nf-core/picard/liftovervcf/main.nf +++ b/modules/nf-core/picard/liftovervcf/main.nf @@ -1,11 +1,11 @@ process PICARD_LIFTOVERVCF { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(input_vcf) @@ -14,9 +14,9 @@ process PICARD_LIFTOVERVCF { tuple val(meta4), path(chain) output: - tuple val(meta), path("*.lifted.vcf.gz") , emit: vcf_lifted + tuple val(meta), path("*.lifted.vcf.gz"), emit: vcf_lifted tuple val(meta), path("*.unlifted.vcf.gz"), emit: vcf_unlifted - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard LiftoverVcf --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -26,25 +26,21 @@ process PICARD_LIFTOVERVCF { def prefix = task.ext.prefix ?: "${meta.id}" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard LiftoverVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard LiftoverVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ picard \\ -Xmx${avail_mem}M \\ LiftoverVcf \\ - $args \\ - --INPUT $input_vcf \\ + ${args} \\ + --INPUT ${input_vcf} \\ --OUTPUT ${prefix}.lifted.vcf.gz \\ - --CHAIN $chain \\ + --CHAIN ${chain} \\ --REJECT ${prefix}.unlifted.vcf.gz \\ - --REFERENCE_SEQUENCE $fasta - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard LiftoverVcf --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + --REFERENCE_SEQUENCE ${fasta} """ stub: @@ -52,10 +48,5 @@ process PICARD_LIFTOVERVCF { """ echo | gzip > ${prefix}.lifted.vcf.gz echo | gzip > ${prefix}.unlifted.vcf.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard LiftoverVcf --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/liftovervcf/meta.yml b/modules/nf-core/picard/liftovervcf/meta.yml index 10fbfc837..24253b41f 100644 --- a/modules/nf-core/picard/liftovervcf/meta.yml +++ b/modules/nf-core/picard/liftovervcf/meta.yml @@ -21,6 +21,7 @@ input: type: file description: VCF file pattern: "*.{vcf,vcf.gz}" + ontologies: [] - - meta2: type: map description: | @@ -30,6 +31,7 @@ input: type: file description: dictionary for fasta file pattern: "*.{dict}" + ontologies: [] - - meta3: type: map description: | @@ -39,6 +41,7 @@ input: type: file description: fasta file pattern: "*.fasta" + ontologies: [] - - meta4: type: map description: | @@ -47,9 +50,10 @@ input: - chain: type: file description: The liftover chain file + ontologies: [] output: - - vcf_lifted: - - meta: + vcf_lifted: + - - meta: type: map description: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] @@ -57,8 +61,9 @@ output: type: file description: VCF file containing successfully lifted variants pattern: "*.{lifted.vcf.gz}" - - vcf_unlifted: - - meta: + ontologies: [] + vcf_unlifted: + - - meta: type: map description: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] @@ -66,11 +71,28 @@ output: type: file description: VCF file containing unsuccessfully lifted variants pattern: "*.{unlifted.vcf.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard LiftoverVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard LiftoverVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@lucpen" - "@ramprasadn" diff --git a/modules/nf-core/picard/liftovervcf/tests/main.nf.test b/modules/nf-core/picard/liftovervcf/tests/main.nf.test index 7b42102de..8317403ca 100644 --- a/modules/nf-core/picard/liftovervcf/tests/main.nf.test +++ b/modules/nf-core/picard/liftovervcf/tests/main.nf.test @@ -17,18 +17,17 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) - ] - input[1] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) - ] - input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ] - input[3] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.chain.gz', checkIfExists: true) - ] - + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) + ] + input[1] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + ] + input[2] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[3] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.chain.gz', checkIfExists: true) + ] """ } } @@ -37,33 +36,31 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.vcf_lifted[0][1]).vcf.summary, - path(process.out.vcf_unlifted[0][1]).vcf.variantsMD5, - process.out.versions - ).match() - } + path(process.out.vcf_lifted[0][1]).vcf.summary, + path(process.out.vcf_unlifted[0][1]).vcf.variantsMD5, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } - test("test-picard-liftovervcf-stubs") { - options '-stub' + test("test-picard-liftovervcf - stub") { + options "-stub" when { process { """ input[0] = [ [ id:'test' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) - ] - input[1] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) - ] - input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ] - input[3] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.chain.gz', checkIfExists: true) - ] - + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) + ] + input[1] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.dict', checkIfExists: true) + ] + input[2] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[3] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.chain.gz', checkIfExists: true) + ] """ } } @@ -71,14 +68,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - file(process.out.vcf_lifted[0][1]).name, - file(process.out.vcf_unlifted[0][1]).name, - process.out.versions - ).match() - } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } - } diff --git a/modules/nf-core/picard/liftovervcf/tests/main.nf.test.snap b/modules/nf-core/picard/liftovervcf/tests/main.nf.test.snap index e88aa9706..c17b69349 100644 --- a/modules/nf-core/picard/liftovervcf/tests/main.nf.test.snap +++ b/modules/nf-core/picard/liftovervcf/tests/main.nf.test.snap @@ -1,30 +1,56 @@ { - "test-picard-liftovervcf-stubs": { + "test-picard-liftovervcf - stub": { "content": [ - "test.lifted.vcf.gz", - "test.unlifted.vcf.gz", - [ - "versions.yml:md5,af33ca5d76aec86863614805fbb4fafb" - ] + { + "vcf_lifted": [ + [ + { + "id": "test" + }, + "test.lifted.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "vcf_unlifted": [ + [ + { + "id": "test" + }, + "test.unlifted.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_picard": [ + [ + "PICARD_LIFTOVERVCF", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:38:09.430447871", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T12:08:23.913395641" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-picard-liftovervcf": { "content": [ "VcfFile [chromosomes=[], sampleCount=1, variantCount=0, phased=true, phasedAutodetect=true]", "39a9de5185d94289283bd27cfcdeba97", - [ - "versions.yml:md5,af33ca5d76aec86863614805fbb4fafb" - ] + { + "versions_picard": [ + [ + "PICARD_LIFTOVERVCF", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T11:40:19.064084452", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T12:08:12.803193917" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/markduplicates/environment.yml b/modules/nf-core/picard/markduplicates/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/markduplicates/environment.yml +++ b/modules/nf-core/picard/markduplicates/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 8a2ed64e6..17bcf27ba 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -1,11 +1,11 @@ process PICARD_MARKDUPLICATES { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(reads) @@ -13,11 +13,11 @@ process PICARD_MARKDUPLICATES { tuple val(meta3), path(fai) output: - tuple val(meta), path("*.bam") , emit: bam, optional: true - tuple val(meta), path("*.bai") , emit: bai, optional: true + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.bai"), emit: bai, optional: true tuple val(meta), path("*.cram"), emit: cram, optional: true tuple val(meta), path("*.metrics.txt"), emit: metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard MarkDuplicates --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -25,44 +25,39 @@ process PICARD_MARKDUPLICATES { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "${reads.getExtension()}" + def suffix = task.ext.suffix ?: "${reads.getExtension()}" def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } - if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" - + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ picard \\ -Xmx${avail_mem}M \\ MarkDuplicates \\ - $args \\ - --INPUT $reads \\ + ${args} \\ + --INPUT ${reads} \\ --OUTPUT ${prefix}.${suffix} \\ - $reference \\ - --METRICS_FILE ${prefix}.MarkDuplicates.metrics.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard MarkDuplicates --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + ${reference} \\ + --METRICS_FILE ${prefix}.metrics.txt """ stub: def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "${reads.getExtension()}" - if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + def suffix = task.ext.suffix ?: "${reads.getExtension()}" + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ touch ${prefix}.${suffix} - touch ${prefix}.MarkDuplicates.metrics.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard MarkDuplicates --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + touch ${prefix}.${suffix}.bai + touch ${prefix}.metrics.txt """ } diff --git a/modules/nf-core/picard/markduplicates/meta.yml b/modules/nf-core/picard/markduplicates/meta.yml index bcaf91605..aa0ddbdba 100644 --- a/modules/nf-core/picard/markduplicates/meta.yml +++ b/modules/nf-core/picard/markduplicates/meta.yml @@ -26,6 +26,7 @@ input: type: file description: Sequence reads file, can be SAM/BAM/CRAM format pattern: "*.{bam,cram,sam}" + ontologies: [] - - meta2: type: map description: | @@ -35,6 +36,7 @@ input: type: file description: Reference genome fasta file, required for CRAM input pattern: "*.{fasta,fa}" + ontologies: [] - - meta3: type: map description: | @@ -44,9 +46,10 @@ input: type: file description: Reference genome fasta index pattern: "*.{fai}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -55,8 +58,9 @@ output: type: file description: BAM file with duplicate reads marked/removed pattern: "*.{bam}" - - bai: - - meta: + ontologies: [] + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -66,8 +70,9 @@ output: description: An optional BAM index file. If desired, --CREATE_INDEX must be passed as a flag pattern: "*.{bai}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -76,8 +81,9 @@ output: type: file description: Output CRAM file pattern: "*.{cram}" - - metrics: - - meta: + ontologies: [] + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -86,11 +92,28 @@ output: type: file description: Duplicate metrics file generated by picard pattern: "*.{metrics.txt}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard MarkDuplicates --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard MarkDuplicates --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@drpatelh" - "@projectoriented" diff --git a/modules/nf-core/picard/markduplicates/tests/main.nf.test b/modules/nf-core/picard/markduplicates/tests/main.nf.test index 9ed909659..4d0064531 100644 --- a/modules/nf-core/picard/markduplicates/tests/main.nf.test +++ b/modules/nf-core/picard/markduplicates/tests/main.nf.test @@ -30,7 +30,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, path(process.out.metrics.get(0).get(1)).readLines()[0..2], - process.out.versions) + process.out.findAll { key, val -> key.startsWith("versions") }) .match() } ) } @@ -57,7 +57,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, path(process.out.metrics.get(0).get(1)).readLines()[0..2], - process.out.versions) + process.out.findAll { key, val -> key.startsWith("versions") }) .match() } ) } @@ -90,7 +90,7 @@ nextflow_process { { assert snapshot( file(process.out.cram[0][1]).name, path(process.out.metrics.get(0).get(1)).readLines()[0..2], - process.out.versions) + process.out.findAll { key, val -> key.startsWith("versions") }) .match() } ) } @@ -114,7 +114,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } @@ -137,7 +137,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } @@ -166,7 +166,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } diff --git a/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap b/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap index 13770a8e2..4ea479a32 100644 --- a/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap +++ b/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap @@ -2,35 +2,14 @@ "sarscov2 [sorted bam] - stub": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.marked.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ + "bai": [ [ { "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "4": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ], - "bai": [ - ], "bam": [ [ @@ -38,7 +17,7 @@ "id": "test", "single_end": false }, - "test.marked.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "cram": [ @@ -50,52 +29,35 @@ "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] ] } ], + "timestamp": "2026-02-19T17:43:13.544887277", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:58:50.046420643" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 [unsorted bam] - stub": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.marked.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ + "bai": [ [ { "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "4": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ], - "bai": [ - ], "bam": [ [ @@ -103,7 +65,7 @@ "id": "test", "single_end": false }, - "test.marked.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "cram": [ @@ -115,106 +77,107 @@ "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] ] } ], + "timestamp": "2026-02-19T17:43:06.193033248", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:58:36.738907079" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 [unsorted bam]": { "content": [ - "test.marked.bam", + "test.md.bam", [ "## htsjdk.samtools.metrics.StringHeader", - "# MarkDuplicates --INPUT test.paired_end.bam --OUTPUT test.marked.bam --METRICS_FILE test.marked.MarkDuplicates.metrics.txt --ASSUME_SORT_ORDER queryname --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", + "# MarkDuplicates --INPUT test.paired_end.bam --OUTPUT test.md.bam --METRICS_FILE test.md.metrics.txt --ASSUME_SORT_ORDER queryname --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", "## htsjdk.samtools.metrics.StringHeader" ], - [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ] + { + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-19T17:42:40.574463587", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:57:16.683233382" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 [sorted bam]": { "content": [ - "test.marked.bam", + "test.md.bam", [ "## htsjdk.samtools.metrics.StringHeader", - "# MarkDuplicates --INPUT test.paired_end.sorted.bam --OUTPUT test.marked.bam --METRICS_FILE test.marked.MarkDuplicates.metrics.txt --ASSUME_SORT_ORDER queryname --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", + "# MarkDuplicates --INPUT test.paired_end.sorted.bam --OUTPUT test.md.bam --METRICS_FILE test.md.metrics.txt --ASSUME_SORT_ORDER queryname --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", "## htsjdk.samtools.metrics.StringHeader" ], - [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ] + { + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-19T17:42:49.374645492", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:57:47.416956759" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens [cram]": { "content": [ - "test.marked.cram", + "test.md.cram", [ "## htsjdk.samtools.metrics.StringHeader", - "# MarkDuplicates --INPUT test.paired_end.sorted.cram --OUTPUT test.marked.cram --METRICS_FILE test.marked.MarkDuplicates.metrics.txt --ASSUME_SORT_ORDER queryname --REFERENCE_SEQUENCE genome.fasta --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", + "# MarkDuplicates --INPUT test.paired_end.sorted.cram --OUTPUT test.md.cram --METRICS_FILE test.md.metrics.txt --ASSUME_SORT_ORDER queryname --REFERENCE_SEQUENCE genome.fasta --MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP 50000 --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 8000 --SORTING_COLLECTION_SIZE_RATIO 0.25 --TAG_DUPLICATE_SET_MEMBERS false --REMOVE_SEQUENCING_DUPLICATES false --TAGGING_POLICY DontTag --CLEAR_DT true --DUPLEX_UMI false --FLOW_MODE false --FLOW_DUP_STRATEGY FLOW_QUALITY_SUM_STRATEGY --FLOW_USE_END_IN_UNPAIRED_READS false --FLOW_USE_UNPAIRED_CLIPPED_END false --FLOW_UNPAIRED_END_UNCERTAINTY 0 --FLOW_UNPAIRED_START_UNCERTAINTY 0 --FLOW_SKIP_FIRST_N_FLOWS 0 --FLOW_Q_IS_KNOWN_END false --FLOW_EFFECTIVE_QUALITY_THRESHOLD 15 --ADD_PG_TAG_TO_READS true --REMOVE_DUPLICATES false --ASSUME_SORTED false --DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES --PROGRAM_RECORD_ID MarkDuplicates --PROGRAM_GROUP_NAME MarkDuplicates --READ_NAME_REGEX --OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 --MAX_OPTICAL_DUPLICATE_SET_SIZE 300000 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", "## htsjdk.samtools.metrics.StringHeader" ], - [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ] + { + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-19T17:42:59.07843756", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:58:15.143314223" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens [cram] - stub": { "content": [ { - "0": [ - - ], - "1": [ - - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test.marked.cram:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ + "bai": [ [ { "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.cram.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "4": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" - ], - "bai": [ - ], "bam": [ @@ -225,7 +188,7 @@ "id": "test", "single_end": false }, - "test.marked.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.cram:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "metrics": [ @@ -234,18 +197,22 @@ "id": "test", "single_end": false }, - "test.marked.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,88717faa02b215b99eef3d05214a6fea" + "versions_picard": [ + [ + "PICARD_MARKDUPLICATES", + "picard", + "3.4.0" + ] ] } ], + "timestamp": "2026-02-19T17:43:20.676018462", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:59:03.402916523" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/markduplicates/tests/nextflow.config b/modules/nf-core/picard/markduplicates/tests/nextflow.config index 02818dd6e..f8dd0f1ca 100644 --- a/modules/nf-core/picard/markduplicates/tests/nextflow.config +++ b/modules/nf-core/picard/markduplicates/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: PICARD_MARKDUPLICATES { - ext.prefix = { "${meta.id}.marked" } + ext.prefix = { "${meta.id}.md" } ext.args = '--ASSUME_SORT_ORDER queryname' } } diff --git a/modules/nf-core/picard/markduplicates/tests/tags.yml b/modules/nf-core/picard/markduplicates/tests/tags.yml deleted file mode 100644 index 4f213d620..000000000 --- a/modules/nf-core/picard/markduplicates/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -picard/markduplicates: - - modules/nf-core/picard/markduplicates/** diff --git a/modules/nf-core/picard/renamesampleinvcf/environment.yml b/modules/nf-core/picard/renamesampleinvcf/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/renamesampleinvcf/environment.yml +++ b/modules/nf-core/picard/renamesampleinvcf/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/renamesampleinvcf/main.nf b/modules/nf-core/picard/renamesampleinvcf/main.nf index 9e5e2e2dc..801ed9f26 100644 --- a/modules/nf-core/picard/renamesampleinvcf/main.nf +++ b/modules/nf-core/picard/renamesampleinvcf/main.nf @@ -1,56 +1,45 @@ - process PICARD_RENAMESAMPLEINVCF { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(vcf) output: tuple val(meta), path("*.vcf.gz"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard RenameSampleInVcf --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def extended_args = args.contains("--NEW_SAMPLE_NAME") ? $args : "${args} --NEW_SAMPLE_NAME ${meta.id}" + def extended_args = args.contains("--NEW_SAMPLE_NAME") ? args : "${args} --NEW_SAMPLE_NAME ${meta.id}" def prefix = task.ext.prefix ?: "${meta.id}" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard RenameSampleInVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard RenameSampleInVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } - """ picard \\ - RenameSampleInVcf \\ -Xmx${avail_mem}M \\ - --INPUT $vcf \\ + RenameSampleInVcf \\ + --INPUT ${vcf} \\ --OUTPUT ${prefix}_renam.vcf.gz \\ - $extended_args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard RenameSampleInVcf --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + ${extended_args} """ stub: - def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}_renam.vcf.gz - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard RenameSampleInVcf --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + echo "" | gzip > ${prefix}_renam.vcf.gz """ } diff --git a/modules/nf-core/picard/renamesampleinvcf/meta.yml b/modules/nf-core/picard/renamesampleinvcf/meta.yml index 7c279fe1e..2b757b19d 100644 --- a/modules/nf-core/picard/renamesampleinvcf/meta.yml +++ b/modules/nf-core/picard/renamesampleinvcf/meta.yml @@ -24,9 +24,10 @@ input: type: file description: VCF file pattern: "*.{vcf,vcf.gz}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -35,11 +36,28 @@ output: type: file description: VCF file pattern: "*.{vcf,vcf.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard RenameSampleInVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard RenameSampleInVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@Lucpen" maintainers: diff --git a/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test b/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test index f755447ff..3e59c23bc 100644 --- a/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test +++ b/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test @@ -16,9 +16,8 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) - ] - + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) + ] """ } } @@ -27,12 +26,30 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.vcf[0][1]).vcf.variantsMD5, - process.out.versions - ).match() - } + path(process.out.vcf[0][1]).vcf.variantsMD5, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } + test("test-picard-renamesampleinvcf - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test.snap b/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test.snap index 6a21666ad..2b6367ae7 100644 --- a/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test.snap +++ b/modules/nf-core/picard/renamesampleinvcf/tests/main.nf.test.snap @@ -2,14 +2,46 @@ "test-picard-renamesampleinvcf": { "content": [ "e21a2349f41663d1fc38f47fbe65a6d5", - [ - "versions.yml:md5,89be4b901aa05e78d449d11b00eff5e9" - ] + { + "versions_picard": [ + [ + "PICARD_RENAMESAMPLEINVCF", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T15:51:56.010473", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T09:53:47.55538945" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } + }, + "test-picard-renamesampleinvcf - stub": { + "content": [ + { + "vcf": [ + [ + { + "id": "test" + }, + "test_renam.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_picard": [ + [ + "PICARD_RENAMESAMPLEINVCF", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:39:17.132250662", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/sortvcf/environment.yml b/modules/nf-core/picard/sortvcf/environment.yml index 1d715d564..b4ac4fe08 100644 --- a/modules/nf-core/picard/sortvcf/environment.yml +++ b/modules/nf-core/picard/sortvcf/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/sortvcf/main.nf b/modules/nf-core/picard/sortvcf/main.nf index a094e6bfa..92286e8a7 100644 --- a/modules/nf-core/picard/sortvcf/main.nf +++ b/modules/nf-core/picard/sortvcf/main.nf @@ -1,11 +1,11 @@ process PICARD_SORTVCF { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(vcf) @@ -14,7 +14,7 @@ process PICARD_SORTVCF { output: tuple val(meta), path("*_sorted.vcf.gz"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard SortVcf --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -22,41 +22,31 @@ process PICARD_SORTVCF { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def seq_dict = dict ? "--SEQUENCE_DICTIONARY $dict" : "" - def reference = fasta ? "--REFERENCE_SEQUENCE $fasta" : "" + def seq_dict = dict ? "--SEQUENCE_DICTIONARY ${dict}" : "" + def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard SortVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard SortVcf] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } - """ picard \\ - SortVcf \\ -Xmx${avail_mem}M \\ - --INPUT $vcf \\ - $args \\ - $seq_dict \\ - $reference \\ + SortVcf \\ + --INPUT ${vcf} \\ + ${args} \\ + ${seq_dict} \\ + ${reference} \\ --OUTPUT ${prefix}_sorted.vcf.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard SortVcf --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}_sorted.vcf.gz + echo "" | gzip > ${prefix}_sorted.vcf.gz touch ${prefix}.bam.bai touch ${prefix}.MarkDuplicates.metrics.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard SortVcf --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/sortvcf/meta.yml b/modules/nf-core/picard/sortvcf/meta.yml index 6dc28e03f..6cbe6b724 100644 --- a/modules/nf-core/picard/sortvcf/meta.yml +++ b/modules/nf-core/picard/sortvcf/meta.yml @@ -22,6 +22,7 @@ input: type: file description: VCF file pattern: "*.{vcf,vcf.gz}" + ontologies: [] - - meta2: type: map description: | @@ -31,6 +32,7 @@ input: type: file description: Reference genome fasta file pattern: "*.{fasta,fa}" + ontologies: [] - - meta3: type: map description: | @@ -40,9 +42,10 @@ input: type: file description: Reference genome dictionary file pattern: "*.{dict}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,11 +54,28 @@ output: type: file description: Sorted VCF file pattern: "*.{vcf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard SortVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard SortVcf --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/picard/sortvcf/tests/main.nf.test b/modules/nf-core/picard/sortvcf/tests/main.nf.test index 9df73ad43..a594b011b 100644 --- a/modules/nf-core/picard/sortvcf/tests/main.nf.test +++ b/modules/nf-core/picard/sortvcf/tests/main.nf.test @@ -16,15 +16,14 @@ nextflow_process { process { """ input[0] = [ [ id:'test' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) - ] - input[1] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) - ] - + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) + ] + input[1] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + ] """ } } @@ -33,12 +32,36 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.vcf[0][1]).linesGzip[3..7], - process.out.versions - ).match() - } + path(process.out.vcf[0][1]).linesGzip[3..7], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } + test("test-picard-sortvcf stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) + ] + input[1] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/sortvcf/tests/main.nf.test.snap b/modules/nf-core/picard/sortvcf/tests/main.nf.test.snap index e4a02c4f3..25dcb7ef6 100644 --- a/modules/nf-core/picard/sortvcf/tests/main.nf.test.snap +++ b/modules/nf-core/picard/sortvcf/tests/main.nf.test.snap @@ -1,4 +1,30 @@ { + "test-picard-sortvcf stub": { + "content": [ + { + "vcf": [ + [ + { + "id": "test" + }, + "test_sorted.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_picard": [ + [ + "PICARD_SORTVCF", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:40:26.218029661", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, "test-picard-sortvcf": { "content": [ [ @@ -8,14 +34,20 @@ "##INFO=", "##INFO=" ], - [ - "versions.yml:md5,e6e6356d3b5b1b8e8cfd5d4958c694e6" - ] + { + "versions_picard": [ + [ + "PICARD_SORTVCF", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T11:47:50.61817621", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:45:30.685264704" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } } } \ No newline at end of file diff --git a/modules/nf-core/qualimap/bamqc/environment.yml b/modules/nf-core/qualimap/bamqc/environment.yml deleted file mode 100644 index 4fa5f4e8e..000000000 --- a/modules/nf-core/qualimap/bamqc/environment.yml +++ /dev/null @@ -1,5 +0,0 @@ -channels: - - conda-forge - - bioconda -dependencies: - - bioconda::qualimap=2.3 diff --git a/modules/nf-core/qualimap/bamqc/main.nf b/modules/nf-core/qualimap/bamqc/main.nf deleted file mode 100644 index 8140e143e..000000000 --- a/modules/nf-core/qualimap/bamqc/main.nf +++ /dev/null @@ -1,123 +0,0 @@ -process QUALIMAP_BAMQC { - tag "$meta.id" - label 'process_medium' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/qualimap:2.3--hdfd78af_0' : - 'biocontainers/qualimap:2.3--hdfd78af_0' }" - - input: - tuple val(meta), path(bam) - path gff - - output: - tuple val(meta), path("${prefix}"), emit: results - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - - def collect_pairs = meta.single_end ? '' : '--collect-overlap-pairs' - def memory = (task.memory.mega*0.8).intValue() + 'M' - def regions = gff ? "--gff $gff" : '' - - def strandedness = 'non-strand-specific' - if (meta.strandedness == 'forward') { - strandedness = 'strand-specific-forward' - } else if (meta.strandedness == 'reverse') { - strandedness = 'strand-specific-reverse' - } - """ - unset DISPLAY - mkdir -p tmp - export _JAVA_OPTIONS=-Djava.io.tmpdir=./tmp - qualimap \\ - --java-mem-size=$memory \\ - bamqc \\ - $args \\ - -bam $bam \\ - $regions \\ - -p $strandedness \\ - $collect_pairs \\ - -outdir $prefix \\ - -nt $task.cpus - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - qualimap: \$(echo \$(qualimap 2>&1) | sed 's/^.*QualiMap v.//; s/Built.*\$//') - END_VERSIONS - """ - - stub: - prefix = task.ext.suffix ? "${meta.id}${task.ext.suffix}" : "${meta.id}" - """ - mkdir -p $prefix/css - mkdir $prefix/images_qualimapReport - mkdir $prefix/raw_data_qualimapReport - cd $prefix/css - touch agogo.css - touch basic.css - touch bgtop.png - touch comment-close.png - touch doctools.js - touch down-pressed.png - touch jquery.js - touch plus.png - touch qualimap_logo_small.png - touch searchtools.js - touch up.png - touch websupport.js - touch ajax-loader.gif - touch bgfooter.png - touch comment-bright.png - touch comment.png - touch down.png - touch file.png - touch minus.png - touch pygments.css - touch report.css - touch underscore.js - touch up-pressed.png - cd ../images_qualimapReport/ - touch genome_coverage_0to50_histogram.png - touch genome_coverage_quotes.png - touch genome_insert_size_across_reference.png - touch genome_mapping_quality_histogram.png - touch genome_uniq_read_starts_histogram.png - touch genome_coverage_across_reference.png - touch genome_gc_content_per_window.png - touch genome_insert_size_histogram.png - touch genome_reads_clipping_profile.png - touch genome_coverage_histogram.png - touch genome_homopolymer_indels.png - touch genome_mapping_quality_across_reference.png - touch genome_reads_content_per_read_position.png - cd ../raw_data_qualimapReport - touch coverage_across_reference.txt - touch genome_fraction_coverage.txt - touch insert_size_histogram.txt - touch mapped_reads_nucleotide_content.txt - touch coverage_histogram.txt - touch homopolymer_indels.txt - touch mapped_reads_clipping_profile.txt - touch mapping_quality_across_reference.txt - touch duplication_rate_histogram.txt - touch insert_size_across_reference.txt - touch mapped_reads_gc-content_distribution.txt - touch mapping_quality_histogram.txt - cd ../ - touch genome_results.txt - touch qualimapReport.html - cd ../ - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - qualimap: \$(echo \$(qualimap 2>&1) | sed 's/^.*QualiMap v.//; s/Built.*\$//') - END_VERSIONS - """ -} diff --git a/modules/nf-core/qualimap/bamqc/meta.yml b/modules/nf-core/qualimap/bamqc/meta.yml deleted file mode 100644 index 8be33c00a..000000000 --- a/modules/nf-core/qualimap/bamqc/meta.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: qualimap_bamqc -description: Evaluate alignment data -keywords: - - quality control - - qc - - bam -tools: - - qualimap: - description: | - Qualimap 2 is a platform-independent application written in - Java and R that provides both a Graphical User Interface and - a command-line interface to facilitate the quality control of - alignment sequencing data and its derivatives like feature counts. - homepage: http://qualimap.bioinfo.cipf.es/ - documentation: http://qualimap.conesalab.org/doc_html/index.html - doi: 10.1093/bioinformatics/bts503 - licence: ["GPL-2.0-only"] - identifier: biotools:qualimap -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM file - pattern: "*.{bam}" - - - gff: - type: file - description: Feature file with regions of interest - pattern: "*.{gff,gtf,bed}" -output: - - results: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - ${prefix}: - type: directory - description: Qualimap results dir - pattern: "*/*" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@phue" -maintainers: - - "@phue" diff --git a/modules/nf-core/qualimap/bamqc/tests/main.nf.test b/modules/nf-core/qualimap/bamqc/tests/main.nf.test deleted file mode 100644 index eec1a41a1..000000000 --- a/modules/nf-core/qualimap/bamqc/tests/main.nf.test +++ /dev/null @@ -1,61 +0,0 @@ -nextflow_process { - - name "Test Process QUALIMAP_BAMQC" - script "../main.nf" - process "QUALIMAP_BAMQC" - tag "modules" - tag "modules_nfcore" - tag "qualimap" - tag "qualimap/bamqc" - - test("homo_sapiens [bam]") { - when { - process { - """ - gff = [] - - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) - ]) - input[1] = gff - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot( - file("${process.out.results[0][1]}/qualimapReport.html").name, - path("${process.out.results[0][1]}/genome_results.txt"), - process.out.versions) - .match() } - ) - } - } - - test("homo_sapiens [bam] - stub") { - options "-stub" - when { - process { - """ - gff = [] - - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) - ]) - input[1] = gff - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } -} \ No newline at end of file diff --git a/modules/nf-core/qualimap/bamqc/tests/main.nf.test.snap b/modules/nf-core/qualimap/bamqc/tests/main.nf.test.snap deleted file mode 100644 index fb6e23e49..000000000 --- a/modules/nf-core/qualimap/bamqc/tests/main.nf.test.snap +++ /dev/null @@ -1,165 +0,0 @@ -{ - "homo_sapiens [bam] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - [ - [ - "agogo.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "ajax-loader.gif:md5,d41d8cd98f00b204e9800998ecf8427e", - "basic.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "bgfooter.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "bgtop.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment-bright.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment-close.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "doctools.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "down-pressed.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "down.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "file.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "jquery.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "minus.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "plus.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "pygments.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "qualimap_logo_small.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "report.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "searchtools.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "underscore.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "up-pressed.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "up.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "websupport.js:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - "genome_results.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - [ - "genome_coverage_0to50_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_quotes.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_gc_content_per_window.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_homopolymer_indels.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_insert_size_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_insert_size_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_mapping_quality_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_mapping_quality_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_reads_clipping_profile.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_reads_content_per_read_position.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_uniq_read_starts_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - "qualimapReport.html:md5,d41d8cd98f00b204e9800998ecf8427e", - [ - "coverage_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "coverage_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "duplication_rate_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_fraction_coverage.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "homopolymer_indels.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "insert_size_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "insert_size_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_clipping_profile.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_gc-content_distribution.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_nucleotide_content.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapping_quality_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapping_quality_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ] - ], - "1": [ - "versions.yml:md5,9024d7d0a189d8be1485249ae591b907" - ], - "results": [ - [ - { - "id": "test", - "single_end": false - }, - [ - [ - "agogo.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "ajax-loader.gif:md5,d41d8cd98f00b204e9800998ecf8427e", - "basic.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "bgfooter.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "bgtop.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment-bright.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment-close.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "comment.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "doctools.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "down-pressed.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "down.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "file.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "jquery.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "minus.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "plus.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "pygments.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "qualimap_logo_small.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "report.css:md5,d41d8cd98f00b204e9800998ecf8427e", - "searchtools.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "underscore.js:md5,d41d8cd98f00b204e9800998ecf8427e", - "up-pressed.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "up.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "websupport.js:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - "genome_results.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - [ - "genome_coverage_0to50_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_coverage_quotes.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_gc_content_per_window.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_homopolymer_indels.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_insert_size_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_insert_size_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_mapping_quality_across_reference.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_mapping_quality_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_reads_clipping_profile.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_reads_content_per_read_position.png:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_uniq_read_starts_histogram.png:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - "qualimapReport.html:md5,d41d8cd98f00b204e9800998ecf8427e", - [ - "coverage_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "coverage_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "duplication_rate_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "genome_fraction_coverage.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "homopolymer_indels.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "insert_size_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "insert_size_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_clipping_profile.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_gc-content_distribution.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapped_reads_nucleotide_content.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapping_quality_across_reference.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "mapping_quality_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ] - ], - "versions": [ - "versions.yml:md5,9024d7d0a189d8be1485249ae591b907" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-22T12:27:15.04081" - }, - "homo_sapiens [bam]": { - "content": [ - "qualimapReport.html", - "genome_results.txt:md5,45103d63ba82df2b905eb04819c32dd3", - [ - "versions.yml:md5,9024d7d0a189d8be1485249ae591b907" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-22T11:21:02.541915" - } -} \ No newline at end of file diff --git a/modules/nf-core/qualimap/bamqc/tests/tags.yml b/modules/nf-core/qualimap/bamqc/tests/tags.yml deleted file mode 100644 index b2b5eb6fc..000000000 --- a/modules/nf-core/qualimap/bamqc/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -qualimap/bamqc: - - modules/nf-core/qualimap/bamqc/** diff --git a/modules/nf-core/rhocall/annotate/environment.yml b/modules/nf-core/rhocall/annotate/environment.yml index ba95c3cbe..8a0fe435e 100644 --- a/modules/nf-core/rhocall/annotate/environment.yml +++ b/modules/nf-core/rhocall/annotate/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/rhocall/annotate/main.nf b/modules/nf-core/rhocall/annotate/main.nf index 78de45c18..070d37c1c 100644 --- a/modules/nf-core/rhocall/annotate/main.nf +++ b/modules/nf-core/rhocall/annotate/main.nf @@ -4,8 +4,8 @@ process RHOCALL_ANNOTATE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/rhocall:0.5.1--py39hbf8eff0_0': - 'biocontainers/rhocall:0.5.1--py39hbf8eff0_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/7d/7dbf7021085cfea72a20cafffe57fcf47392706d9a433f1143f1e60b389b85ae/data': + 'community.wave.seqera.io/library/rhocall:0.5.1--a7eced77e39d2b82' }" input: tuple val(meta), path(vcf), path(tbi) @@ -14,7 +14,7 @@ process RHOCALL_ANNOTATE { output: tuple val(meta), path("*_rhocall.vcf"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("rhocall"), eval("rhocall --version | sed 's/rhocall, version //'"), topic: versions, emit: versions_rhocall when: task.ext.when == null || task.ext.when @@ -24,6 +24,8 @@ process RHOCALL_ANNOTATE { def prefix = task.ext.prefix ?: "${meta.id}" def az_bed = bed ? "-b ${bed}" : '' """ + export MPLCONFIGDIR=\$PWD + rhocall \\ annotate \\ $args \\ @@ -31,21 +33,13 @@ process RHOCALL_ANNOTATE { -r $roh \\ -o ${prefix}_rhocall.vcf \\ $vcf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rhocall: \$(echo \$(rhocall --version 2>&1) | sed 's/rhocall, version //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}_rhocall.vcf + export MPLCONFIGDIR=\$PWD - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rhocall: \$(echo \$(rhocall --version 2>&1) | sed 's/rhocall, version //' ) - END_VERSIONS + touch ${prefix}_rhocall.vcf """ } diff --git a/modules/nf-core/rhocall/annotate/meta.yml b/modules/nf-core/rhocall/annotate/meta.yml index fb041cae8..4df7c6d6e 100644 --- a/modules/nf-core/rhocall/annotate/meta.yml +++ b/modules/nf-core/rhocall/annotate/meta.yml @@ -10,7 +10,8 @@ tools: homepage: "https://github.com/dnil/rhocall" documentation: "https://github.com/dnil/rhocall" tool_dev_url: "https://github.com/dnil" - licence: ["GPL v3"] + licence: + - "GPL v3" identifier: "" input: - - meta: @@ -22,10 +23,12 @@ input: type: file description: vcf file pattern: "*.{vcf,vcf.gz}" + ontologies: [] - tbi: type: file description: vcf index file pattern: "*.{tbi}" + ontologies: [] - - meta2: type: map description: | @@ -35,13 +38,15 @@ input: type: file description: Bcftools roh style TSV file with CHR,POS,AZ,QUAL pattern: "*.{roh}" - - - bed: - type: file - description: BED file with AZ windows. - pattern: "*.{bed}" + ontologies: [] + - bed: + type: file + description: BED file with AZ windows. + pattern: "*.{bed}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -50,11 +55,28 @@ output: type: file description: vcf file pattern: "*.{vcf,vcf.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_rhocall: + - - ${task.process}: + type: string + description: The name of the process + - rhocall: + type: string + description: The name of the tool + - rhocall --version | sed 's/rhocall, version //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - rhocall: + type: string + description: The name of the tool + - rhocall --version | sed 's/rhocall, version //': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/rhocall/annotate/tests/main.nf.test b/modules/nf-core/rhocall/annotate/tests/main.nf.test new file mode 100644 index 000000000..fafd3826d --- /dev/null +++ b/modules/nf-core/rhocall/annotate/tests/main.nf.test @@ -0,0 +1,87 @@ +nextflow_process { + + name "Test Process RHOCALL_ANNOTATE" + + script "../main.nf" + process "RHOCALL_ANNOTATE" + + tag "modules" + tag "modules_nfcore" + tag "rhocall" + tag "rhocall/annotate" + tag "bcftools" + tag "bcftools/roh" + + setup { + run("BCFTOOLS_ROH") { + script "../../../bcftools/roh/main.nf" + + process { + """ + input[0] = [[id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists:true) + ] + input[1] = [[],[]] + input[2] = [] + input[3] = [] + input[4] = [] + input[5] = [] + """ + } + } + } + + test("sarscov2") { + + when { + params { + module_args = '' + } + process { + """ + input[0] = [[id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists:true) + ] + input[1] = BCFTOOLS_ROH.out.roh + input[2] = [] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.vcf[0][1]).vcf.variantsMD5, + process.out.findAll {key, value -> key.startsWith("versions")} + ).match() } + ) + } + } + + test("sarscov2 - stub") { + options '-stub' + when { + params { + module_args = '' + } + process { + """ + input[0] = [[id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists:true)] + input[1] = BCFTOOLS_ROH.out.roh + input[2] = [] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/rhocall/annotate/tests/main.nf.test.snap b/modules/nf-core/rhocall/annotate/tests/main.nf.test.snap new file mode 100644 index 000000000..44987e7fd --- /dev/null +++ b/modules/nf-core/rhocall/annotate/tests/main.nf.test.snap @@ -0,0 +1,62 @@ +{ + "sarscov2 - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test_rhocall.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "RHOCALL_ANNOTATE", + "rhocall", + "0.5.1" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test_rhocall.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_rhocall": [ + [ + "RHOCALL_ANNOTATE", + "rhocall", + "0.5.1" + ] + ] + } + ], + "timestamp": "2026-02-18T10:11:48.513471", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2": { + "content": [ + "bc7bf3ee9e8430e064c539eb81e59bf9", + { + "versions_rhocall": [ + [ + "RHOCALL_ANNOTATE", + "rhocall", + "0.5.1" + ] + ] + } + ], + "timestamp": "2026-02-18T10:14:26.928869", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/rhocall/viz/environment.yml b/modules/nf-core/rhocall/viz/environment.yml index 538db5092..8a0fe435e 100644 --- a/modules/nf-core/rhocall/viz/environment.yml +++ b/modules/nf-core/rhocall/viz/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - "bioconda::rhocall=0.5.1" + - bioconda::rhocall=0.5.1 diff --git a/modules/nf-core/rhocall/viz/main.nf b/modules/nf-core/rhocall/viz/main.nf index 4191ef3bc..78c048ede 100644 --- a/modules/nf-core/rhocall/viz/main.nf +++ b/modules/nf-core/rhocall/viz/main.nf @@ -4,8 +4,8 @@ process RHOCALL_VIZ { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/rhocall:0.5.1--py39hbf8eff0_0': - 'biocontainers/rhocall:0.5.1--py39hbf8eff0_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/7d/7dbf7021085cfea72a20cafffe57fcf47392706d9a433f1143f1e60b389b85ae/data': + 'community.wave.seqera.io/library/rhocall:0.5.1--a7eced77e39d2b82' }" input: tuple val(meta), path(vcf) @@ -14,7 +14,7 @@ process RHOCALL_VIZ { output: tuple val(meta), path("${prefix}/${prefix}.bed"), emit: bed tuple val(meta), path("${prefix}/${prefix}.wig"), emit: wig - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("rhocall"), eval("rhocall --version | sed 's/rhocall, version //'"), topic: versions, emit: versions_rhocall when: task.ext.when == null || task.ext.when @@ -32,11 +32,6 @@ process RHOCALL_VIZ { mv ${prefix}/output.bed ${prefix}/${prefix}.bed mv ${prefix}/output.wig ${prefix}/${prefix}.wig - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rhocall: \$(echo \$(rhocall --version 2>&1) | sed 's/rhocall, version //' ) - END_VERSIONS """ stub: @@ -45,10 +40,5 @@ process RHOCALL_VIZ { mkdir ${prefix} touch ${prefix}/${prefix}.bed touch ${prefix}/${prefix}.wig - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rhocall: \$(echo \$(rhocall --version 2>&1) | sed 's/rhocall, version //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/rhocall/viz/meta.yml b/modules/nf-core/rhocall/viz/meta.yml index 7efcab02a..5911cae46 100644 --- a/modules/nf-core/rhocall/viz/meta.yml +++ b/modules/nf-core/rhocall/viz/meta.yml @@ -10,9 +10,9 @@ tools: homepage: "https://github.com/dnil/rhocall" documentation: "https://github.com/dnil/rhocall" tool_dev_url: "https://github.com/dnil" - licence: ["GPL v3"] + licence: + - "GPL v3" identifier: "" - input: - - meta: type: map @@ -23,6 +23,7 @@ input: type: file description: VCF file pattern: "*.{vcf}" + ontologies: [] - - meta2: type: map description: | @@ -32,9 +33,10 @@ input: type: file description: Input RHO file produced from rhocall pattern: "*.{roh}" + ontologies: [] output: - - bed: - - meta: + bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -43,8 +45,9 @@ output: type: file description: Bed file containing roh calls pattern: "*.{bed}" - - wig: - - meta: + ontologies: [] + wig: + - - meta: type: map description: | Groovy Map containing sample information @@ -53,11 +56,28 @@ output: type: file description: Wig file containing roh calls pattern: "*.{wig}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_rhocall: + - - ${task.process}: + type: string + description: The name of the process + - rhocall: + type: string + description: The name of the tool + - rhocall --version | sed 's/rhocall, version //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - rhocall: + type: string + description: The name of the tool + - rhocall --version | sed 's/rhocall, version //': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/rhocall/viz/tests/main.nf.test.snap b/modules/nf-core/rhocall/viz/tests/main.nf.test.snap index cba4067f2..c7c75a230 100644 --- a/modules/nf-core/rhocall/viz/tests/main.nf.test.snap +++ b/modules/nf-core/rhocall/viz/tests/main.nf.test.snap @@ -19,7 +19,11 @@ ] ], "2": [ - "versions.yml:md5,079291120b14dd6b9368dd1cff72518e" + [ + "RHOCALL_VIZ", + "rhocall", + "0.5.1" + ] ], "bed": [ [ @@ -29,8 +33,12 @@ "test.bed:md5,4579710bbd8e1e4449274d261c439891" ] ], - "versions": [ - "versions.yml:md5,079291120b14dd6b9368dd1cff72518e" + "versions_rhocall": [ + [ + "RHOCALL_VIZ", + "rhocall", + "0.5.1" + ] ], "wig": [ [ @@ -42,6 +50,10 @@ ] } ], - "timestamp": "2024-02-05T17:57:24.70125206" + "timestamp": "2026-02-18T10:11:58.070955", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/rhocall/viz/tests/tags.yml b/modules/nf-core/rhocall/viz/tests/tags.yml deleted file mode 100644 index bc2d74a70..000000000 --- a/modules/nf-core/rhocall/viz/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -rhocall/viz: - - "modules/nf-core/rhocall/viz/**" diff --git a/modules/nf-core/rtgtools/format/environment.yml b/modules/nf-core/rtgtools/format/environment.yml index 8aa83cdc4..27597a220 100644 --- a/modules/nf-core/rtgtools/format/environment.yml +++ b/modules/nf-core/rtgtools/format/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::rtg-tools=3.12.1 + - bioconda::rtg-tools=3.13 diff --git a/modules/nf-core/rtgtools/format/main.nf b/modules/nf-core/rtgtools/format/main.nf index 9cae7f99c..ffbbbdfb9 100644 --- a/modules/nf-core/rtgtools/format/main.nf +++ b/modules/nf-core/rtgtools/format/main.nf @@ -4,15 +4,15 @@ process RTGTOOLS_FORMAT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/rtg-tools:3.12.1--hdfd78af_0': - 'biocontainers/rtg-tools:3.12.1--hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/dc/dca5ba13b7ec38bf7cacf00a33517b9080067bea638745c05d50a4957c75fc2e/data': + 'community.wave.seqera.io/library/rtg-tools:3.13--3465421f1b0be0ce' }" input: tuple val(meta), path(input1), path(input2), path(sam_rg) output: tuple val(meta), path("*.sdf"), emit: sdf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('rtgtools'), eval("rtg version | head -n 1 | sed 's/Product: RTG Tools //'"), topic: versions, emit: versions_rtgtools when: task.ext.when == null || task.ext.when @@ -38,11 +38,6 @@ process RTGTOOLS_FORMAT { ${rg} \\ --output ${prefix}.sdf \\ ${input} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rtg-tools: \$(echo \$(rtg version | head -n 1 | awk '{print \$4}')) - END_VERSIONS """ stub: @@ -56,10 +51,5 @@ process RTGTOOLS_FORMAT { } """ touch ${prefix}.sdf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rtg-tools: \$(echo \$(rtg version | head -n 1 | awk '{print \$4}')) - END_VERSIONS """ } diff --git a/modules/nf-core/rtgtools/format/meta.yml b/modules/nf-core/rtgtools/format/meta.yml index e09aff3af..309a9ffb0 100644 --- a/modules/nf-core/rtgtools/format/meta.yml +++ b/modules/nf-core/rtgtools/format/meta.yml @@ -1,6 +1,6 @@ name: "rtgtools_format" -description: Converts the contents of sequence data files (FASTA/FASTQ/SAM/BAM) into - the RTG Sequence Data File (SDF) format. +description: Converts the contents of sequence data files (FASTA/FASTQ/SAM/BAM) + into the RTG Sequence Data File (SDF) format. keywords: - rtg - fasta @@ -12,9 +12,10 @@ tools: description: "RealTimeGenomics Tools -- Utilities for accurate VCF comparison and manipulation" homepage: "https://www.realtimegenomics.com/products/rtg-tools" - documentation: "https://github.com/RealTimeGenomics/rtg-tools" + documentation: "https://cdn.jsdelivr.net/gh/RealTimeGenomics/rtg-tools@master/installer/resources/tools/RTGOperationsManual.pdf" tool_dev_url: "https://github.com/RealTimeGenomics/rtg-tools" - licence: ["BSD"] + licence: + - "BSD" identifier: "" input: - - meta: @@ -24,34 +25,57 @@ input: e.g. [ id:'test', single_end:false ] - input1: type: file - description: FASTA, FASTQ, BAM or SAM file. This should be the left input file - when using paired end FASTQ/FASTA data + description: FASTA, FASTQ, BAM or SAM file. This should be the left input + file when using paired end FASTQ/FASTA data pattern: "*.{fasta,fa,fna,fastq,fastq.gz,fq,fq.gz,bam,sam}" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ - input2: type: file description: The right input file when using paired end FASTQ/FASTA data pattern: "*.{fasta,fa,fna,fastq,fastq.gz,fq,fq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ - sam_rg: type: file - description: A file containing a single readgroup header as a SAM header. This - can also be supplied as a string in `task.ext.args` as `--sam-rg `. + description: A file containing a single readgroup header as a SAM header. + This can also be supplied as a string in `task.ext.args` as `--sam-rg + `. pattern: "*.{txt,sam}" + ontologies: [] output: - - sdf: - - meta: + sdf: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.sdf": type: directory - description: The sequence dictionary format folder created from the input file(s) + description: The sequence dictionary format folder created from the + input file(s) pattern: "*.sdf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_rtgtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rtgtools: + type: string + description: The name of the tool + - "rtg version | head -n 1 | sed 's/Product: RTG Tools //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rtgtools: + type: string + description: The name of the tool + - "rtg version | head -n 1 | sed 's/Product: RTG Tools //'": + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" maintainers: diff --git a/modules/nf-core/rtgtools/format/tests/fastq.config b/modules/nf-core/rtgtools/format/tests/fastq.config new file mode 100644 index 000000000..24540986e --- /dev/null +++ b/modules/nf-core/rtgtools/format/tests/fastq.config @@ -0,0 +1,3 @@ +process { + ext.args = "--format fastq" +} diff --git a/modules/nf-core/rtgtools/format/tests/main.nf.test b/modules/nf-core/rtgtools/format/tests/main.nf.test new file mode 100644 index 000000000..d768da7d8 --- /dev/null +++ b/modules/nf-core/rtgtools/format/tests/main.nf.test @@ -0,0 +1,138 @@ +nextflow_process { + + name "Test Process RTGTOOLS_FORMAT" + script "../main.nf" + process "RTGTOOLS_FORMAT" + + tag "modules" + tag "modules_nfcore" + tag "rtgtools" + tag "rtgtools/format" + + test("sarscov2 - fasta") { + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.sdf[0][1]).list().collect { file(it.toString()).name }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + + } + + test("sarscov2 - fastqs") { + + config "./fastq.config" + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + [] + ] + """ + } + } + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.sdf[0][1]).list().collect { file(it.toString()).name }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + + } + + test("sarscov2 - bam, rg") { + + config "./sam.config" + + when { + process { + """ + def rg = Channel.of("@RG\tID:READGROUP1\tSM:SAMPLE\tPL:ILLUMINA") + .collectFile(name:'sam_rg.txt') + + input[0] = Channel.of([ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true), + [] + ]).combine(rg) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.sdf[0][1]).list().collect { file(it.toString()).name }, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + + } + + test("sarscov2 - fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/rtgtools/format/tests/main.nf.test.snap b/modules/nf-core/rtgtools/format/tests/main.nf.test.snap new file mode 100644 index 000000000..437afa7af --- /dev/null +++ b/modules/nf-core/rtgtools/format/tests/main.nf.test.snap @@ -0,0 +1,144 @@ +{ + "sarscov2 - fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.sdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "RTGTOOLS_FORMAT", + "rtgtools", + "3.13" + ] + ], + "sdf": [ + [ + { + "id": "test" + }, + "test.sdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_rtgtools": [ + [ + "RTGTOOLS_FORMAT", + "rtgtools", + "3.13" + ] + ] + } + ], + "timestamp": "2026-02-12T14:17:42.538436462", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } + }, + "sarscov2 - fasta": { + "content": [ + [ + "done", + "format.log", + "mainIndex", + "nameIndex0", + "namedata0", + "namepointer0", + "progress", + "seqdata0", + "seqpointer0", + "sequenceIndex0", + "suffixIndex0", + "suffixdata0", + "suffixpointer0", + "summary.txt" + ], + { + "versions_rtgtools": [ + [ + "RTGTOOLS_FORMAT", + "rtgtools", + "3.13" + ] + ] + } + ], + "timestamp": "2026-02-12T14:17:07.354438336", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } + }, + "sarscov2 - fastqs": { + "content": [ + [ + "done", + "format.log", + "mainIndex", + "nameIndex0", + "namedata0", + "namepointer0", + "progress", + "qualitydata0", + "seqdata0", + "seqpointer0", + "sequenceIndex0", + "suffixIndex0", + "suffixdata0", + "suffixpointer0", + "summary.txt" + ], + { + "versions_rtgtools": [ + [ + "RTGTOOLS_FORMAT", + "rtgtools", + "3.13" + ] + ] + } + ], + "timestamp": "2026-02-12T14:17:19.613328433", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } + }, + "sarscov2 - bam, rg": { + "content": [ + [ + "done", + "format.log", + "mainIndex", + "nameIndex0", + "namedata0", + "namepointer0", + "progress", + "qualitydata0", + "seqdata0", + "seqpointer0", + "sequenceIndex0", + "summary.txt" + ], + { + "versions_rtgtools": [ + [ + "RTGTOOLS_FORMAT", + "rtgtools", + "3.13" + ] + ] + } + ], + "timestamp": "2026-02-12T14:17:31.66811346", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/rtgtools/format/tests/sam.config b/modules/nf-core/rtgtools/format/tests/sam.config new file mode 100644 index 000000000..5ccfdb27b --- /dev/null +++ b/modules/nf-core/rtgtools/format/tests/sam.config @@ -0,0 +1,3 @@ +process { + ext.args = "--format sam-se" +} diff --git a/modules/nf-core/rtgtools/vcfeval/environment.yml b/modules/nf-core/rtgtools/vcfeval/environment.yml index 8aa83cdc4..27597a220 100644 --- a/modules/nf-core/rtgtools/vcfeval/environment.yml +++ b/modules/nf-core/rtgtools/vcfeval/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::rtg-tools=3.12.1 + - bioconda::rtg-tools=3.13 diff --git a/modules/nf-core/rtgtools/vcfeval/main.nf b/modules/nf-core/rtgtools/vcfeval/main.nf index 330a1f3d9..82477eb11 100644 --- a/modules/nf-core/rtgtools/vcfeval/main.nf +++ b/modules/nf-core/rtgtools/vcfeval/main.nf @@ -4,8 +4,8 @@ process RTGTOOLS_VCFEVAL { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/rtg-tools:3.12.1--hdfd78af_0': - 'biocontainers/rtg-tools:3.12.1--hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/dc/dca5ba13b7ec38bf7cacf00a33517b9080067bea638745c05d50a4957c75fc2e/data': + 'community.wave.seqera.io/library/rtg-tools:3.13--3465421f1b0be0ce' }" input: tuple val(meta), path(query_vcf), path(query_vcf_tbi), path(truth_vcf), path(truth_vcf_tbi), path(truth_bed), path(regions_bed) @@ -25,7 +25,8 @@ process RTGTOOLS_VCFEVAL { tuple val(meta), path("*.weighted_roc.tsv.gz") , emit: weighted_roc tuple val(meta), path("*.summary.txt") , emit: summary tuple val(meta), path("*.phasing.txt") , emit: phasing - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('rtgtools'), eval("rtg version | sed 's/Product: RTG Tools //; q'"), topic: versions, emit: versions_rtgtools + when: task.ext.when == null || task.ext.when @@ -57,11 +58,6 @@ process RTGTOOLS_VCFEVAL { mv done progress .. for f in * ; do mv "\$f" "../${prefix}.\$f" ; done cd .. - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rtg-tools: \$(echo \$(rtg version | head -n 1 | awk '{print \$4}')) - END_VERSIONS """ stub: @@ -81,10 +77,5 @@ process RTGTOOLS_VCFEVAL { echo | gzip > ${prefix}.weighted_roc.tsv.gz touch ${prefix}.summary.txt touch ${prefix}.phasing.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - rtg-tools: \$(echo \$(rtg version | head -n 1 | awk '{print \$4}')) - END_VERSIONS """ } diff --git a/modules/nf-core/rtgtools/vcfeval/meta.yml b/modules/nf-core/rtgtools/vcfeval/meta.yml index 4c59bab52..bfe06aa94 100644 --- a/modules/nf-core/rtgtools/vcfeval/meta.yml +++ b/modules/nf-core/rtgtools/vcfeval/meta.yml @@ -1,6 +1,6 @@ name: "rtgtools_vcfeval" -description: The VCFeval tool of RTG tools. It is used to evaluate called variants - for agreement with a baseline variant set +description: The VCFeval tool of RTG tools. It is used to evaluate called + variants for agreement with a baseline variant set keywords: - benchmarking - vcf @@ -10,9 +10,10 @@ tools: description: "RealTimeGenomics Tools -- Utilities for accurate VCF comparison and manipulation" homepage: "https://www.realtimegenomics.com/products/rtg-tools" - documentation: "https://github.com/RealTimeGenomics/rtg-tools" + documentation: "https://cdn.jsdelivr.net/gh/RealTimeGenomics/rtg-tools@master/installer/resources/tools/RTGOperationsManual.pdf" tool_dev_url: "https://github.com/RealTimeGenomics/rtg-tools" - licence: ["BSD"] + licence: + - "BSD" identifier: "" input: - - meta: @@ -24,30 +25,37 @@ input: type: file description: A VCF with called variants to benchmark against the standard pattern: "*.{vcf,vcf.gz}" + ontologies: [] - query_vcf_tbi: type: file - description: The index of the VCF file with called variants to benchmark against the standard + description: The index of the VCF file with called variants to benchmark + against the standard pattern: "*.{vcf.gz.tbi, vcf.tbi}" + ontologies: [] - truth_vcf: type: file description: A standard VCF to compare against pattern: "*.{vcf,vcf.gz}" + ontologies: [] - truth_vcf_tbi: type: file description: The index of the standard VCF to compare against pattern: "*.{vcf.gz.tbi, vcf.tbi}" + ontologies: [] - truth_bed: type: file - description: A BED file containining the strict regions where VCFeval should - only evaluate the fully overlapping variants (optional) - This input should be used to provide the golden truth BED files. + description: A BED file containing the strict regions where VCFeval should + only evaluate the fully overlapping variants (optional) This input + should be used to provide the golden truth BED files. pattern: "*.bed" + ontologies: [] - regions_bed: type: file - description: A BED file containing the regions where VCFeval will evaluate every - fully and partially overlapping variant (optional) - This input should be used to provide the regions used by the analysis + description: A BED file containing the regions where VCFeval will evaluate + every fully and partially overlapping variant (optional) This input + should be used to provide the regions used by the analysis pattern: "*.bed" + ontologies: [] - - meta2: type: map description: | @@ -55,10 +63,12 @@ input: e.g. [ id:'test', single_end:false ] - sdf: type: file - description: The SDF (RTG Sequence Data File) folder of the reference genome + description: The SDF (RTG Sequence Data File) folder of the reference + genome + ontologies: [] output: - - tp_vcf: - - meta: + tp_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -67,8 +77,10 @@ output: type: file description: A VCF file for the true positive variants pattern: "*.tp.vcf.gz" - - tp_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tp_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -77,8 +89,9 @@ output: type: file description: The index of the VCF file for the true positive variants pattern: "*.tp.vcf.gz.tbi" - - fn_vcf: - - meta: + ontologies: [] + fn_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -87,8 +100,10 @@ output: type: file description: A VCF file for the false negative variants pattern: "*.fn.vcf.gz" - - fn_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + fn_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -97,8 +112,9 @@ output: type: file description: The index of the VCF file for the false negative variants pattern: "*.fn.vcf.gz.tbi" - - fp_vcf: - - meta: + ontologies: [] + fp_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -107,8 +123,10 @@ output: type: file description: A VCF file for the false positive variants pattern: "*.fp.vcf.gz" - - fp_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + fp_tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -117,8 +135,9 @@ output: type: file description: The index of the VCF file for the false positive variants pattern: "*.fp.vcf.gz.tbi" - - baseline_vcf: - - meta: + ontologies: [] + baseline_vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -127,19 +146,22 @@ output: type: file description: A VCF file for the true positive variants from the baseline pattern: "*.tp-baseline.vcf.gz" - - baseline_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + baseline_tbi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.tp-baseline.vcf.gz.tbi": type: file - description: The index of the VCF file for the true positive variants from the - baseline + description: The index of the VCF file for the true positive variants + from the baseline pattern: "*.tp-baseline.vcf.gz.tbi" - - snp_roc: - - meta: + ontologies: [] + snp_roc: + - - meta: type: map description: | Groovy Map containing sample information @@ -148,8 +170,10 @@ output: type: file description: TSV files containing ROC data for the SNPs pattern: "*.snp_roc.tsv.gz" - - non_snp_roc: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + non_snp_roc: + - - meta: type: map description: | Groovy Map containing sample information @@ -158,8 +182,10 @@ output: type: file description: TSV files containing ROC data for all variants except SNPs pattern: "*.non_snp_roc.tsv.gz" - - weighted_roc: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + weighted_roc: + - - meta: type: map description: | Groovy Map containing sample information @@ -168,8 +194,10 @@ output: type: file description: TSV files containing weighted ROC data for all variants pattern: "*.weighted_snp_roc.tsv.gz" - - summary: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + summary: + - - meta: type: map description: | Groovy Map containing sample information @@ -178,8 +206,9 @@ output: type: file description: A TXT file containing the summary of the evaluation pattern: "*.summary.txt" - - phasing: - - meta: + ontologies: [] + phasing: + - - meta: type: map description: | Groovy Map containing sample information @@ -188,11 +217,28 @@ output: type: file description: A TXT file containing the data on the phasing pattern: "*.phasing.txt" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_rtgtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rtgtools: + type: string + description: The name of the tool + - "rtg version | sed 's/Product: RTG Tools //; q'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rtgtools: + type: string + description: The name of the tool + - "rtg version | sed 's/Product: RTG Tools //; q'": + type: eval + description: The expression to obtain the version of the tool authors: - "@nvnieuwk" maintainers: diff --git a/modules/nf-core/rtgtools/vcfeval/tests/main.nf.test.snap b/modules/nf-core/rtgtools/vcfeval/tests/main.nf.test.snap index 4f39e2d46..f85d503e5 100644 --- a/modules/nf-core/rtgtools/vcfeval/tests/main.nf.test.snap +++ b/modules/nf-core/rtgtools/vcfeval/tests/main.nf.test.snap @@ -23,7 +23,7 @@ { "id": "test" }, - "test.weighted_roc.tsv.gz:md5,de36bf613b3dacf4a043311336bb4a94" + "test.weighted_roc.tsv.gz:md5,c0155caab6b8a314c303ca1b481ba1af" ] ], "11": [ @@ -43,7 +43,11 @@ ] ], "13": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "2": [ [ @@ -98,7 +102,7 @@ { "id": "test" }, - "test.snp_roc.tsv.gz:md5,11d7393a16c25ac0a092382fecafee9b" + "test.snp_roc.tsv.gz:md5,6c8977c744a08c90123a21f22c0f4e54" ] ], "9": [ @@ -106,7 +110,7 @@ { "id": "test" }, - "test.non_snp_roc.tsv.gz:md5,eb0910409b8b088655defbd152103b81" + "test.non_snp_roc.tsv.gz:md5,574afefc756c4102bb3aefb0cde19dff" ] ], "baseline_tbi": [ @@ -162,7 +166,7 @@ { "id": "test" }, - "test.non_snp_roc.tsv.gz:md5,eb0910409b8b088655defbd152103b81" + "test.non_snp_roc.tsv.gz:md5,574afefc756c4102bb3aefb0cde19dff" ] ], "phasing": [ @@ -178,7 +182,7 @@ { "id": "test" }, - "test.snp_roc.tsv.gz:md5,11d7393a16c25ac0a092382fecafee9b" + "test.snp_roc.tsv.gz:md5,6c8977c744a08c90123a21f22c0f4e54" ] ], "summary": [ @@ -205,24 +209,28 @@ "test.tp.vcf.gz:md5,5171021307097220337dbcaccc860495" ] ], - "versions": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + "versions_rtgtools": [ + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "weighted_roc": [ [ { "id": "test" }, - "test.weighted_roc.tsv.gz:md5,de36bf613b3dacf4a043311336bb4a94" + "test.weighted_roc.tsv.gz:md5,c0155caab6b8a314c303ca1b481ba1af" ] ] } ], + "timestamp": "2026-02-12T13:43:20.930061214", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-30T15:17:31.564974666" + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } }, "homo_sapiens - [vcf, [], truth, [], [], []], sdf": { "content": [ @@ -248,7 +256,7 @@ { "id": "test" }, - "test.weighted_roc.tsv.gz:md5,5dfacd641b080cc8ad22eebec015c698" + "test.weighted_roc.tsv.gz:md5,599331bcba15312abc402bdffc8d2e30" ] ], "11": [ @@ -268,7 +276,11 @@ ] ], "13": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "2": [ [ @@ -323,7 +335,7 @@ { "id": "test" }, - "test.snp_roc.tsv.gz:md5,85edc0101bb9e8d3edc11abe4fdcda93" + "test.snp_roc.tsv.gz:md5,7906ac0bdf54d34ac9b52bfd101cddfd" ] ], "9": [ @@ -331,7 +343,7 @@ { "id": "test" }, - "test.non_snp_roc.tsv.gz:md5,30283ede3bcc5dd247f8a84bf345bf9a" + "test.non_snp_roc.tsv.gz:md5,0917d6986ae90818f431c316b1cbea27" ] ], "baseline_tbi": [ @@ -387,7 +399,7 @@ { "id": "test" }, - "test.non_snp_roc.tsv.gz:md5,30283ede3bcc5dd247f8a84bf345bf9a" + "test.non_snp_roc.tsv.gz:md5,0917d6986ae90818f431c316b1cbea27" ] ], "phasing": [ @@ -403,7 +415,7 @@ { "id": "test" }, - "test.snp_roc.tsv.gz:md5,85edc0101bb9e8d3edc11abe4fdcda93" + "test.snp_roc.tsv.gz:md5,7906ac0bdf54d34ac9b52bfd101cddfd" ] ], "summary": [ @@ -430,24 +442,28 @@ "test.tp.vcf.gz:md5,5125ee41457c9d93f46b19e32788edb4" ] ], - "versions": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + "versions_rtgtools": [ + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "weighted_roc": [ [ { "id": "test" }, - "test.weighted_roc.tsv.gz:md5,5dfacd641b080cc8ad22eebec015c698" + "test.weighted_roc.tsv.gz:md5,599331bcba15312abc402bdffc8d2e30" ] ] } ], + "timestamp": "2026-02-12T13:43:44.651308348", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-30T15:18:04.344989466" + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } }, "homo_sapiens - [vcf, tbi, truth, truth_tbi, truth_bed, regions_bed], sdf - stub": { "content": [ @@ -493,7 +509,11 @@ ] ], "13": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "2": [ [ @@ -655,8 +675,12 @@ "test.tp.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,a228f0d9e8b205b4cc7c485151a77bb0" + "versions_rtgtools": [ + [ + "RTGTOOLS_VCFEVAL", + "rtgtools", + "3.13" + ] ], "weighted_roc": [ [ @@ -668,10 +692,10 @@ ] } ], + "timestamp": "2026-02-12T13:44:03.078796934", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-30T15:23:21.165461388" + "nf-test": "0.9.3", + "nextflow": "25.04.3" + } } } \ No newline at end of file diff --git a/modules/nf-core/ensemblvep/filtervep/environment.yml b/modules/nf-core/saltshaker/call/environment.yml similarity index 50% rename from modules/nf-core/ensemblvep/filtervep/environment.yml rename to modules/nf-core/saltshaker/call/environment.yml index 3d36eb17c..ba1172042 100644 --- a/modules/nf-core/ensemblvep/filtervep/environment.yml +++ b/modules/nf-core/saltshaker/call/environment.yml @@ -2,4 +2,6 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::ensembl-vep=113.0 + - pip==26.0.1 + - pip: + - saltshaker==1.1.1 diff --git a/modules/nf-core/saltshaker/call/main.nf b/modules/nf-core/saltshaker/call/main.nf new file mode 100644 index 000000000..4f16b1f4e --- /dev/null +++ b/modules/nf-core/saltshaker/call/main.nf @@ -0,0 +1,59 @@ +process SALTSHAKER_CALL { + tag "$meta.id" + label 'process_single' + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/5a/5a902cc9f161d602fde9c268a509be2f593cfac7ed4cdc2219f630e02e43b2ec/data': + 'community.wave.seqera.io/library/pip_saltshaker:be40ca61bbf77cf2' }" + + input: + tuple val(meta), path(breakpoint), path(cluster) + tuple val(meta2), path(mtfasta) + val flank + val heteroplasmy_limit + val mito_length + val heavy_strand_origin_start + val heavy_strand_origin_end + val light_strand_origin_start + val light_strand_origin_end + + output: + tuple val(meta), path("*_call_metadata.tsv"), emit: call + tuple val("${task.process}"), val('saltshaker'), val("1.1.1"), topic: versions, emit: versions_saltshaker + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + saltshaker call \\ + --prefix $prefix \\ + --output-dir . \\ + --reference $mtfasta \\ + --cluster $cluster \\ + --breakpoint $breakpoint \\ + --flank-size $flank \\ + --het-limit $heteroplasmy_limit \\ + --genome-length $mito_length \\ + --ori-h-start $heavy_strand_origin_start \\ + --ori-h-end $heavy_strand_origin_end \\ + --ori-l-start $light_strand_origin_start \\ + --ori-l-end $light_strand_origin_end \\ + $args + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + echo $args + + touch ${prefix}.saltshaker_call_metadata.tsv + """ +} diff --git a/modules/nf-core/saltshaker/call/meta.yml b/modules/nf-core/saltshaker/call/meta.yml new file mode 100644 index 000000000..773034b7b --- /dev/null +++ b/modules/nf-core/saltshaker/call/meta.yml @@ -0,0 +1,100 @@ +name: "saltshaker_call" +description: mtDNA deletion and duplication calling downstream of mitosalt +keywords: + - saltshaker + - mitosalt + - mtDNA + - structural-variant calling +tools: + - "saltshaker": + description: "A Python package for classifying and visualizing mitochondrial structural + variants from MitoSAlt pipeline output." + homepage: "https://pypi.org/project/saltshaker" + documentation: "https://pypi.org/project/saltshaker/" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - breakpoint: + type: file + description: breakpoint file from mitosalt + pattern: "*.{breakpoint}" + ontologies: [] + - cluster: + type: file + description: cluster file from mitosalt + pattern: "*.{cluster}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'fasta' ] + - mtfasta: + type: file + description: Reference mitochondrial genome in FASTA format + pattern: "*.{fasta,fa}" + ontologies: [] + - flank: + type: integer + description: Basepairs flanking a deletion + - heteroplasmy_limit: + type: float + description: Minimum heteroplasmy level to report a deletion/duplication + - mito_length: + type: integer + description: Length of the mitochondrial genome + - heavy_strand_origin_start: + type: integer + description: Start position of the heavy strand origin of replication + - heavy_strand_origin_end: + type: integer + description: End position of the heavy strand origin of replication + - light_strand_origin_start: + type: integer + description: Start position of the light strand origin of replication + - light_strand_origin_end: + type: integer + description: End position of the light strand origin of replication +output: + call: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*_call_metadata.tsv": + type: file + description: tsv with variant call metadata to be used in + saltshaker_classify + pattern: "*_call_metadata.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 + versions_saltshaker: + - - ${task.process}: + type: string + description: The name of the process + - saltshaker: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - saltshaker: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: The expression to obtain the version of the tool +authors: + - "@ieduba" +maintainers: + - "@ieduba" diff --git a/modules/nf-core/saltshaker/call/tests/main.nf.test b/modules/nf-core/saltshaker/call/tests/main.nf.test new file mode 100644 index 000000000..8bb37c3b9 --- /dev/null +++ b/modules/nf-core/saltshaker/call/tests/main.nf.test @@ -0,0 +1,94 @@ +nextflow_process { + + name "Test Process SALTSHAKER_CALL" + script "../main.nf" + process "SALTSHAKER_CALL" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "saltshaker" + tag "saltshaker/call" + + test("call - tsv") { + + when { + process { + """ + + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.breakpoint', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.cluster', checkIfExists: true), + ] + + input[1] = [ + [ id:'hg38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/human_mt_rCRS.fasta', checkIfExists: true), + ] + + input[2] = 15 + input[3] = 0.01 + input[4] = 16569 + input[5] = 16081 + input[6] = 407 + input[7] = 5730 + input[8] = 5763 + + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out) + ).match() } + ) + } + + } + + test("call - tsv - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.breakpoint', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.cluster', checkIfExists: true), + ] + + input[1] = [ + [ id:'hg38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/human_mt_rCRS.fasta', checkIfExists: true), + ] + + input[2] = 15 + input[3] = 0.01 + input[4] = 16569 + input[5] = 16081 + input[6] = 407 + input[7] = 5730 + input[8] = 5763 + + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out) + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/saltshaker/call/tests/main.nf.test.snap b/modules/nf-core/saltshaker/call/tests/main.nf.test.snap new file mode 100644 index 000000000..fa9ff6b47 --- /dev/null +++ b/modules/nf-core/saltshaker/call/tests/main.nf.test.snap @@ -0,0 +1,54 @@ +{ + "call - tsv": { + "content": [ + { + "call": [ + [ + { + "id": "test" + }, + "test.saltshaker_call_metadata.tsv:md5,5d0d87c5e2a29a07afa0b60cdb9c72d2" + ] + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CALL", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-01T13:42:19.667355", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "call - tsv - stub": { + "content": [ + { + "call": [ + [ + { + "id": "test" + }, + "test.saltshaker_call_metadata.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CALL", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-01T13:41:08.005824", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/saltshaker/call/tests/nextflow.config b/modules/nf-core/saltshaker/call/tests/nextflow.config new file mode 100644 index 000000000..ba448353c --- /dev/null +++ b/modules/nf-core/saltshaker/call/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'SALTSHAKER_CALL' { + ext.args = '--blacklist' + } +} diff --git a/modules/nf-core/haplocheck/environment.yml b/modules/nf-core/saltshaker/classify/environment.yml similarity index 50% rename from modules/nf-core/haplocheck/environment.yml rename to modules/nf-core/saltshaker/classify/environment.yml index 4fb40238b..ba1172042 100644 --- a/modules/nf-core/haplocheck/environment.yml +++ b/modules/nf-core/saltshaker/classify/environment.yml @@ -2,4 +2,6 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::haplocheck=1.3.3 + - pip==26.0.1 + - pip: + - saltshaker==1.1.1 diff --git a/modules/nf-core/saltshaker/classify/main.nf b/modules/nf-core/saltshaker/classify/main.nf new file mode 100644 index 000000000..4a685c5b6 --- /dev/null +++ b/modules/nf-core/saltshaker/classify/main.nf @@ -0,0 +1,49 @@ +process SALTSHAKER_CLASSIFY { + tag "$meta.id" + label 'process_single' + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/5a/5a902cc9f161d602fde9c268a509be2f593cfac7ed4cdc2219f630e02e43b2ec/data': + 'community.wave.seqera.io/library/pip_saltshaker:be40ca61bbf77cf2' }" + + input: + tuple val(meta), path(call) + val mito_name + + output: + tuple val(meta), path("*_classify_metadata.tsv"), emit: classify + tuple val(meta), path("*_classify.txt") , emit: txt + tuple val(meta), path("*saltshaker.vcf") , emit: vcf, optional: true + tuple val("${task.process}"), val('saltshaker'), val("1.1.1"), topic: versions, emit: versions_saltshaker + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + saltshaker classify \\ + --prefix $prefix \\ + --input-dir . \\ + --chr-format $mito_name \\ + $args + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def touch_vcf = args.contains('--vcf') ? "touch ${prefix}.saltshaker.vcf" : '' + + """ + echo $args + + $touch_vcf + touch ${prefix}.saltshaker_classify.txt + touch ${prefix}.saltshaker_classify_metadata.tsv + """ +} diff --git a/modules/nf-core/saltshaker/classify/meta.yml b/modules/nf-core/saltshaker/classify/meta.yml new file mode 100644 index 000000000..c02c10c59 --- /dev/null +++ b/modules/nf-core/saltshaker/classify/meta.yml @@ -0,0 +1,94 @@ +name: "saltshaker_classify" +description: mtDNA deletion and duplication classification downstream of mitosalt +keywords: + - saltshaker + - mitosalt + - mtDNA + - structural-variant calling +tools: + - "saltshaker": + description: "A Python package for classifying and visualizing mitochondrial structural variants from MitoSAlt pipeline output." + homepage: "https://pypi.org/project/saltshaker" + documentation: "https://pypi.org/project/saltshaker" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - call: + type: file + description: call metadata file from saltshaker_call + pattern: "*_call_metadata.tsv" + ontologies: + - edam: http://edamontology.org/operation_3227 #variant calling + - edam: http://edamontology.org/format_3475 #tsv + - mito_name: + type: string + description: Name of the mitochondrial chromosome +output: + classify: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*_classify_metadata.tsv": + type: file + description: tsv with classified call metadata to be used in saltshaker_plot + pattern: "*_classify_metadata.tsv" + ontologies: + - edam: http://edamontology.org/operation_3225 #classification + - edam: http://edamontology.org/format_3475 #tsv + txt: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*_classify.txt": + type: file + description: txt file with case classification + pattern: "*_classify.txt" + ontologies: + - edam: http://edamontology.org/operation_3225 #classification + - edam: http://edamontology.org/format_2330 #txt + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*saltshaker.vcf": + type: file + description: vcf file with classified calls + pattern: "*saltshaker.vcf" + ontologies: + - edam: http://edamontology.org/operation_3225 #classification + - edam: http://edamontology.org/format_3016 #vcf + versions_saltshaker: + - - ${task.process}: + type: string + description: The name of the process + - saltshaker: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: Hardcoded version of saltshaker used in the module +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - saltshaker: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: Hardcoded version of saltshaker used in the module +authors: + - "@ieduba" +maintainers: + - "@ieduba" diff --git a/modules/nf-core/saltshaker/classify/tests/main.nf.test b/modules/nf-core/saltshaker/classify/tests/main.nf.test new file mode 100644 index 000000000..3830b1832 --- /dev/null +++ b/modules/nf-core/saltshaker/classify/tests/main.nf.test @@ -0,0 +1,148 @@ +nextflow_process { + + name "Test Process SALTSHAKER_CLASSIFY" + script "../main.nf" + process "SALTSHAKER_CLASSIFY" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "saltshaker" + tag "saltshaker/call" + tag "saltshaker/classify" + + setup { + run("SALTSHAKER_CALL") { + script "../../call/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.breakpoint', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.cluster', checkIfExists: true), + ] + + input[1] = [ + [ id:'hg38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/human_mt_rCRS.fasta', checkIfExists: true), + ] + + input[2] = 15 + input[3] = 0.01 + input[4] = 16569 + input[5] = 16081 + input[6] = 407 + input[7] = 5730 + input[8] = 5763 + """ + } + } + } + + test("classify - vcf") { + + when { + params { + module_args = '--blacklist --vcf --dominant-fraction 0.5 --radius 600 --high-het 10 --multiple-threshold 5 --noise 0.3' + } + process { + """ + input[0] = SALTSHAKER_CALL.out.call + input[1] = "MT" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out), + ).match() } + + ) + } + + } + + test("classify - vcf - stub") { + + options "-stub" + + when { + params { + module_args = '--blacklist --vcf --dominant-fraction 0.5 --radius 600 --high-het 10 --multiple-threshold 5 --noise 0.3' + } + process { + """ + input[0] = SALTSHAKER_CALL.out.call + input[1] = "MT" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out), + ).match() } + ) + } + + } + + test("classify - defaults") { + + when { + params { + module_args = '' + } + process { + """ + input[0] = SALTSHAKER_CALL.out.call + input[1] = "MT" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out), + ).match() } + + ) + } + + } + + test("classify - defaults - stub") { + + options "-stub" + + when { + params { + module_args = '' + } + process { + """ + input[0] = SALTSHAKER_CALL.out.call + input[1] = "MT" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out), + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/saltshaker/classify/tests/main.nf.test.snap b/modules/nf-core/saltshaker/classify/tests/main.nf.test.snap new file mode 100644 index 000000000..c7e9d7868 --- /dev/null +++ b/modules/nf-core/saltshaker/classify/tests/main.nf.test.snap @@ -0,0 +1,162 @@ +{ + "classify - defaults - stub": { + "content": [ + { + "classify": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify_metadata.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "txt": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CLASSIFY", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-01T13:52:59.878729", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "classify - defaults": { + "content": [ + { + "classify": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify_metadata.tsv:md5,2ed89e393a16ab2b7602ed06e807e187" + ] + ], + "txt": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify.txt:md5,21b5114cd8e2d1cd720de1bfa18abd3e" + ] + ], + "vcf": [ + + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CLASSIFY", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-01T15:59:15.738107", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "classify - vcf - stub": { + "content": [ + { + "classify": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify_metadata.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "txt": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.saltshaker.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CLASSIFY", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-01T13:52:46.708731", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "classify - vcf": { + "content": [ + { + "classify": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify_metadata.tsv:md5,2ed89e393a16ab2b7602ed06e807e187" + ] + ], + "txt": [ + [ + { + "id": "test" + }, + "test.saltshaker_classify.txt:md5,21b5114cd8e2d1cd720de1bfa18abd3e" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + + "test.saltshaker.vcf:md5,e8e3c00ef62888bb217983a4bf5559a5" + ] + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_CLASSIFY", + "saltshaker", + "1.1.1" + ] + ] + } + ], + + "timestamp": "2026-06-05T09:21:05.922028", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/saltshaker/classify/tests/nextflow.config b/modules/nf-core/saltshaker/classify/tests/nextflow.config new file mode 100644 index 000000000..97d25b454 --- /dev/null +++ b/modules/nf-core/saltshaker/classify/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'SALTSHAKER_CLASSIFY' { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/haplogrep3/classify/environment.yml b/modules/nf-core/saltshaker/plot/environment.yml similarity index 50% rename from modules/nf-core/haplogrep3/classify/environment.yml rename to modules/nf-core/saltshaker/plot/environment.yml index ca0c7e691..ba1172042 100644 --- a/modules/nf-core/haplogrep3/classify/environment.yml +++ b/modules/nf-core/saltshaker/plot/environment.yml @@ -2,4 +2,6 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::haplogrep3=3.2.2 + - pip==26.0.1 + - pip: + - saltshaker==1.1.1 diff --git a/modules/nf-core/saltshaker/plot/main.nf b/modules/nf-core/saltshaker/plot/main.nf new file mode 100644 index 000000000..75679dfde --- /dev/null +++ b/modules/nf-core/saltshaker/plot/main.nf @@ -0,0 +1,42 @@ +process SALTSHAKER_PLOT { + tag "$meta.id" + label 'process_single' + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/5a/5a902cc9f161d602fde9c268a509be2f593cfac7ed4cdc2219f630e02e43b2ec/data': + 'community.wave.seqera.io/library/pip_saltshaker:be40ca61bbf77cf2' }" + + input: + tuple val(meta), path(classify) + + output: + tuple val(meta), path("*saltshaker.png"), emit: plot + tuple val("${task.process}"), val('saltshaker'), val("1.1.1"), topic: versions, emit: versions_saltshaker + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + saltshaker plot \\ + --prefix $prefix \\ + --input-dir . \\ + $args + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + echo $args + + touch ${prefix}.saltshaker.png + """ +} diff --git a/modules/nf-core/saltshaker/plot/meta.yml b/modules/nf-core/saltshaker/plot/meta.yml new file mode 100644 index 000000000..200700538 --- /dev/null +++ b/modules/nf-core/saltshaker/plot/meta.yml @@ -0,0 +1,66 @@ +name: "saltshaker_plot" +description: mtDNA deletion and duplication plotting downstream of mitosalt +keywords: + - saltshaker + - mitosalt + - mtDNA + - structural-variant calling +tools: + - "saltshaker": + description: "A Python package for classifying and visualizing mitochondrial structural + variants from MitoSAlt pipeline output." + homepage: "https://pypi.org/project/saltshaker" + documentation: "https://pypi.org/project/saltshaker" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - classify: + type: file + description: classify metadata file from saltshaker_classify + pattern: "*_classify_metadata.tsv" + ontologies: + - edam: http://edamontology.org/operation_3225 #classification + - edam: http://edamontology.org/format_3475 #tsv +output: + plot: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*saltshaker.png": + type: file + description: png file with saltshaker plot + pattern: "*saltshaker.png" + ontologies: + - edam: http://edamontology.org/operation_0337 #visualization + - edam: http://edamontology.org/format_3603 #png + versions_saltshaker: + - - "${task.process}": + type: string + description: The name of the process + - "saltshaker": + type: string + description: The name of the tool + - "1.1.1": + type: string + description: Hardcoded version of saltshaker used in the module +topics: + versions: + - - "${task.process}": + type: string + description: The name of the process + - "saltshaker": + type: string + description: The name of the tool + - "1.1.1": + type: string + description: Hardcoded version of saltshaker used in the module +authors: + - "@ieduba" +maintainers: + - "@ieduba" diff --git a/modules/nf-core/saltshaker/plot/tests/main.nf.test b/modules/nf-core/saltshaker/plot/tests/main.nf.test new file mode 100644 index 000000000..f40353dcb --- /dev/null +++ b/modules/nf-core/saltshaker/plot/tests/main.nf.test @@ -0,0 +1,106 @@ +nextflow_process { + + name "Test Process SALTSHAKER_PLOT" + script "../main.nf" + process "SALTSHAKER_PLOT" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "saltshaker" + tag "saltshaker/call" + tag "saltshaker/classify" + tag "saltshaker/plot" + + setup { + run("SALTSHAKER_CALL") { + script "../../call/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.breakpoint', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/mitosalt/test_mitosalt.cluster', checkIfExists: true), + ] + + input[1] = [ + [ id:'hg38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/human_mt_rCRS.fasta', checkIfExists: true), + ] + + input[2] = 15 + input[3] = 0.01 + input[4] = 16569 + input[5] = 16081 + input[6] = 407 + input[7] = 5730 + input[8] = 5763 + """ + } + } + + run("SALTSHAKER_CLASSIFY") { + script "../../classify/main.nf" + process { + """ + input[0] = SALTSHAKER_CALL.out.call + input[1] = "MT" + """ + } + } + } + + + test("plot - png") { + + when { + params { + module_args = '--blacklist' + } + process { + """ + input[0] = SALTSHAKER_CLASSIFY.out.classify + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.findAll { key, val -> key.startsWith('versions') }, + process.out.plot.collect { meta, plot -> file(plot).name } + ).match() + } + ) + } + + } + + test("plot - png - stub") { + + options "-stub" + + when { + params { + module_args = '--blacklist' + } + process { + """ + input[0] = SALTSHAKER_CLASSIFY.out.classify + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out), + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/saltshaker/plot/tests/main.nf.test.snap b/modules/nf-core/saltshaker/plot/tests/main.nf.test.snap new file mode 100644 index 000000000..ebde03458 --- /dev/null +++ b/modules/nf-core/saltshaker/plot/tests/main.nf.test.snap @@ -0,0 +1,49 @@ +{ + "plot - png - stub": { + "content": [ + { + "plot": [ + [ + { + "id": "test" + }, + "test.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_saltshaker": [ + [ + "SALTSHAKER_PLOT", + "saltshaker", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-06-03T10:34:26.252966", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "plot - png": { + "content": [ + { + "versions_saltshaker": [ + [ + "SALTSHAKER_PLOT", + "saltshaker", + "1.1.1" + ] + ] + }, + [ + "test.saltshaker.png" + ] + ], + "timestamp": "2026-06-05T09:43:08.53978", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/saltshaker/plot/tests/nextflow.config b/modules/nf-core/saltshaker/plot/tests/nextflow.config new file mode 100644 index 000000000..51393788b --- /dev/null +++ b/modules/nf-core/saltshaker/plot/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'SALTSHAKER_PLOT' { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/sambamba/depth/environment.yml b/modules/nf-core/sambamba/depth/environment.yml new file mode 100644 index 000000000..a26092351 --- /dev/null +++ b/modules/nf-core/sambamba/depth/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::sambamba=1.0.1 diff --git a/modules/nf-core/sambamba/depth/main.nf b/modules/nf-core/sambamba/depth/main.nf new file mode 100644 index 000000000..42a1a80a3 --- /dev/null +++ b/modules/nf-core/sambamba/depth/main.nf @@ -0,0 +1,56 @@ +process SAMBAMBA_DEPTH { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/sambamba:1.0.1--he614052_3': + 'biocontainers/sambamba:1.0.1--he614052_3' }" + + input: + tuple val(meta), path(bam), path(bai) + tuple val(meta2), path(bed) + val(mode) + + output: + tuple val(meta), path("*.bed"), emit: bed + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + if (!['region','window','base'].contains(mode)) { + error "Mode needs to be one of: region, window, base" + } + def bed_arg = bed ? "--regions ${bed}" : '' + + """ + sambamba \\ + depth \\ + $mode \\ + $bed_arg \\ + $args \\ + -t $task.cpus \\ + -o ${prefix}.bed \\ + $bam + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sambamba: \$(echo \$(sambamba --version 2>&1) | awk '{print \$2}' ) + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.bed + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sambamba: \$(echo \$(sambamba --version 2>&1) | awk '{print \$2}' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/sambamba/depth/meta.yml b/modules/nf-core/sambamba/depth/meta.yml new file mode 100644 index 000000000..c16ce3a72 --- /dev/null +++ b/modules/nf-core/sambamba/depth/meta.yml @@ -0,0 +1,70 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "sambamba_depth" +description: Outputs a coverage file from bam files +keywords: + - depth + - coverage + - sambamba +tools: + - "sambamba": + description: "Tools for working with SAM/BAM data" + homepage: "https://lomereiter.github.io/sambamba/docs/sambamba-view.html" + documentation: "https://lomereiter.github.io/sambamba/docs/sambamba-view.html" + tool_dev_url: "https://github.com/biod/sambamba" + doi: 10.1093/bioinformatics/btv098 + licence: ["GPL v2"] + identifier: biotools:sambamba +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - bam: + type: file + description: BAM file + pattern: "*.{bam}" + ontologies: + - edam: "http://edamontology.org/format_2572" + - bai: + type: file + description: BAI file + pattern: "*.{bai}" + ontologies: + - edam: "http://edamontology.org/format_2572" + - - meta2: + type: map + description: | + Groovy Map containing regions information + - bed: + type: file + description: bed file + pattern: "*.{bed}" + ontologies: + - edam: "http://edamontology.org/format_3003" # BED + - mode: + type: string + description: Analysis mode can be region, window, base + pattern: "region|window|base" +output: + bed: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.bed": + type: file + description: bed file + pattern: "*.bed" + ontologies: + - edam: "http://edamontology.org/format_3586" # bed12 + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@peterpru" +maintainers: + - "@peterpru" diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test b/modules/nf-core/sambamba/depth/tests/main.nf.test new file mode 100644 index 000000000..3f6fce50b --- /dev/null +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test @@ -0,0 +1,98 @@ + +nextflow_process { + + name "Test Process SAMBAMBA_DEPTH" + script "../main.nf" + process "SAMBAMBA_DEPTH" + + tag "modules" + tag "modules_nfcore" + tag "sambamba" + tag "sambamba/depth" + + test("test-sambamba-depth") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[], []] + input[2] = 'base' + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out, + process.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("test-sambamba-depth-with-region-bed") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id:'test2' ], // meta2 map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + input[2] = 'region' + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test-sambamba-depth-stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[], []] + input[2] = 'base' + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out, + process.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test.snap b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap new file mode 100644 index 000000000..d1eb47aaa --- /dev/null +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap @@ -0,0 +1,121 @@ +{ + "test-sambamba-depth-with-region-bed": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,e312edd2c0a9f63b833b5a8913952ba6" + ] + ], + "1": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,e312edd2c0a9f63b833b5a8913952ba6" + ] + ], + "versions": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-05T12:03:11.190921915" + }, + "test-sambamba-depth": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,430bc921fe8a56d4a47a692a708dfb96" + ] + ], + "1": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,430bc921fe8a56d4a47a692a708dfb96" + ] + ], + "versions": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ] + }, + [ + { + "SAMBAMBA_DEPTH": { + "sambamba": "1.0.1" + } + } + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-05T12:03:07.689091449" + }, + "test-sambamba-depth-stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ] + }, + [ + { + "SAMBAMBA_DEPTH": { + "sambamba": "1.0.1" + } + } + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-05T12:03:14.737096819" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/collate/environment.yml b/modules/nf-core/samtools/collate/environment.yml new file mode 100644 index 000000000..89e12a645 --- /dev/null +++ b/modules/nf-core/samtools/collate/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/collate/main.nf b/modules/nf-core/samtools/collate/main.nf new file mode 100644 index 000000000..a81622ba2 --- /dev/null +++ b/modules/nf-core/samtools/collate/main.nf @@ -0,0 +1,52 @@ +process SAMTOOLS_COLLATE { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0': + 'biocontainers/samtools:1.22.1--h96c455f_0' }" + + input: + tuple val(meta), path(input) + tuple val(meta2), path(fasta), path(fai) + + output: + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.sam"), emit: sam, optional: true + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def reference = fasta ? "--reference ${fasta}" : "" + def extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" + if ("$input" == "${prefix}.${extension}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + samtools \\ + collate \\ + $args \\ + ${reference} \\ + -@ $task.cpus \\ + -o ${prefix}.${extension} \\ + $input + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" + """ + touch ${prefix}.${extension} + """ +} diff --git a/modules/nf-core/samtools/collate/meta.yml b/modules/nf-core/samtools/collate/meta.yml new file mode 100644 index 000000000..5e4c71548 --- /dev/null +++ b/modules/nf-core/samtools/collate/meta.yml @@ -0,0 +1,103 @@ +name: "samtools_collate" +description: shuffles and groups reads together by their names +keywords: + - collate + - bam + - sam + - cram +tools: + - "samtools": + description: "Tools for dealing with SAM, BAM and CRAM files" + homepage: "http://www.htslib.org" + documentation: "https://www.htslib.org/doc/samtools-collate.html" + tool_dev_url: "https://github.com/samtools/samtools" + doi: "10.1093/bioinformatics/btp352" + licence: ["MIT"] + identifier: biotools:samtools +input: + # Only when we have meta + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Reference genome file + pattern: "*.{fa,fasta}" + ontologies: [] + - fai: + type: file + description: Reference genome index file + pattern: "*.fai" + ontologies: [] +output: + #Only when we have meta + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bam": + type: file + description: Sorted BAM + pattern: "*.{bam}" + ontologies: [] + cram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cram": + type: file + description: Sorted CRAM + pattern: "*.{cram}" + ontologies: [] + sam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.sam": + type: file + description: Sorted SAM + pattern: "*.{sam}" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@priyanka-surana" +maintainers: + - "@priyanka-surana" diff --git a/modules/nf-core/samtools/collate/tests/main.nf.test b/modules/nf-core/samtools/collate/tests/main.nf.test new file mode 100644 index 000000000..b2dedc717 --- /dev/null +++ b/modules/nf-core/samtools/collate/tests/main.nf.test @@ -0,0 +1,79 @@ +nextflow_process { + + name "Test Process SAMTOOLS_COLLATE" + script "../main.nf" + process "SAMTOOLS_COLLATE" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/collate" + + test("sarscov2 - bam") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ] + input[1] = [ [id:'fasta'], [], [] ] + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("homo_sapiens - cram + fasta") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true) + ] + input[1] = [ + [ id:'fasta'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + [] + ] + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("sarscov2 - bam -- stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ] + input[1] = [ [id:'fasta'], [], [] ] + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} diff --git a/modules/nf-core/samtools/collate/tests/main.nf.test.snap b/modules/nf-core/samtools/collate/tests/main.nf.test.snap new file mode 100644 index 000000000..49c054f96 --- /dev/null +++ b/modules/nf-core/samtools/collate/tests/main.nf.test.snap @@ -0,0 +1,161 @@ +{ + "sarscov2 - bam -- stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cram": [ + + ], + "sam": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T14:56:50.33210565" + }, + "sarscov2 - bam": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,06aa42b8b8dff9eb8c693dc1a9767e23" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,06aa42b8b8dff9eb8c693dc1a9767e23" + ] + ], + "cram": [ + + ], + "sam": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T14:56:36.179835312" + }, + "homo_sapiens - cram + fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,aefab9d7e786892bef3fca019494abda" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,aefab9d7e786892bef3fca019494abda" + ] + ], + "cram": [ + + ], + "sam": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_COLLATE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T14:56:44.148216078" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/faidx/environment.yml b/modules/nf-core/samtools/faidx/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/faidx/environment.yml +++ b/modules/nf-core/samtools/faidx/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 28c0a81cf..97bfb578f 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -4,47 +4,46 @@ process SAMTOOLS_FAIDX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(fasta) - tuple val(meta2), path(fai) + tuple val(meta), path(fasta), path(fai) + val get_sizes output: - tuple val(meta), path ("*.{fa,fasta}") , emit: fa , optional: true + tuple val(meta), path ("*.{fa,fasta}") , emit: fa, optional: true + tuple val(meta), path ("*.sizes") , emit: sizes, optional: true tuple val(meta), path ("*.fai") , emit: fai, optional: true tuple val(meta), path ("*.gzi") , emit: gzi, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' + def get_sizes_command = get_sizes ? "cut -f 1,2 ${fasta}.fai > ${fasta}.sizes" : '' """ samtools \\ faidx \\ $fasta \\ $args - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + ${get_sizes_command} """ stub: def match = (task.ext.args =~ /-o(?:utput)?\s(.*)\s?/).findAll() def fastacmd = match[0] ? "touch ${match[0][1]}" : '' + def get_sizes_command = get_sizes ? "touch ${fasta}.sizes" : '' """ ${fastacmd} touch ${fasta}.fai + if [[ "${fasta.extension}" == "gz" ]]; then + touch ${fasta}.gzi + fi - cat <<-END_VERSIONS > versions.yml - - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + ${get_sizes_command} """ } diff --git a/modules/nf-core/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml index 6721b2cb8..80aae1dae 100644 --- a/modules/nf-core/samtools/faidx/meta.yml +++ b/modules/nf-core/samtools/faidx/meta.yml @@ -1,9 +1,11 @@ name: samtools_faidx -description: Index FASTA file +description: Index FASTA file, and optionally generate a file of chromosome + sizes keywords: - index - fasta - faidx + - chromosome tools: - samtools: description: | @@ -13,7 +15,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:samtools input: - - meta: @@ -25,18 +28,18 @@ input: type: file description: FASTA file pattern: "*.{fa,fasta}" - - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] + ontologies: [] - fai: type: file description: FASTA index file pattern: "*.{fai}" + ontologies: [] + - get_sizes: + type: boolean + description: use cut to get the sizes of the index (true) or not (false) output: - - fa: - - meta: + fa: + - - meta: type: map description: | Groovy Map containing sample information @@ -45,8 +48,20 @@ output: type: file description: FASTA file pattern: "*.{fa}" - - fai: - - meta: + ontologies: [] + sizes: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.sizes": + type: file + description: File containing chromosome lengths + pattern: "*.{sizes}" + ontologies: [] + fai: + - - meta: type: map description: | Groovy Map containing sample information @@ -55,8 +70,9 @@ output: type: file description: FASTA index file pattern: "*.{fai}" - - gzi: - - meta: + ontologies: [] + gzi: + - - meta: type: map description: | Groovy Map containing sample information @@ -65,16 +81,32 @@ output: type: file description: Optional gzip index file for compressed inputs pattern: "*.gzi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The command used to generate the version of the tool authors: - "@drpatelh" - "@ewels" - "@phue" maintainers: - - "@drpatelh" - - "@ewels" + - "@maxulysse" - "@phue" diff --git a/modules/nf-core/samtools/faidx/tests/main.nf.test b/modules/nf-core/samtools/faidx/tests/main.nf.test index 17244ef2e..9a86db862 100644 --- a/modules/nf-core/samtools/faidx/tests/main.nf.test +++ b/modules/nf-core/samtools/faidx/tests/main.nf.test @@ -8,24 +8,30 @@ nextflow_process { tag "modules_nfcore" tag "samtools" tag "samtools/faidx" + config "./nextflow.config" test("test_samtools_faidx") { when { + params { + module_args = '' + } process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] - - input[1] = [[],[]] + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [] + ] + input[1] = false """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match()} ) } } @@ -33,90 +39,215 @@ nextflow_process { test("test_samtools_faidx_bgzip") { when { + params { + module_args = '' + } process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true)] - - input[1] = [[],[]] + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true), + [] + ] + input[1] = false """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match()} ) } } test("test_samtools_faidx_fasta") { - config "./nextflow.config" - when { + params { + module_args = 'MT192765.1 -o extract.fa' + } process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] - - input[1] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = false """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match()} ) } } test("test_samtools_faidx_stub_fasta") { - config "./nextflow2.config" + options "-stub" + when { + params { + module_args = '-o extract.fa' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[1] = false + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match()} + ) + } + } + + test("test_samtools_faidx_stub_fai") { + options "-stub" when { + params { + module_args = '' + } process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [] + ] + input[1] = false + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match()} + ) + } + } - input[1] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] + test("test_samtools_faidx_get_sizes") { + + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [] + ] + input[1] = true """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match()} ) } } - test("test_samtools_faidx_stub_fai") { + test("test_samtools_faidx_get_sizes_bgzip") { when { + params { + module_args = '' + } process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true), + [] + ] + input[1] = true + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match()} + ) + } + } + + test("test_samtools_faidx_get_sizes - stub") { + + options "-stub" - input[1] = [[],[]] + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [] + ] + input[1] = true """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match()} ) } } -} \ No newline at end of file + + test("test_samtools_faidx_get_sizes_bgzip - stub") { + + options "-stub" + + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true), + [] + ] + input[1] = true + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match()} + ) + } + } + +} diff --git a/modules/nf-core/samtools/faidx/tests/main.nf.test.snap b/modules/nf-core/samtools/faidx/tests/main.nf.test.snap index 1bbb3ec2b..416974442 100644 --- a/modules/nf-core/samtools/faidx/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/faidx/tests/main.nf.test.snap @@ -2,85 +2,133 @@ "test_samtools_faidx": { "content": [ { - "0": [ + "fa": [ ], - "1": [ + "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" ] ], - "2": [ + "gzi": [ ], - "3": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-10T15:39:12.541649151" + }, + "test_samtools_faidx_get_sizes_bgzip - stub": { + "content": [ + { "fa": [ ], "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "genome.fasta.gz.fai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "gzi": [ - + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], - "versions": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:57:47.450887871" + "timestamp": "2026-02-10T15:41:44.040426987" }, - "test_samtools_faidx_bgzip": { + "test_samtools_faidx_get_sizes": { "content": [ { - "0": [ + "fa": [ ], - "1": [ + "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" ] ], - "2": [ + "gzi": [ + + ], + "sizes": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + "genome.fasta.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" ] ], - "3": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" - ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-10T15:47:03.653912015" + }, + "test_samtools_faidx_bgzip": { + "content": [ + { "fa": [ ], "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" ] @@ -88,49 +136,36 @@ "gzi": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" ] ], - "versions": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:58:04.804905659" + "timestamp": "2026-02-10T15:50:04.023566795" }, "test_samtools_faidx_fasta": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "extract.fa:md5,6a0774a0ad937ba0bfd2ac7457d90f36" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" - ], "fa": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "extract.fa:md5,6a0774a0ad937ba0bfd2ac7457d90f36" ] @@ -141,45 +176,73 @@ "gzi": [ ], - "versions": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:58:23.831268154" + "timestamp": "2026-02-10T15:39:23.529404162" }, - "test_samtools_faidx_stub_fasta": { + "test_samtools_faidx_get_sizes - stub": { "content": [ { - "0": [ + "fa": [ + + ], + "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "extract.fa:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "genome.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "1": [ - - ], - "2": [ + "gzi": [ ], - "3": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-10T15:41:39.039834304" + }, + "test_samtools_faidx_stub_fasta": { + "content": [ + { "fa": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "extract.fa:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "extract.fa:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "fai": [ @@ -188,62 +251,102 @@ "gzi": [ ], - "versions": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:58:35.600243706" + "timestamp": "2026-02-10T15:39:28.961701609" }, "test_samtools_faidx_stub_fai": { "content": [ { - "0": [ + "fa": [ ], - "1": [ + "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "genome.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "2": [ + "gzi": [ ], - "3": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-10T15:39:34.471028474" + }, + "test_samtools_faidx_get_sizes_bgzip": { + "content": [ + { "fa": [ ], "fai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" ] ], "gzi": [ - + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + ] ], - "versions": [ - "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_FAIDX", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:58:54.705460167" + "timestamp": "2026-02-10T15:39:45.439016495" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/faidx/tests/nextflow.config b/modules/nf-core/samtools/faidx/tests/nextflow.config index f76a3ba09..202c036ed 100644 --- a/modules/nf-core/samtools/faidx/tests/nextflow.config +++ b/modules/nf-core/samtools/faidx/tests/nextflow.config @@ -1,7 +1,7 @@ process { withName: SAMTOOLS_FAIDX { - ext.args = 'MT192765.1 -o extract.fa' + ext.args = params.module_args } } diff --git a/modules/nf-core/samtools/faidx/tests/nextflow2.config b/modules/nf-core/samtools/faidx/tests/nextflow2.config deleted file mode 100644 index 33ebbd5df..000000000 --- a/modules/nf-core/samtools/faidx/tests/nextflow2.config +++ /dev/null @@ -1,6 +0,0 @@ -process { - - withName: SAMTOOLS_FAIDX { - ext.args = '-o extract.fa' - } -} diff --git a/modules/nf-core/samtools/faidx/tests/tags.yml b/modules/nf-core/samtools/faidx/tests/tags.yml deleted file mode 100644 index e4a839481..000000000 --- a/modules/nf-core/samtools/faidx/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/faidx: - - modules/nf-core/samtools/faidx/** diff --git a/modules/nf-core/samtools/index/environment.yml b/modules/nf-core/samtools/index/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/index/environment.yml +++ b/modules/nf-core/samtools/index/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index 311756102..e2a0e56da 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -4,8 +4,8 @@ process SAMTOOLS_INDEX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input) @@ -14,7 +14,7 @@ process SAMTOOLS_INDEX { tuple val(meta), path("*.bai") , optional:true, emit: bai tuple val(meta), path("*.csi") , optional:true, emit: csi tuple val(meta), path("*.crai"), optional:true, emit: crai - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -24,14 +24,9 @@ process SAMTOOLS_INDEX { """ samtools \\ index \\ - -@ ${task.cpus-1} \\ + -@ ${task.cpus} \\ $args \\ $input - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -40,10 +35,5 @@ process SAMTOOLS_INDEX { "crai" : args.contains("-c") ? "csi" : "bai" """ touch ${input}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index db8df0d50..c6d4ce259 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -14,7 +14,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:samtools input: - - meta: @@ -25,9 +26,10 @@ input: - input: type: file description: input file + ontologies: [] output: - - bai: - - meta: + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -36,8 +38,9 @@ output: type: file description: BAM/CRAM/SAM index file pattern: "*.{bai,crai,sai}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -46,8 +49,9 @@ output: type: file description: CSI index file pattern: "*.{csi}" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -56,11 +60,28 @@ output: type: file description: BAM/CRAM/SAM index file pattern: "*.{bai,crai,sai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/index/tests/main.nf.test b/modules/nf-core/samtools/index/tests/main.nf.test index ca34fb5cd..c96cec860 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test +++ b/modules/nf-core/samtools/index/tests/main.nf.test @@ -23,7 +23,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.bai, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } @@ -43,7 +46,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.crai, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } @@ -67,7 +73,7 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.csi[0][1]).name, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -89,7 +95,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.bai, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } @@ -110,7 +119,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.crai, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } @@ -133,7 +145,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.csi, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } diff --git a/modules/nf-core/samtools/index/tests/main.nf.test.snap b/modules/nf-core/samtools/index/tests/main.nf.test.snap index 72d65e81a..afc8a1ff6 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/index/tests/main.nf.test.snap @@ -1,250 +1,156 @@ { "csi - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], { - "0": [ - - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ], - "bai": [ - - ], - "crai": [ - - ], - "csi": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:21:25.261127166" + "timestamp": "2026-01-28T17:52:10.030187" }, "crai - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], { - "0": [ - - ], - "1": [ - - ], - "2": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" ] - ], - "3": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ], - "bai": [ - - ], - "crai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:21:12.653194876" + "timestamp": "2026-01-28T17:51:59.125484" }, "bai - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], { - "0": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ], - "bai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "crai": [ - - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:21:01.854932651" + "timestamp": "2026-01-28T17:51:47.277042" }, "csi": { "content": [ "test.paired_end.sorted.bam.csi", - [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ] + { + "versions_samtools": [ + [ + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:20:51.485364222" + "timestamp": "2026-01-28T17:51:35.758735" }, "crai": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + ] + ], { - "0": [ - - ], - "1": [ - - ], - "2": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" ] - ], - "3": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ], - "bai": [ - - ], - "crai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" - ] - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:20:40.518873972" + "timestamp": "2026-01-28T17:51:26.561965" }, "bai": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + ] + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" - ], - "bai": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + "SAMTOOLS_INDEX", + "samtools", + "1.22.1" ] - ], - "crai": [ - - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:20:21.184050361" + "timestamp": "2026-01-28T17:51:15.299035" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/index/tests/tags.yml b/modules/nf-core/samtools/index/tests/tags.yml deleted file mode 100644 index e0f58a7a3..000000000 --- a/modules/nf-core/samtools/index/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/index: - - modules/nf-core/samtools/index/** diff --git a/modules/nf-core/samtools/merge/environment.yml b/modules/nf-core/samtools/merge/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/merge/environment.yml +++ b/modules/nf-core/samtools/merge/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/merge/main.nf b/modules/nf-core/samtools/merge/main.nf index 34da4c7c8..23aa0d522 100644 --- a/modules/nf-core/samtools/merge/main.nf +++ b/modules/nf-core/samtools/merge/main.nf @@ -4,21 +4,19 @@ process SAMTOOLS_MERGE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input_files, stageAs: "?/*") - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) + tuple val(meta), path(input_files, stageAs: "?/*"), path(index_files, stageAs: "?/*") + tuple val(meta2), path(fasta), path(fai), path(gzi) output: tuple val(meta), path("${prefix}.bam") , optional:true, emit: bam tuple val(meta), path("${prefix}.cram"), optional:true, emit: cram tuple val(meta), path("*.csi") , optional:true, emit: csi tuple val(meta), path("*.crai") , optional:true, emit: crai - path "versions.yml" , emit: versions - + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -29,6 +27,7 @@ process SAMTOOLS_MERGE { def file_type = input_files instanceof List ? input_files[0].getExtension() : input_files.getExtension() def reference = fasta ? "--reference ${fasta}" : "" """ + # Note: --threads value represents *additional* CPUs to allocate (total CPUs = 1 + --threads). samtools \\ merge \\ --threads ${task.cpus-1} \\ @@ -36,11 +35,6 @@ process SAMTOOLS_MERGE { ${reference} \\ ${prefix}.${file_type} \\ $input_files - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -52,10 +46,5 @@ process SAMTOOLS_MERGE { """ touch ${prefix}.${file_type} ${index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/merge/meta.yml b/modules/nf-core/samtools/merge/meta.yml index 235aa2194..8a8afca87 100644 --- a/modules/nf-core/samtools/merge/meta.yml +++ b/modules/nf-core/samtools/merge/meta.yml @@ -26,6 +26,12 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram,sam}" + ontologies: [] + - index_files: + type: file + description: BAI/CRAI/CSI index file + pattern: "*.{bai,crai,csi}" + ontologies: [] - - meta2: type: map description: | @@ -35,18 +41,21 @@ input: type: file description: Reference file the CRAM was created with (optional) pattern: "*.{fasta,fa}" - - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] + ontologies: [] - fai: type: file description: Index of the reference file the CRAM was created with (optional) pattern: "*.fai" + ontologies: [] + - gzi: + type: file + description: Index of the compressed reference file the CRAM was created with + (optional) + pattern: "*.gzi" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -55,8 +64,9 @@ output: type: file description: BAM file pattern: "*.{bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -65,8 +75,9 @@ output: type: file description: CRAM file pattern: "*.{cram}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -75,8 +86,9 @@ output: type: file description: BAM index file (optional) pattern: "*.csi" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -85,20 +97,36 @@ output: type: file description: CRAM index file (optional) pattern: "*.crai" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool authors: - - "@drpatelh" - - "@yuukiiwa " + - "@yuukiiwa" - "@maxulysse" - "@FriederikeHanssen" - "@ramprasadn" maintainers: - - "@drpatelh" - - "@yuukiiwa " + - "@yuukiiwa" - "@maxulysse" - "@FriederikeHanssen" - "@ramprasadn" diff --git a/modules/nf-core/samtools/merge/tests/index.config b/modules/nf-core/samtools/merge/tests/index.config deleted file mode 100644 index 8c5668cf3..000000000 --- a/modules/nf-core/samtools/merge/tests/index.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--write-index" -} \ No newline at end of file diff --git a/modules/nf-core/samtools/merge/tests/main.nf.test b/modules/nf-core/samtools/merge/tests/main.nf.test index 40b36e82b..3c2c524fc 100644 --- a/modules/nf-core/samtools/merge/tests/main.nf.test +++ b/modules/nf-core/samtools/merge/tests/main.nf.test @@ -8,70 +8,121 @@ nextflow_process { tag "modules_nfcore" tag "samtools" tag "samtools/merge" + config "./nextflow.config" test("bams") { - config "./index.config" - when { + params { + module_args = '--write-index' + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test'], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true) ] - ]) - input[1] = [[],[]] - input[2] = [[],[]] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true) ], + [] + ] + input[1] = [[],[],[],[]] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bams_bam") }, - { assert snapshot(process.out.cram).match("bams_cram") }, - { assert snapshot(file(process.out.csi[0][1]).name).match("bams_csi") }, - { assert snapshot(process.out.crai).match("bams_crai") }, - { assert snapshot(process.out.versions).match("bams_versions") } + { assert snapshot( + bam(process.out.bam[0][1]).getReadsMD5(), + file(process.out.csi[0][1]).name, + process.out.cram, + process.out.crai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } } - test("crams") { + test("crams_fastq") { + + when { + params { + module_args = '--write-index --output-fmt cram,version=3.0' + } + process { + """ + input[0] = [ + [ id:'test' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test2.paired_end.sorted.cram', checkIfExists: true) ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test2.paired_end.sorted.cram.crai', checkIfExists: true) ] + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true), + [] + ] + """ + } + } + + then { + def fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.fasta' + assert process.success + assertAll( + { assert snapshot( + cram(process.out.cram[0][1], fasta).getReadsMD5(), + process.out.csi, + process.out.bam, + file(process.out.crai[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } + ) + } + } - config "./index.config" + test("crams_fastq_gz") { when { + params { + module_args = '--write-index' + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test2.paired_end.recalibrated.sorted.cram', checkIfExists: true) ] - ]) - input[1] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ]) + input[0] = [ + [ id:'test' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test2.paired_end.sorted.cram', checkIfExists: true) ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test2.paired_end.sorted.cram.crai', checkIfExists: true) ] + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) + ] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(file(process.out.cram[0][1]).name).match("crams_cram") }, - { assert snapshot(process.out.bam).match("crams_bam") }, - { assert snapshot(file(process.out.crai[0][1]).name).match("crams_crai") }, - { assert snapshot(process.out.csi).match("crams_csi") }, - { assert snapshot(process.out.versions).match("crams_versions") } + { assert snapshot( + //nft-bam doesn't like the fasta.gz + file(process.out.cram[0][1]).name, + process.out.csi, + process.out.bam, + file(process.out.crai[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } } @@ -79,59 +130,94 @@ nextflow_process { test("bam") { when { + params { + module_args = '' + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam', checkIfExists: true) ] - ]) - input[1] = [[],[]] - input[2] = [[],[]] + input[0] = [ + [ id:'test' ], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam', checkIfExists: true) ], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam.bai', checkIfExists: true) ] + ] + input[1] = [[],[],[],[]] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bam_bam") }, - { assert snapshot(process.out.cram).match("bam_cram") }, - { assert snapshot(process.out.crai).match("bam_crai") }, - { assert snapshot(process.out.csi).match("bam_csi") }, - { assert snapshot(process.out.versions).match("bam_versions") } + { assert snapshot( + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.csi, + process.out.cram, + process.out.crai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } } - test("bams_stub") { + test("bams - stub") { - config "./index.config" options "-stub" when { + params { + module_args = '' + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true) ] - ]) - input[1] = [[],[]] - input[2] = [[],[]] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true) ], + [] + ] + input[1] = [[],[],[],[]] """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bams_stub_bam") }, - { assert snapshot(process.out.cram).match("bams_stub_cram") }, - { assert snapshot(file(process.out.csi[0][1]).name).match("bams_stub_csi") }, - { assert snapshot(process.out.crai).match("bams_stub_crai") }, - { assert snapshot(process.out.versions).match("bams_stub_versions") } + { assert snapshot(process.out).match()} ) } } + + test("bams_no_index - stub") { + + options "-stub" + + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [ id:'test'], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.methylated.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true) ], + [] + ] + input[1] = [[],[],[],[]] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match()} + ) + } + } + } diff --git a/modules/nf-core/samtools/merge/tests/main.nf.test.snap b/modules/nf-core/samtools/merge/tests/main.nf.test.snap index 0a41e01af..e8d4d18a0 100644 --- a/modules/nf-core/samtools/merge/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/merge/tests/main.nf.test.snap @@ -1,228 +1,226 @@ { - "crams_cram": { - "content": [ - "test.cram" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:00.647389" - }, - "bams_stub_cram": { - "content": [ + "bams_no_index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-22T09:07:54.643129787" + }, + "crams_fastq": { + "content": [ + "c4525b95f05075208347295e6a1fb232", [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:19.937013" - }, - "bams_crai": { - "content": [ + ], [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:49:24.928616" - }, - "bams_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:49:24.923289" - }, - "bams_cram": { - "content": [ + ], + "test.cram.crai", + { + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-21T15:47:17.739468093" + }, + "bams - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-22T09:07:47.303781531" + }, + "bams": { + "content": [ + "47c9f174d8c8afc1a13c75ee4b5e5d43", + "test.bam.csi", [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:49:24.925716" - }, - "crams_csi": { - "content": [ + ], [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:00.655959" - }, - "bam_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:10.319539" - }, - "bam_versions": { - "content": [ - [ - "versions.yml:md5,d51d18a97513e370e43f0c891c51dfc4" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:16:30.476887194" - }, - "bams_csi": { - "content": [ - "test.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:49:24.92719" - }, - "bams_stub_csi": { - "content": [ - "test.csi" + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-02-12T18:50:19.940498" + "timestamp": "2025-12-21T15:47:07.586929894" }, - "bam_crai": { + "crams_fastq_gz": { "content": [ + "test.cram", [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:10.328852" - }, - "bams_stub_versions": { - "content": [ - [ - "versions.yml:md5,d51d18a97513e370e43f0c891c51dfc4" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:16:52.203823961" - }, - "bam_cram": { - "content": [ + ], [ - ] + ], + "test.cram.crai", + { + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-02-12T18:50:10.324219" + "timestamp": "2025-12-21T15:47:26.095542073" }, - "bams_stub_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:19.933153" - }, - "bams_versions": { - "content": [ - [ - "versions.yml:md5,d51d18a97513e370e43f0c891c51dfc4" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T08:29:57.524363148" - }, - "crams_bam": { + "bam": { "content": [ + "8da8fc1099a955e3ceb198665350e766", [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:00.650652" - }, - "crams_versions": { - "content": [ - [ - "versions.yml:md5,d51d18a97513e370e43f0c891c51dfc4" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:16:06.977096207" - }, - "bam_csi": { - "content": [ + ], [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:10.33292" - }, - "crams_crai": { - "content": [ - "test.cram.crai" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:00.653512" - }, - "bams_stub_crai": { - "content": [ + ], [ - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T18:50:19.943839" + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_MERGE", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-21T15:47:33.563513564" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/merge/tests/nextflow.config b/modules/nf-core/samtools/merge/tests/nextflow.config new file mode 100644 index 000000000..2b2a46100 --- /dev/null +++ b/modules/nf-core/samtools/merge/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: "SAMTOOLS_MERGE" { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/samtools/merge/tests/tags.yml b/modules/nf-core/samtools/merge/tests/tags.yml deleted file mode 100644 index b869abcb8..000000000 --- a/modules/nf-core/samtools/merge/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/merge: - - "modules/nf-core/samtools/merge/**" diff --git a/modules/nf-core/samtools/sort/environment.yml b/modules/nf-core/samtools/sort/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/sort/environment.yml +++ b/modules/nf-core/samtools/sort/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index caf3c61a8..6b5aa31dd 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -4,30 +4,41 @@ process SAMTOOLS_SORT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta) , path(bam) tuple val(meta2), path(fasta) + val index_format output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - tuple val(meta), path("*.csi"), emit: csi, optional: true - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true + tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true + tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true + tuple val(meta), path("${prefix}.${extension}.crai"), emit: crai, optional: true + tuple val(meta), path("${prefix}.${extension}.csi"), emit: csi, optional: true + tuple val(meta), path("${prefix}.${extension}.bai"), emit: bai, optional: true + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" def reference = fasta ? "--reference ${fasta}" : "" + output_file = index_format ? "${prefix}.${extension}##idx##${prefix}.${extension}.${index_format} --write-index" : "${prefix}.${extension}" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (extension == "sam") { + error "Indexing not compatible with SAM output" + } + } if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ @@ -39,34 +50,29 @@ process SAMTOOLS_SORT { -T ${prefix} \\ --threads $task.cpus \\ ${reference} \\ - -o ${prefix}.${extension} \\ + -o ${output_file} \\ - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (extension == "sam") { + error "Indexing not compatible with SAM output" + } + } + index = index_format ? "touch ${prefix}.${extension}.${index_format}" : "" + """ touch ${prefix}.${extension} - if [ "${extension}" == "bam" ]; - then - touch ${prefix}.${extension}.csi - elif [ "${extension}" == "cram" ]; - then - touch ${prefix}.${extension}.crai - fi + ${index} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index a9dbec5a8..699683047 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -26,6 +26,7 @@ input: type: file description: BAM/CRAM/SAM file(s) pattern: "*.{bam,cram,sam}" + ontologies: [] - - meta2: type: map description: | @@ -36,52 +37,101 @@ input: description: Reference genome FASTA file pattern: "*.{fa,fasta,fna}" optional: true + ontologies: [] + - index_format: + type: string + description: Index format to use (optional) + pattern: "bai|csi|crai" output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.bam": + - "${prefix}.bam": type: file description: Sorted BAM file pattern: "*.{bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.cram": + - "${prefix}.cram": type: file description: Sorted CRAM file pattern: "*.{cram}" - - crai: - - meta: + ontologies: [] + sam: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.crai": + - "${prefix}.sam": + type: file + description: Sorted SAM file + pattern: "*.{sam}" + ontologies: [] + crai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.crai": type: file description: CRAM index file (optional) pattern: "*.crai" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.csi": + - "${prefix}.${extension}.csi": type: file description: BAM index file (optional) pattern: "*.csi" - - versions: - - versions.yml: + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.bai": type: file - description: File containing software versions - pattern: "versions.yml" + description: BAM index file (optional) + pattern: "*.bai" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool + authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test b/modules/nf-core/samtools/sort/tests/main.nf.test index b05e6691b..df47bb25c 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test +++ b/modules/nf-core/samtools/sort/tests/main.nf.test @@ -8,7 +8,7 @@ nextflow_process { tag "samtools" tag "samtools/sort" - test("bam") { + test("bam_no_index") { config "./nextflow.config" @@ -23,6 +23,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -32,8 +33,72 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.bai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("bam_bai_index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'bai' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.bai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("bam_csi_index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'csi' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.csi, + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -57,6 +122,77 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("multiple bam bai index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true) + ] + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'bai' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.bai.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("multiple bam csi index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true) + ] + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'csi' """ } } @@ -67,7 +203,7 @@ nextflow_process { { assert snapshot( process.out.bam, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -88,6 +224,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -98,7 +235,7 @@ nextflow_process { { assert snapshot( process.out.cram.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.crai.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -120,6 +257,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -127,7 +265,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } @@ -150,6 +288,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -157,7 +296,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } @@ -178,6 +317,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -185,7 +325,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test.snap b/modules/nf-core/samtools/sort/tests/main.nf.test.snap index 469891fe3..4e618fa3f 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/sort/tests/main.nf.test.snap @@ -19,147 +19,77 @@ "test.sorted.cram.crai" ] ], - [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:49:58.207549273" + "timestamp": "2025-10-29T12:47:01.171084" }, - "bam - stub": { + "bam_csi_index": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,72ca1dff5344a5e5e6b892fe5f6b134d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.csi:md5,01394e702c729cb478df914ffaf9f7f8" + ] + ], { - "0": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "crai": [ - - ], - "cram": [ - - ], - "csi": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:50:08.630951018" + "timestamp": "2025-10-29T12:46:00.961675" }, - "cram - stub": { + "bam - stub": { "content": [ { - "0": [ - - ], - "1": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ - - ], - "crai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "cram": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:50:19.061912443" + "timestamp": "2025-10-29T12:47:12.154354" }, - "multiple bam": { + "multiple bam bai index": { "content": [ [ [ @@ -167,7 +97,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "test.sorted.bam:md5,3ffa2affc29f0aa6e7b36dded84625fe" ] ], [ @@ -176,85 +106,122 @@ "id": "test", "single_end": false }, - "test.sorted.bam.csi" + "test.sorted.bam.bai" ] ], - [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:59:55.479443" + "timestamp": "2025-10-29T12:46:25.488622" }, - "multiple bam - stub": { + "cram - stub": { "content": [ { - "0": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:47:28.485045" + }, + "multiple bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,cd4eb0077f25e9cff395366b8883dd1f" + ] + ], + [ + + ], + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d185916eaff9afeb4d0aeab3310371f9" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:46:13.168476" + }, + "multiple bam - stub": { + "content": [ + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "crai": [ - - ], - "cram": [ - - ], - "csi": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:47:21.628088" + }, + "bam_no_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,26b27d1f9bcb61c25da21b562349784e" + ] + ], + [ + + ], + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d185916eaff9afeb4d0aeab3310371f9" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:36:13.781404" + "timestamp": "2025-10-29T12:45:47.139418" }, - "bam": { + "multiple bam csi index": { "content": [ [ [ @@ -262,7 +229,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,34aa85e86abefe637f7a4a9887f016fc" + "test.sorted.bam:md5,295503ba5342531a3310c33ad0efbc22" ] ], [ @@ -274,14 +241,56 @@ "test.sorted.bam.csi" ] ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:46:51.5531" + }, + "bam_bai_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,cae7564cb83bb4a5911205bf94124b54" + ] + ], [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,50dd467c169545a4d5d1f709f7e986e0" + ] + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:59:46.372244" + "timestamp": "2025-10-29T12:45:52.796936" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/sort/tests/nextflow.config b/modules/nf-core/samtools/sort/tests/nextflow.config index f642771f5..723f62b21 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow.config +++ b/modules/nf-core/samtools/sort/tests/nextflow.config @@ -2,7 +2,6 @@ process { withName: SAMTOOLS_SORT { ext.prefix = { "${meta.id}.sorted" } - ext.args = "--write-index" } } diff --git a/modules/nf-core/samtools/sort/tests/tags.yml b/modules/nf-core/samtools/sort/tests/tags.yml deleted file mode 100644 index cd63ea208..000000000 --- a/modules/nf-core/samtools/sort/tests/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -samtools/sort: - - modules/nf-core/samtools/sort/** - - tests/modules/nf-core/samtools/sort/** diff --git a/modules/nf-core/samtools/stats/environment.yml b/modules/nf-core/samtools/stats/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/stats/environment.yml +++ b/modules/nf-core/samtools/stats/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 493525a9e..57d246806 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -4,8 +4,8 @@ process SAMTOOLS_STATS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input), path(input_index) @@ -13,37 +13,28 @@ process SAMTOOLS_STATS { output: tuple val(meta), path("*.stats"), emit: stats - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval('samtools version | sed "1!d;s/.* //"'), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--reference ${fasta}" : "" """ samtools \\ stats \\ + ${args} \\ --threads ${task.cpus} \\ ${reference} \\ ${input} \\ > ${prefix}.stats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.stats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index 77b020f76..5c59cce43 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -27,10 +27,12 @@ input: type: file description: BAM/CRAM file from alignment pattern: "*.{bam,cram}" + ontologies: [] - input_index: type: file description: BAI/CRAI file from alignment pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +42,10 @@ input: type: file description: Reference file the CRAM was created with (optional) pattern: "*.{fasta,fa}" + ontologies: [] output: - - stats: - - meta: + stats: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,11 +54,30 @@ output: type: file description: File containing samtools stats output pattern: "*.{stats}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@FriederikeHanssen" diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test.snap b/modules/nf-core/samtools/stats/tests/main.nf.test.snap index df507be7a..94d981b2a 100644 --- a/modules/nf-core/samtools/stats/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/stats/tests/main.nf.test.snap @@ -8,11 +8,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -20,19 +24,23 @@ "id": "test", "single_end": false }, - "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:16.767396182" + "timestamp": "2025-11-01T02:27:18.460724" }, "bam - stub": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -58,16 +70,20 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:29.721580274" + "timestamp": "2025-11-01T02:27:30.245839" }, "cram - stub": { "content": [ @@ -82,7 +98,11 @@ ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -93,16 +113,20 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:53.567964304" + "timestamp": "2025-11-01T02:27:39.041649" }, "bam": { "content": [ @@ -113,11 +137,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,d53a2584376d78942839e9933a34d11b" + "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -125,18 +153,22 @@ "id": "test", "single_end": false }, - "test.stats:md5,d53a2584376d78942839e9933a34d11b" + "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:28:50.73610604" + "timestamp": "2025-11-01T02:26:55.988241" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/stats/tests/tags.yml b/modules/nf-core/samtools/stats/tests/tags.yml deleted file mode 100644 index 7c28e30f3..000000000 --- a/modules/nf-core/samtools/stats/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/stats: - - modules/nf-core/samtools/stats/** diff --git a/modules/nf-core/samtools/view/environment.yml b/modules/nf-core/samtools/view/environment.yml index 62054fc97..89e12a645 100644 --- a/modules/nf-core/samtools/view/environment.yml +++ b/modules/nf-core/samtools/view/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf index 37e05cec8..b189b5ba4 100644 --- a/modules/nf-core/samtools/view/main.nf +++ b/modules/nf-core/samtools/view/main.nf @@ -4,13 +4,14 @@ process SAMTOOLS_VIEW { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input), path(index) - tuple val(meta2), path(fasta) + tuple val(meta2), path(fasta), path(fai) path qname + val index_format output: tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true @@ -20,8 +21,8 @@ process SAMTOOLS_VIEW { tuple val(meta), path("${prefix}.${file_type}.csi"), emit: csi, optional: true tuple val(meta), path("${prefix}.${file_type}.crai"), emit: crai, optional: true tuple val(meta), path("${prefix}.unselected.${file_type}"), emit: unselected, optional: true - tuple val(meta), path("${prefix}.unselected.${file_type}.{bai,csi,crsi}"), emit: unselected_index, optional: true - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}.unselected.${file_type}.{csi,crai}"), emit: unselected_index, optional: true + tuple val("${task.process}"), val('samtools'), eval('samtools version | sed "1!d;s/.* //"'), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -35,23 +36,30 @@ process SAMTOOLS_VIEW { args.contains("--output-fmt bam") ? "bam" : args.contains("--output-fmt cram") ? "cram" : input.getExtension() + + output_file = index_format ? "${prefix}.${file_type}##idx##${prefix}.${file_type}.${index_format} --write-index" : "${prefix}.${file_type}" + // Can't choose index type of unselected file readnames = qname ? "--qname-file ${qname} --output-unselected ${prefix}.unselected.${file_type}": "" + if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (file_type == "sam") { + error "Indexing not compatible with SAM output" + } + } """ + # Note: --threads value represents *additional* CPUs to allocate (total CPUs = 1 + --threads). samtools \\ view \\ --threads ${task.cpus-1} \\ ${reference} \\ ${readnames} \\ $args \\ - -o ${prefix}.${file_type} \\ + -o ${output_file} \\ $input \\ $args2 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -61,17 +69,26 @@ process SAMTOOLS_VIEW { args.contains("--output-fmt bam") ? "bam" : args.contains("--output-fmt cram") ? "cram" : input.getExtension() - if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" - - def index = args.contains("--write-index") ? "touch ${prefix}.${file_type}.csi" : "" + default_index_format = + file_type == "bam" ? "csi" : + file_type == "cram" ? "crai" : "" + index = index_format ? "touch ${prefix}.${file_type}.${index_format}" : args.contains("--write-index") ? "touch ${prefix}.${file_type}.${default_index_format}" : "" + unselected = qname ? "touch ${prefix}.unselected.${file_type}" : "" + // Can't choose index type of unselected file + unselected_index = qname && (args.contains("--write-index") || index_format) ? "touch ${prefix}.unselected.${file_type}.${default_index_format}" : "" + if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (file_type == "sam") { + error "Indexing not compatible with SAM output." + } + } """ touch ${prefix}.${file_type} ${index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + ${unselected} + ${unselected_index} """ } diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index caa7b0150..23a1af338 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/meta.yml @@ -26,26 +26,41 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - index: type: file description: BAM.BAI/BAM.CSI/CRAM.CRAI file (optional) pattern: "*.{.bai,.csi,.crai}" + ontologies: [] - - meta2: type: map description: | Groovy Map containing reference information - e.g. [ id:'test' ] + e.g. [ id:'genome' ] - fasta: type: file - description: Reference file the CRAM was created with (optional) + description: Fasta reference file pattern: "*.{fasta,fa}" - - - qname: + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - fai: type: file - description: Optional file with read names to output only select alignments - pattern: "*.{txt,list}" + description: Fasta reference file index + pattern: "*.{fai}" + ontologies: + - edam: http://edamontology.org/format_3326 # Index + - qname: + type: file + description: Optional file with read names to output only select alignments + pattern: "*.{txt,list}" + ontologies: [] + - index_format: + type: string + description: Index format, used together with ext.args = '--write-index' + pattern: "bai|csi|crai" output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -54,8 +69,9 @@ output: type: file description: optional filtered/converted BAM file pattern: "*.{bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -64,8 +80,9 @@ output: type: file description: optional filtered/converted CRAM file pattern: "*.{cram}" - - sam: - - meta: + ontologies: [] + sam: + - - meta: type: map description: | Groovy Map containing sample information @@ -74,8 +91,9 @@ output: type: file description: optional filtered/converted SAM file pattern: "*.{sam}" - - bai: - - meta: + ontologies: [] + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -84,8 +102,9 @@ output: type: file description: optional BAM file index pattern: "*.{bai}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -94,8 +113,9 @@ output: type: file description: optional tabix BAM file index pattern: "*.{csi}" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -104,8 +124,9 @@ output: type: file description: optional CRAM file index pattern: "*.{crai}" - - unselected: - - meta: + ontologies: [] + unselected: + - - meta: type: map description: | Groovy Map containing sample information @@ -114,21 +135,41 @@ output: type: file description: optional file with unselected alignments pattern: "*.unselected.{bam,cram,sam}" - - unselected_index: - - meta: + ontologies: [] + unselected_index: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - ${prefix}.unselected.${file_type}.{bai,csi,crsi}: + - ${prefix}.unselected.${file_type}.{csi,crai}: type: file description: index for the "unselected" file - pattern: "*.unselected.{bai,csi,crai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + pattern: "*.unselected.{csi,crai}" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@joseespinosa" diff --git a/modules/nf-core/samtools/view/tests/bam.config b/modules/nf-core/samtools/view/tests/bam.config deleted file mode 100644 index c10d10811..000000000 --- a/modules/nf-core/samtools/view/tests/bam.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--output-fmt bam" -} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/bam_index.config b/modules/nf-core/samtools/view/tests/bam_index.config deleted file mode 100644 index 771ae033a..000000000 --- a/modules/nf-core/samtools/view/tests/bam_index.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--output-fmt bam --write-index" -} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/main.nf.test b/modules/nf-core/samtools/view/tests/main.nf.test index 37b81a916..8d8f292fb 100644 --- a/modules/nf-core/samtools/view/tests/main.nf.test +++ b/modules/nf-core/samtools/view/tests/main.nf.test @@ -2,6 +2,7 @@ nextflow_process { name "Test Process SAMTOOLS_VIEW" script "../main.nf" + config "./nextflow.config" process "SAMTOOLS_VIEW" tag "modules" @@ -10,17 +11,20 @@ nextflow_process { tag "samtools/view" test("bam") { - when { + params { + samtools_args = "" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true), [] - ]) - input[1] = [[],[]] + ] + input[1] = [[],[],[]] input[2] = [] + input[3] = [] """ } } @@ -28,32 +32,140 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bam_bam") }, - { assert snapshot(process.out.bai).match("bam_bai") }, - { assert snapshot(process.out.crai).match("bam_crai") }, - { assert snapshot(process.out.cram).match("bam_cram") }, - { assert snapshot(process.out.csi).match("bam_csi") }, - { assert snapshot(process.out.sam).match("bam_sam") }, - { assert snapshot(process.out.versions).match("bam_versions") } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam"])).match()} ) } } - test("cram") { + test("bam_csi_index") { + when { + params { + samtools_args = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = [] + input[3] = 'csi' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "csi"])).match()} + ) + } + } + + test("bam_bai_index") { + when { + params { + samtools_args = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = [] + input[3] = 'bai' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "bai"])).match()} + ) + } + } + test("bam_bai_index_unselected") { when { + params { + samtools_args = "--output-fmt bam --write-index" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = Channel.of('testN:1') + .collectFile(name: 'selected_reads.txt') + input[3] = 'bai' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "bai", "unselected", "unselected_index"])).match()} + ) + } + } + + test("cram_crai_index_unselected") { + when { + params { + samtools_args = "--output-fmt cram --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = Channel.of('testN:1') + .collectFile(name: 'selected_reads.txt') + input[3] = 'crai' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "bai", "unselected", "unselected_index", "crai"])).match()} + ) + } + } + + test("cram") { + when { + params { + samtools_args = "" + } + process { + """ + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] input[2] = [] + input[3] = [] """ } } @@ -61,34 +173,30 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.cram[0][1]).name).match("cram_cram") }, - { assert snapshot(process.out.bai).match("cram_bai") }, - { assert snapshot(process.out.bam).match("cram_bam") }, - { assert snapshot(process.out.crai).match("cram_crai") }, - { assert snapshot(process.out.csi).match("cram_csi") }, - { assert snapshot(process.out.sam).match("cram_sam") }, - { assert snapshot(process.out.versions).match("cram_versions") } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["cram"])).match()} ) } } test("cram_to_bam") { - - config "./bam.config" - when { + params { + samtools_args = "--output-fmt bam" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), [] - ]) - input[1] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] input[2] = [] + input[3] = [] """ } } @@ -96,34 +204,30 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_bam") }, - { assert snapshot(process.out.bai).match("cram_to_bam_bai") }, - { assert snapshot(process.out.crai).match("cram_to_bam_crai") }, - { assert snapshot(process.out.cram).match("cram_to_bam_cram") }, - { assert snapshot(process.out.csi).match("cram_to_bam_csi") }, - { assert snapshot(process.out.sam).match("cram_to_bam_sam") }, - { assert snapshot(process.out.versions).match("cram_to_bam_versions") } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam"])).match()} ) } } test("cram_to_bam_index") { - - config "./bam_index.config" - when { + params { + samtools_args = "--output-fmt bam --write-index" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), [] - ]) - input[1] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] input[2] = [] + input[3] = [] """ } } @@ -131,34 +235,31 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_bam") }, - { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_csi") }, - { assert snapshot(process.out.bai).match("cram_to_bam_index_bai") }, - { assert snapshot(process.out.crai).match("cram_to_bam_index_crai") }, - { assert snapshot(process.out.cram).match("cram_to_bam_index_cram") }, - { assert snapshot(process.out.sam).match("cram_to_bam_index_sam") }, - { assert snapshot(process.out.versions).match("cram_to_bam_index_versions") } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "csi"])).match()} ) } } test("cram_to_bam_index_qname") { - - config "./bam_index.config" - when { + params { + samtools_args = "--output-fmt bam --write-index" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), [] - ]) - input[1] = Channel.of([ - [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of("testN:2817", "testN:2814").collectFile(name: "readnames.list", newLine: true) + ] + input[1] = [ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[2] = Channel.of("testN:2817", "testN:2814") + .collectFile(name: "readnames.list", newLine: true) + input[3] = [] """ } } @@ -166,15 +267,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_qname_bam") }, - { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_qname_csi") }, - { assert snapshot(process.out.bai).match("cram_to_bam_index_qname_bai") }, - { assert snapshot(process.out.crai).match("cram_to_bam_index_qname_crai") }, - { assert snapshot(process.out.cram).match("cram_to_bam_index_qname_cram") }, - { assert snapshot(process.out.sam).match("cram_to_bam_index_qname_sam") }, - { assert snapshot(file(process.out.unselected[0][1]).name).match("cram_to_bam_index_qname_unselected") }, - { assert snapshot(file(process.out.unselected_index[0][1]).name).match("cram_to_bam_index_qname_unselected_csi") }, - { assert snapshot(process.out.versions).match("cram_to_bam_index_qname_versions") } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "bai", "unselected", "unselected_index"])).match()} ) } } @@ -182,18 +275,143 @@ nextflow_process { test("bam_stub") { options "-stub" - config "./bam_index.config" when { + params { + samtools_args = "--output-fmt bam --write-index" + } process { """ - input[0] = Channel.of([ - [ id:'test', single_end:false ], // meta map + input[0] = [ + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true), [] - ]) - input[1] = [[],[]] + ] + input[1] = [[],[],[]] + input[2] = [] + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["bam", "csi"])).match()} + ) + } + } + + test("bam_csi_index - stub") { + + options "-stub" + + when { + params { + samtools_args = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] input[2] = [] + input[3] = 'csi' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("bam_bai_index - stub") { + + options "-stub" + + when { + params { + samtools_args = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = [] + input[3] = 'bai' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("bam_bai_index_uselected - stub") { + + options "-stub" + + when { + params { + samtools_args = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = Channel.of('testN:1') + .collectFile(name: 'selected_reads.txt') + input[3] = 'bai' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("cram_crai_index_unselected - stub") { + + options "-stub" + + when { + params { + samtools_args = "--output-fmt cram --write-index" + } + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [[],[],[]] + input[2] = Channel.of('testN:1') + .collectFile(name: 'selected_reads.txt') + input[3] = 'crai' """ } } @@ -201,13 +419,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bam_stub_bam") }, - { assert snapshot(file(process.out.csi[0][1]).name).match("bam_stub_csi") }, - { assert snapshot(process.out.bai).match("bam_stub_bai") }, - { assert snapshot(process.out.crai).match("bam_stub_crai") }, - { assert snapshot(process.out.cram).match("bam_stub_cram") }, - { assert snapshot(process.out.sam).match("bam_stub_sam") }, - { assert snapshot(process.out.versions).match("bam_stub_versions") } + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/samtools/view/tests/main.nf.test.snap b/modules/nf-core/samtools/view/tests/main.nf.test.snap index 63849b037..95205e56f 100644 --- a/modules/nf-core/samtools/view/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/view/tests/main.nf.test.snap @@ -1,528 +1,949 @@ { - "bam_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.256068" - }, - "cram_to_bam_index_csi": { - "content": [ - "test.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.958617" - }, - "bam_stub_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.065301" - }, - "bam_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.258578" - }, - "bam_stub_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.071284" - }, - "bam_stub_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:26:24.461775464" - }, - "cram_to_bam_index_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.972288" - }, - "cram_to_bam_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.999247" - }, - "cram_to_bam_index_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.976457" - }, - "cram_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.497581" - }, - "cram_csi": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.50038" - }, - "cram_to_bam_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.992239" - }, - "cram_to_bam_index_qname_csi": { - "content": [ - "test.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.325496" - }, - "bam_stub_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.079529" - }, - "cram_cram": { - "content": [ - "test.cram" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.490286" - }, - "cram_to_bam_index_qname_unselected_csi": { - "content": [ - "test.unselected.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.328458" - }, - "bam_csi": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.262882" - }, - "cram_to_bam_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.989247" - }, - "cram_to_bam_index_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.967681" - }, - "cram_to_bam_index_qname_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:25:51.953436682" - }, - "cram_to_bam_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.982361" - }, - "cram_to_bam_index_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.95456" - }, - "cram_to_bam_index_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:25:14.475388399" - }, - "cram_to_bam_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.98601" - }, - "cram_to_bam_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:24:49.673441798" - }, - "cram_bam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.495512" - }, - "bam_stub_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.076908" - }, - "cram_to_bam_index_qname_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.328458" - }, - "cram_to_bam_index_qname_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.330789" - }, - "cram_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.493129" - }, - "bam_stub_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.074313" - }, - "cram_to_bam_index_qname_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.322874" - }, - "cram_to_bam_index_qname_unselected": { - "content": [ - "test.unselected.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.322874" - }, - "cram_to_bam_index_qname_unselected_csi": { - "content": [ - "test.unselected.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.328458" - }, - "bam_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:23:27.151650338" - }, - "cram_to_bam_index_qname_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.333248" - }, - "bam_crai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.259774" - }, - "bam_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.261287" - }, - "cram_to_bam_csi": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:04.995454" - }, - "cram_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:56.502625" - }, - "cram_versions": { - "content": [ - [ - "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T09:24:12.95416913" - }, - "cram_to_bam_index_qname_unselected": { - "content": [ - "test.unselected.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.322874" - }, - "bam_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:37:51.264651" - }, - "cram_to_bam_index_bai": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:12.962863" - }, - "cram_to_bam_index_qname_sam": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:23.337634" - }, - "bam_stub_csi": { - "content": [ - "test.bam.csi" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-12T19:38:32.068596" + "cram_to_bam_index": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test" + }, + "test.bam.csi" + ] + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:14.82588493" + }, + "bam_csi_index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test" + }, + "test.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + + ], + "6": [ + + ], + "7": [ + + ], + "8": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ], + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test" + }, + "test.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:31.409368544" + }, + "bam_csi_index": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test" + }, + "test.bam.csi" + ] + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:48:46.36824035" + }, + "cram_to_bam_index_qname": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test" + }, + "test.bam.csi:md5,15d725bced7ececd45b4312b2af99a6b" + ] + ], + "sam": [ + + ], + "unselected": [ + [ + { + "id": "test" + }, + "test.unselected.bam" + ] + ], + "unselected_index": [ + [ + { + "id": "test" + }, + "test.unselected.bam.csi" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:20.747636525" + }, + "bam_bai_index_unselected": { + "content": [ + { + "bai": [ + [ + { + "id": "test" + }, + "test.bam.bai" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + [ + { + "id": "test" + }, + "test.unselected.bam" + ] + ], + "unselected_index": [ + [ + { + "id": "test" + }, + "test.unselected.bam.csi" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:48:57.713608154" + }, + "cram_crai_index_unselected - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test" + }, + "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test" + }, + "test.unselected.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test" + }, + "test.unselected.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ], + "bai": [ + + ], + "bam": [ + + ], + "crai": [ + [ + { + "id": "test" + }, + "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cram": [ + [ + { + "id": "test" + }, + "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + [ + { + "id": "test" + }, + "test.unselected.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "unselected_index": [ + [ + { + "id": "test" + }, + "test.unselected.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:48.092654899" + }, + "bam": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:48:27.608944526" + }, + "bam_bai_index": { + "content": [ + { + "bai": [ + [ + { + "id": "test" + }, + "test.bam.bai" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:48:52.047178732" + }, + "cram_to_bam": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:50:41.727031999" + }, + "bam_bai_index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + + ], + "7": [ + + ], + "8": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ], + "bai": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:36.783381688" + }, + "cram": { + "content": [ + { + "bai": [ + + ], + "bam": [ + + ], + "crai": [ + + ], + "cram": [ + [ + { + "id": "test" + }, + "test.cram" + ] + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:09.393102901" + }, + "bam_bai_index_uselected - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + [ + { + "id": "test" + }, + "test.unselected.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test" + }, + "test.unselected.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ], + "bai": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + [ + { + "id": "test" + }, + "test.unselected.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "unselected_index": [ + [ + { + "id": "test" + }, + "test.unselected.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:42.344755528" + }, + "cram_crai_index_unselected": { + "content": [ + { + "bai": [ + + ], + "bam": [ + + ], + "crai": [ + [ + { + "id": "test" + }, + "test.cram.crai" + ] + ], + "cram": [ + [ + { + "id": "test" + }, + "test.cram:md5,9b6eeca8f6b4b744297ae7cc87c031a4" + ] + ], + "csi": [ + + ], + "sam": [ + + ], + "unselected": [ + [ + { + "id": "test" + }, + "test.unselected.cram" + ] + ], + "unselected_index": [ + [ + { + "id": "test" + }, + "test.unselected.cram.crai" + ] + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:03.431621547" + }, + "bam_stub": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test" + }, + "test.bam.csi" + ] + ], + "sam": [ + + ], + "unselected": [ + + ], + "unselected_index": [ + + ], + "versions_samtools": [ + [ + "SAMTOOLS_VIEW", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-03T16:49:26.152824543" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/nextflow.config b/modules/nf-core/samtools/view/tests/nextflow.config new file mode 100644 index 000000000..37c564396 --- /dev/null +++ b/modules/nf-core/samtools/view/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: SAMTOOLS_VIEW { + ext.args = params.samtools_args + } +} diff --git a/modules/nf-core/samtools/view/tests/tags.yml b/modules/nf-core/samtools/view/tests/tags.yml deleted file mode 100644 index 4fdf1dd12..000000000 --- a/modules/nf-core/samtools/view/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/view: - - "modules/nf-core/samtools/view/**" diff --git a/modules/nf-core/sentieon/bwaindex/environment.yml b/modules/nf-core/sentieon/bwaindex/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/bwaindex/environment.yml +++ b/modules/nf-core/sentieon/bwaindex/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/bwaindex/main.nf b/modules/nf-core/sentieon/bwaindex/main.nf index 4372cc04b..1b36961a1 100644 --- a/modules/nf-core/sentieon/bwaindex/main.nf +++ b/modules/nf-core/sentieon/bwaindex/main.nf @@ -1,19 +1,19 @@ process SENTIEON_BWAINDEX { - tag "$fasta" + tag "${fasta}" label 'process_high' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(fasta) output: - tuple val(meta), path(bwa), emit: index - path "versions.yml" , emit: versions + tuple val(meta), path("bwa"), emit: index + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when @@ -21,20 +21,18 @@ process SENTIEON_BWAINDEX { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ? "bwa/${task.ext.prefix}" : "bwa/${fasta.baseName}" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ + ${sentieonLicense} mkdir bwa sentieon \\ bwa index \\ - $args \\ - -p $prefix \\ - $fasta - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - bwa: \$(echo \$(sentieon bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS + ${args} \\ + -p ${prefix} \\ + ${fasta} """ stub: @@ -46,11 +44,5 @@ process SENTIEON_BWAINDEX { touch bwa/genome.bwt touch bwa/genome.pac touch bwa/genome.sa - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - bwa: \$(echo \$(sentieon bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/bwaindex/meta.yml b/modules/nf-core/sentieon/bwaindex/meta.yml index acbd14d51..165247da8 100644 --- a/modules/nf-core/sentieon/bwaindex/meta.yml +++ b/modules/nf-core/sentieon/bwaindex/meta.yml @@ -23,9 +23,10 @@ input: - fasta: type: file description: Input genome fasta file + ontologies: [] output: - - index: - - meta: + index: + - - meta: type: map description: | Groovy Map containing reference information. @@ -34,14 +35,29 @@ output: type: file description: BWA genome index files pattern: "*.{amb,ann,bwt,pac,sa}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool authors: - - "@drpatelh" - "@maxulysse" maintainers: - - "@drpatelh" - "@maxulysse" diff --git a/modules/nf-core/sentieon/bwaindex/tests/main.nf.test b/modules/nf-core/sentieon/bwaindex/tests/main.nf.test new file mode 100644 index 000000000..57526c705 --- /dev/null +++ b/modules/nf-core/sentieon/bwaindex/tests/main.nf.test @@ -0,0 +1,55 @@ +nextflow_process { + + name "Test Process SENTIEON_BWAINDEX" + script "../main.nf" + process "SENTIEON_BWAINDEX" + + tag "modules" + tag "modules_nfcore" + tag "sentieon" + tag "sentieon/bwaindex" + + test("build index - fasta") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } + + test("build index - fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/sentieon/bwaindex/tests/main.nf.test.snap b/modules/nf-core/sentieon/bwaindex/tests/main.nf.test.snap new file mode 100644 index 000000000..98d1984ac --- /dev/null +++ b/modules/nf-core/sentieon/bwaindex/tests/main.nf.test.snap @@ -0,0 +1,108 @@ +{ + "build index - fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "SENTIEON_BWAINDEX", + "sentieon", + "202503.02" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_BWAINDEX", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-19T18:27:10.208416609" + }, + "build index - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,3a68b8b2287e07dd3f5f95f4344ba76e", + "genome.ann:md5,c32e11f6c859f166c7525a9c1d583567", + "genome.bwt:md5,0469c30a1e239dd08f68afe66fde99da", + "genome.pac:md5,983e3d2cd6f36e2546e6d25a0da78d66", + "genome.sa:md5,ab3952cabf026b48cd3eb5bccbb636d1" + ] + ] + ], + "1": [ + [ + "SENTIEON_BWAINDEX", + "sentieon", + "202503.02" + ] + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.amb:md5,3a68b8b2287e07dd3f5f95f4344ba76e", + "genome.ann:md5,c32e11f6c859f166c7525a9c1d583567", + "genome.bwt:md5,0469c30a1e239dd08f68afe66fde99da", + "genome.pac:md5,983e3d2cd6f36e2546e6d25a0da78d66", + "genome.sa:md5,ab3952cabf026b48cd3eb5bccbb636d1" + ] + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_BWAINDEX", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-19T18:27:03.694090374" + } +} \ No newline at end of file diff --git a/modules/nf-core/sentieon/bwaindex/tests/nextflow.config b/modules/nf-core/sentieon/bwaindex/tests/nextflow.config new file mode 100644 index 000000000..9a93f5007 --- /dev/null +++ b/modules/nf-core/sentieon/bwaindex/tests/nextflow.config @@ -0,0 +1,11 @@ +env { + // NOTE This is how nf-core/sarek users will use Sentieon in real world use + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') + // NOTE This should only happen in GitHub actions or nf-core MegaTests + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') + SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA + // NOTE This is how users will test out Sentieon in Sarek with a license file + // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) +} diff --git a/modules/nf-core/sentieon/bwamem/environment.yml b/modules/nf-core/sentieon/bwamem/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/bwamem/environment.yml +++ b/modules/nf-core/sentieon/bwamem/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/bwamem/main.nf b/modules/nf-core/sentieon/bwamem/main.nf index c038a857b..ca37c2c59 100644 --- a/modules/nf-core/sentieon/bwamem/main.nf +++ b/modules/nf-core/sentieon/bwamem/main.nf @@ -1,12 +1,12 @@ process SENTIEON_BWAMEM { - tag "$meta.id" + tag "${meta.id}" label 'process_high' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(reads) @@ -16,7 +16,8 @@ process SENTIEON_BWAMEM { output: tuple val(meta), path("${prefix}"), path("${prefix}.{bai,crai}"), emit: bam_and_bai - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bwa'), eval('sentieon bwa 2>&1 | sed -n "s/^Version: *//p"'), topic: versions, emit: versions_bwa + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when @@ -24,47 +25,34 @@ process SENTIEON_BWAMEM { script: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}.bam" - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} export bwt_max_mem="${(task.memory * 0.9).toGiga()}G" INDEX=`find -L ./ -name "*.amb" | sed 's/.amb//'` sentieon bwa mem \\ - $args \\ - -t $task.cpus \\ + ${args} \\ + -t ${task.cpus} \\ \$INDEX \\ - $reads \\ - | sentieon util sort -r $fasta -t $task.cpus -o ${prefix} --sam2bam - + ${reads} \\ + | sentieon util sort -r ${fasta} -t ${task.cpus} -o ${prefix} --sam2bam - # Delete *.bai file if prefix ends with .cram if [[ "${prefix}" == *.cram ]]; then rm -f "${prefix}.bai" fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - bwa: \$(echo \$(sentieon bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS """ stub: prefix = task.ext.prefix ?: "${meta.id}.bam" - index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" - + index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" """ touch ${prefix} touch ${prefix}.${index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - bwa: \$(echo \$(sentieon bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/bwamem/meta.yml b/modules/nf-core/sentieon/bwamem/meta.yml index b27dd4877..a36fb5f5e 100644 --- a/modules/nf-core/sentieon/bwamem/meta.yml +++ b/modules/nf-core/sentieon/bwamem/meta.yml @@ -25,6 +25,7 @@ input: - reads: type: file description: Genome fastq files (single-end or paired-end) + ontologies: [] - - meta2: type: map description: | @@ -34,6 +35,7 @@ input: type: file description: BWA genome index files pattern: "*.{amb,ann,bwt,pac,sa}" + ontologies: [] - - meta3: type: map description: | @@ -43,6 +45,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta4: type: map description: | @@ -52,9 +55,10 @@ input: type: file description: The index of the FASTA reference. pattern: "*.fai" + ontologies: [] output: - - bam_and_bai: - - meta: + bam_and_bai: + - - meta: type: map description: | Groovy Map containing reference information. @@ -63,15 +67,54 @@ output: type: file description: BAM file with corresponding index. pattern: "*.{bam,bai}" + ontologies: [] - ${prefix}.{bai,crai}: type: file description: BAM file with corresponding index. pattern: "*.{bam,bai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwa: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bwa: + type: string + description: The tool name + - 'sentieon bwa 2>&1 | sed -n "s/^Version: *//p"': + type: string + description: The command used to generate the version of the tool + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bwa: + type: string + description: The tool name + - 'sentieon bwa 2>&1 | sed -n "s/^Version: *//p"': + type: string + description: The command used to generate the version of the tool + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool + authors: - "@asp8200" maintainers: diff --git a/modules/nf-core/sentieon/bwamem/tests/main.nf.test b/modules/nf-core/sentieon/bwamem/tests/main.nf.test index 074722882..676ec10b8 100644 --- a/modules/nf-core/sentieon/bwamem/tests/main.nf.test +++ b/modules/nf-core/sentieon/bwamem/tests/main.nf.test @@ -11,9 +11,9 @@ nextflow_process { script "../main.nf" process "SENTIEON_BWAMEM" + config "./nextflow.config" test("Single-End") { - config "./nextflow.config" setup { run("SENTIEON_BWAINDEX") { @@ -30,6 +30,10 @@ nextflow_process { } when { + params { + module_args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + module_out_cram = false + } process { """ input[0] = [ @@ -46,16 +50,18 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + bam(process.out.bam_and_bai[0][1]).getReadsMD5(), + file(process.out.bam_and_bai[0][2]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("Single-End Output CRAM") { - config "./nextflow_out_cram.config" setup { run("SENTIEON_BWAINDEX") { @@ -72,6 +78,10 @@ nextflow_process { } when { + params { + module_args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + module_out_cram = true + } process { """ input[0] = [ @@ -88,16 +98,19 @@ nextflow_process { } then { + def fasta = "https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/sarscov2/genome/genome.fasta" + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + cram(process.out.bam_and_bai[0][1], fasta).getReadsMD5(), + file(process.out.bam_and_bai[0][2]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("Paired-End") { - config "./nextflow.config" setup { run("SENTIEON_BWAINDEX") { @@ -114,23 +127,10 @@ nextflow_process { } when { - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) - ] - ] - input[1] = SENTIEON_BWAINDEX.out.index - input[2] = [[id: 'test'],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = [[id: 'test'],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] - """ + params { + module_args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + module_out_cram = false } - } - - when { process { """ input[0] = [ @@ -147,16 +147,20 @@ nextflow_process { } } + then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + bam(process.out.bam_and_bai[0][1]).getReadsMD5(), + file(process.out.bam_and_bai[0][2]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } test("Single-End - stub") { - config "./nextflow.config" options "-stub" setup { @@ -174,6 +178,10 @@ nextflow_process { } when { + params { + module_args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + module_out_cram = false + } process { """ input[0] = [ @@ -190,16 +198,14 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } test("Paired-End - stub") { - config "./nextflow.config" options "-stub" setup { @@ -217,23 +223,10 @@ nextflow_process { } when { - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - [ - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) - ] - ] - input[1] = SENTIEON_BWAINDEX.out.index - input[2] = [[id: 'test'],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = [[id: 'test'],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] - """ + params { + module_args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + module_out_cram = false } - } - - when { process { """ input[0] = [ @@ -250,13 +243,12 @@ nextflow_process { } } + then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } } - - } diff --git a/modules/nf-core/sentieon/bwamem/tests/main.nf.test.snap b/modules/nf-core/sentieon/bwamem/tests/main.nf.test.snap index 77070ccc4..5a0fa2006 100644 --- a/modules/nf-core/sentieon/bwamem/tests/main.nf.test.snap +++ b/modules/nf-core/sentieon/bwamem/tests/main.nf.test.snap @@ -1,40 +1,30 @@ { "Single-End": { "content": [ + "30c325e1e032eb1782a280d34c0fb1c7", + "test.bam.bai", { - "0": [ + "versions_bwa": [ [ - { - "id": "test", - "single_end": true - }, - "test.bam:md5,7b62831cb67d6d4a8e33b3cb788dfb1b", - "test.bam.bai:md5,6fc1dff58fab0491ecfa48f016041a18" + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" ] ], - "1": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" - ], - "bam_and_bai": [ + "versions_sentieon": [ [ - { - "id": "test", - "single_end": true - }, - "test.bam:md5,7b62831cb67d6d4a8e33b3cb788dfb1b", - "test.bam.bai:md5,6fc1dff58fab0491ecfa48f016041a18" + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" ] - ], - "versions": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:25:33.275731212" + "timestamp": "2026-01-20T13:36:45.282690704" }, "Paired-End - stub": { "content": [ @@ -50,7 +40,18 @@ ] ], "1": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" + [ + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" + ] + ], + "2": [ + [ + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" + ] ], "bam_and_bai": [ [ @@ -62,53 +63,54 @@ "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" + "versions_bwa": [ + [ + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:26:16.58588651" + "timestamp": "2026-01-19T16:27:57.975551525" }, "Paired-End": { "content": [ + "2d64e4363d9f3c0e2167fce49d5087cf", + "test.bam.bai", { - "0": [ + "versions_bwa": [ [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,b0c8606d660dbe50a34cf80a376bb268", - "test.bam.bai:md5,be4ad85790468042f7fc01ca2e36a919" + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" ] ], - "1": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" - ], - "bam_and_bai": [ + "versions_sentieon": [ [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,b0c8606d660dbe50a34cf80a376bb268", - "test.bam.bai:md5,be4ad85790468042f7fc01ca2e36a919" + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" ] - ], - "versions": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:25:55.068934639" + "timestamp": "2026-01-20T13:37:06.816187615" }, "Single-End - stub": { "content": [ @@ -124,7 +126,18 @@ ] ], "1": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" + [ + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" + ] + ], + "2": [ + [ + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" + ] ], "bam_and_bai": [ [ @@ -136,52 +149,53 @@ "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" + "versions_bwa": [ + [ + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:26:05.151760076" + "timestamp": "2026-01-19T16:27:48.308820347" }, "Single-End Output CRAM": { "content": [ + "30c325e1e032eb1782a280d34c0fb1c7", + "test.cram.crai", { - "0": [ + "versions_bwa": [ [ - { - "id": "test", - "single_end": true - }, - "test.cram:md5,817cf0847ae0c89062e2ee4be312101a", - "test.cram.crai:md5,60f801c550a18982e55207adb31ec351" + "SENTIEON_BWAMEM", + "bwa", + "0.7.17-r1188" ] ], - "1": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" - ], - "bam_and_bai": [ + "versions_sentieon": [ [ - { - "id": "test", - "single_end": true - }, - "test.cram:md5,817cf0847ae0c89062e2ee4be312101a", - "test.cram.crai:md5,60f801c550a18982e55207adb31ec351" + "SENTIEON_BWAMEM", + "sentieon", + "202503.02" ] - ], - "versions": [ - "versions.yml:md5,755d24c7416c1408313ec93814cef759" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:25:44.360755915" + "timestamp": "2026-01-20T13:36:56.563978907" } } \ No newline at end of file diff --git a/modules/nf-core/sentieon/bwamem/tests/nextflow.config b/modules/nf-core/sentieon/bwamem/tests/nextflow.config index 717fb52c7..e3d56f721 100644 --- a/modules/nf-core/sentieon/bwamem/tests/nextflow.config +++ b/modules/nf-core/sentieon/bwamem/tests/nextflow.config @@ -1,15 +1,18 @@ env { // NOTE This is how nf-core/sarek users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how nf-core/sarek users will test out Sentieon in Sarek with a license file + // NOTE This is how users will test out Sentieon in Sarek with a license file // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) } process { withName: 'SENTIEON_BWAMEM' { - ext.args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" + ext.args = params.module_args + ext.prefix = { "${meta.id}." + (params.module_out_cram ? 'cram' : 'bam') } } } diff --git a/modules/nf-core/sentieon/bwamem/tests/nextflow_out_cram.config b/modules/nf-core/sentieon/bwamem/tests/nextflow_out_cram.config deleted file mode 100644 index 07ae63d98..000000000 --- a/modules/nf-core/sentieon/bwamem/tests/nextflow_out_cram.config +++ /dev/null @@ -1,16 +0,0 @@ -env { - // NOTE This is how nf-core/sarek users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" - // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" - SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how nf-core/sarek users will test out Sentieon in Sarek with a license file - // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) -} - -process { - withName: 'SENTIEON_BWAMEM' { - ext.args = "-R \"@RG\\tID:sample_lane\\tPU:lane\\tSM:patient_sample\\tLB:sample\\tDS:fasta\\tPL:seqplatform\"" - ext.prefix = { "${meta.id}.cram" } - } -} diff --git a/modules/nf-core/sentieon/bwamem/tests/tags.yml b/modules/nf-core/sentieon/bwamem/tests/tags.yml deleted file mode 100644 index fbc2bb3cc..000000000 --- a/modules/nf-core/sentieon/bwamem/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -sentieon/bwamem: - - "modules/nf-core/sentieon/bwamem/**" diff --git a/modules/nf-core/sentieon/datametrics/environment.yml b/modules/nf-core/sentieon/datametrics/environment.yml index d7abf668e..2986b7b43 100644 --- a/modules/nf-core/sentieon/datametrics/environment.yml +++ b/modules/nf-core/sentieon/datametrics/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 + - conda-forge::gnuplot=5.4.10 diff --git a/modules/nf-core/sentieon/datametrics/main.nf b/modules/nf-core/sentieon/datametrics/main.nf index 85bf6b507..9c1b8dd65 100644 --- a/modules/nf-core/sentieon/datametrics/main.nf +++ b/modules/nf-core/sentieon/datametrics/main.nf @@ -1,12 +1,12 @@ process SENTIEON_DATAMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ae/ae67a134620c3af22c8563a2913c4639caa0d75ce25764e7b10c996b242aa023/data' + : 'community.wave.seqera.io/library/sentieon_gnuplot:41931fca35668c97'}" input: tuple val(meta), path(bam), path(bai) @@ -15,55 +15,50 @@ process SENTIEON_DATAMETRICS { val plot_results output: - tuple val(meta), path('*mq_metrics.txt') , emit: mq_metrics - tuple val(meta), path('*qd_metrics.txt') , emit: qd_metrics - tuple val(meta), path('*gc_summary.txt') , emit: gc_summary - tuple val(meta), path('*gc_metrics.txt') , emit: gc_metrics + tuple val(meta), path('*mq_metrics.txt'), emit: mq_metrics + tuple val(meta), path('*qd_metrics.txt'), emit: qd_metrics + tuple val(meta), path('*gc_summary.txt'), emit: gc_summary + tuple val(meta), path('*gc_metrics.txt'), emit: gc_metrics tuple val(meta), path('*aln_metrics.txt'), emit: aln_metrics - tuple val(meta), path('*is_metrics.txt') , emit: is_metrics - tuple val(meta), path('*mq_metrics.pdf') , emit: mq_plot, optional: true - tuple val(meta), path('*qd_metrics.pdf') , emit: qd_plot, optional: true - tuple val(meta), path('*is_metrics.pdf') , emit: is_plot, optional: true - tuple val(meta), path('*gc_metrics.pdf') , emit: gc_plot, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path('*is_metrics.txt'), emit: is_metrics + tuple val(meta), path('*mq_metrics.pdf'), emit: mq_plot, optional: true + tuple val(meta), path('*qd_metrics.pdf'), emit: qd_plot, optional: true + tuple val(meta), path('*is_metrics.pdf'), emit: is_plot, optional: true + tuple val(meta), path('*gc_metrics.pdf'), emit: gc_plot, optional: true + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def input = bam.sort().collect{"-i $it"}.join(' ') - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def input = bam.sort().collect {in -> "-i ${in}" }.join(' ') + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} sentieon \\ driver \\ - -t $task.cpus \\ - -r $fasta \\ - $input \\ - $args \\ + -t ${task.cpus} \\ + -r ${fasta} \\ + ${input} \\ + ${args} \\ --algo GCBias --summary ${prefix}_gc_summary.txt ${prefix}_gc_metrics.txt \\ --algo MeanQualityByCycle ${prefix}_mq_metrics.txt \\ --algo QualDistribution ${prefix}_qd_metrics.txt \\ --algo InsertSizeMetricAlgo ${prefix}_is_metrics.txt \\ --algo AlignmentStat ${prefix}_aln_metrics.txt - if $plot_results + if ${plot_results} then sentieon plot GCBias -o ${prefix}_gc_metrics.pdf ${prefix}_gc_metrics.txt sentieon plot MeanQualityByCycle -o ${prefix}_mq_metrics.pdf ${prefix}_mq_metrics.txt sentieon plot QualDistribution -o ${prefix}_qd_metrics.pdf ${prefix}_qd_metrics.txt sentieon plot InsertSizeMetricAlgo -o ${prefix}_is_metrics.pdf ${prefix}_is_metrics.txt fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ stub: @@ -76,17 +71,12 @@ process SENTIEON_DATAMETRICS { touch ${prefix}_aln_metrics.txt touch ${prefix}_is_metrics.txt - if $plot_results + if ${plot_results} then touch ${prefix}_gc_metrics.pdf touch ${prefix}_mq_metrics.pdf touch ${prefix}_qd_metrics.pdf touch ${prefix}_is_metrics.pdf fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/datametrics/meta.yml b/modules/nf-core/sentieon/datametrics/meta.yml index 2b59da39c..ad5e18d93 100644 --- a/modules/nf-core/sentieon/datametrics/meta.yml +++ b/modules/nf-core/sentieon/datametrics/meta.yml @@ -22,10 +22,12 @@ input: type: file description: Sorted BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Index of th sorted BAM/CRAM/SAM file pattern: "*.{bai,crai,sai}" + ontologies: [] - - meta2: type: map description: | @@ -35,6 +37,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -44,35 +47,38 @@ input: type: file description: Index of the genome fasta file pattern: "*.fai" - - - plot_results: - type: boolean - description: Boolean to determine whether plots should be generated - pattern: "true or false" + ontologies: [] + - plot_results: + type: boolean + description: Boolean to determine whether plots should be generated + pattern: "true or false" output: - - mq_metrics: - - meta: + mq_metrics: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*mq_metrics.txt": type: file - description: File containing the information about mean base quality score for - each sequencing cycle + description: File containing the information about mean base quality score + for each sequencing cycle pattern: "*.txt" - - qd_metrics: - - meta: + ontologies: [] + qd_metrics: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*qd_metrics.txt": type: file - description: File containing the information about number of bases with a specific - base quality score + description: File containing the information about number of bases with a + specific base quality score pattern: "*.txt" - - gc_summary: - - meta: + ontologies: [] + gc_summary: + - - meta: type: map description: | Groovy Map containing sample information @@ -82,8 +88,9 @@ output: description: File containing the information about GC bias in the reference and the sample pattern: "*.txt" - - gc_metrics: - - meta: + ontologies: [] + gc_metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -93,8 +100,9 @@ output: description: File containing the information about GC bias in the reference and the sample pattern: "*.txt" - - aln_metrics: - - meta: + ontologies: [] + aln_metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -103,8 +111,9 @@ output: type: file description: File containing the statistics about the alignment of the reads pattern: "*.txt" - - is_metrics: - - meta: + ontologies: [] + is_metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -114,51 +123,72 @@ output: description: File containing the information about statistical distribution of insert sizes pattern: "*.txt" - - mq_plot: - - meta: + ontologies: [] + mq_plot: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*mq_metrics.pdf": type: file - description: "PDF containting plot of mean base quality scores" + description: "PDF containing plot of mean base quality scores" pattern: "*.pdf" - - qd_plot: - - meta: + ontologies: [] + qd_plot: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*qd_metrics.pdf": type: file - description: "PDF containting plot of specific base quality score" + description: "PDF containing plot of specific base quality score" pattern: "*.pdf" - - is_plot: - - meta: + ontologies: [] + is_plot: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*is_metrics.pdf": type: file - description: "PDF containting plot of insert sizes" + description: "PDF containing plot of insert sizes" pattern: "*.pdf" - - gc_plot: - - meta: + ontologies: [] + gc_plot: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*gc_metrics.pdf": type: file - description: "PDF containting plot of GC bias" + description: "PDF containing plot of GC bias" pattern: "*.pdf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/sentieon/datametrics/tests/main.nf.test b/modules/nf-core/sentieon/datametrics/tests/main.nf.test index a13d68e6e..87b193ca3 100644 --- a/modules/nf-core/sentieon/datametrics/tests/main.nf.test +++ b/modules/nf-core/sentieon/datametrics/tests/main.nf.test @@ -33,12 +33,20 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + path(process.out.mq_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.qd_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.gc_summary[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.gc_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.aln_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.is_metrics[0][1]).readLines()[1..3].join("\n").md5(), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } - } test("metrics - with plots") { @@ -64,12 +72,24 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + path(process.out.mq_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.qd_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.gc_summary[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.gc_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.aln_metrics[0][1]).readLines()[1..3].join("\n").md5(), + path(process.out.is_metrics[0][1]).readLines()[1..3].join("\n").md5(), + file(process.out.mq_plot[0][1]).name, + file(process.out.qd_plot[0][1]).name, + file(process.out.is_plot[0][1]).name, + file(process.out.gc_plot[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } - } test("sarscov2 - stub") { @@ -98,12 +118,10 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/sentieon/datametrics/tests/main.nf.test.snap b/modules/nf-core/sentieon/datametrics/tests/main.nf.test.snap index d31612106..5683e7ecb 100644 --- a/modules/nf-core/sentieon/datametrics/tests/main.nf.test.snap +++ b/modules/nf-core/sentieon/datametrics/tests/main.nf.test.snap @@ -21,7 +21,11 @@ ] ], "10": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" + [ + "SENTIEON_DATAMETRICS", + "sentieon", + "202503.02" + ] ], "2": [ [ @@ -185,361 +189,71 @@ "test_qd_metrics.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" + "versions_sentieon": [ + [ + "SENTIEON_DATAMETRICS", + "sentieon", + "202503.02" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:22:45.899449567" + "timestamp": "2026-01-22T07:24:06.675145986" }, "metrics - with plots": { "content": [ + "8fdd2f19b222aa3a8f1d4f82d3792809", + "a5b70394b8ab8ab26fad4a0b819df96c", + "1e40f4ebb6098e8f7e07f51d873cc26b", + "547b7f29acc4efc43462d4df3f34b774", + "8d28671f4ef0d56ed1704cf236bf0952", + "186761dcce9ac40f25ae4bdaa0153544", + "test_mq_metrics.pdf", + "test_qd_metrics.pdf", + "test_is_metrics.pdf", + "test_gc_metrics.pdf", { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.txt:md5,159ed897b11e7621703365134f60c1f7" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.txt:md5,fa86f2f5cc195ea48565401f68ba0730" - ] - ], - "10": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_summary.txt:md5,367143e0f7680555bb68173561919e5f" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.txt:md5,42d6ee7ce81858329b66c38e6558d66d" - ] - ], - "4": [ - [ - { - "id": "test", - "single_end": false - }, - "test_aln_metrics.txt:md5,1950af402ff3751023761de5bb649b43" - ] - ], - "5": [ - [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.txt:md5,0ce93baa9d470f9b6344094218d74e59" - ] - ], - "6": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.pdf:md5,c04212fac971c67066082dcb63fa08ce" - ] - ], - "7": [ - [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.pdf:md5,4edab3779660668a7cfd203196912ace" - ] - ], - "8": [ - [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.pdf:md5,068232633e0f93ea2b53f4c698bd8a54" - ] - ], - "9": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.pdf:md5,950372106204ff4d2fbe5ca413ac8300" - ] - ], - "aln_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_aln_metrics.txt:md5,1950af402ff3751023761de5bb649b43" - ] - ], - "gc_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.txt:md5,42d6ee7ce81858329b66c38e6558d66d" - ] - ], - "gc_plot": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.pdf:md5,950372106204ff4d2fbe5ca413ac8300" - ] - ], - "gc_summary": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_summary.txt:md5,367143e0f7680555bb68173561919e5f" - ] - ], - "is_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.txt:md5,0ce93baa9d470f9b6344094218d74e59" - ] - ], - "is_plot": [ - [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.pdf:md5,068232633e0f93ea2b53f4c698bd8a54" - ] - ], - "mq_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.txt:md5,159ed897b11e7621703365134f60c1f7" - ] - ], - "mq_plot": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.pdf:md5,c04212fac971c67066082dcb63fa08ce" - ] - ], - "qd_metrics": [ + "versions_sentieon": [ [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.txt:md5,fa86f2f5cc195ea48565401f68ba0730" + "SENTIEON_DATAMETRICS", + "sentieon", + "202503.02" ] - ], - "qd_plot": [ - [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.pdf:md5,4edab3779660668a7cfd203196912ace" - ] - ], - "versions": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:22:36.981327826" + "timestamp": "2026-01-22T20:37:45.530044821" }, "metrics - no plots": { "content": [ + "8fdd2f19b222aa3a8f1d4f82d3792809", + "a5b70394b8ab8ab26fad4a0b819df96c", + "1e40f4ebb6098e8f7e07f51d873cc26b", + "547b7f29acc4efc43462d4df3f34b774", + "8d28671f4ef0d56ed1704cf236bf0952", + "186761dcce9ac40f25ae4bdaa0153544", { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.txt:md5,159ed897b11e7621703365134f60c1f7" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.txt:md5,fa86f2f5cc195ea48565401f68ba0730" - ] - ], - "10": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_summary.txt:md5,367143e0f7680555bb68173561919e5f" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.txt:md5,42d6ee7ce81858329b66c38e6558d66d" - ] - ], - "4": [ - [ - { - "id": "test", - "single_end": false - }, - "test_aln_metrics.txt:md5,1950af402ff3751023761de5bb649b43" - ] - ], - "5": [ + "versions_sentieon": [ [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.txt:md5,0ce93baa9d470f9b6344094218d74e59" + "SENTIEON_DATAMETRICS", + "sentieon", + "202503.02" ] - ], - "6": [ - - ], - "7": [ - - ], - "8": [ - - ], - "9": [ - - ], - "aln_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_aln_metrics.txt:md5,1950af402ff3751023761de5bb649b43" - ] - ], - "gc_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_metrics.txt:md5,42d6ee7ce81858329b66c38e6558d66d" - ] - ], - "gc_plot": [ - - ], - "gc_summary": [ - [ - { - "id": "test", - "single_end": false - }, - "test_gc_summary.txt:md5,367143e0f7680555bb68173561919e5f" - ] - ], - "is_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_is_metrics.txt:md5,0ce93baa9d470f9b6344094218d74e59" - ] - ], - "is_plot": [ - - ], - "mq_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_mq_metrics.txt:md5,159ed897b11e7621703365134f60c1f7" - ] - ], - "mq_plot": [ - - ], - "qd_metrics": [ - [ - { - "id": "test", - "single_end": false - }, - "test_qd_metrics.txt:md5,fa86f2f5cc195ea48565401f68ba0730" - ] - ], - "qd_plot": [ - - ], - "versions": [ - "versions.yml:md5,aa6e267932a3f74d88a7bce286a1493a" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:22:26.909097428" + "timestamp": "2026-01-22T20:39:54.583316564" } } \ No newline at end of file diff --git a/modules/nf-core/sentieon/datametrics/tests/nextflow.config b/modules/nf-core/sentieon/datametrics/tests/nextflow.config index dead4e323..5ea3ffb66 100644 --- a/modules/nf-core/sentieon/datametrics/tests/nextflow.config +++ b/modules/nf-core/sentieon/datametrics/tests/nextflow.config @@ -1,16 +1,11 @@ env { // NOTE This is how pipeline users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how pipeline users will test out Sentieon with a license file + // NOTE This is how users will test out Sentieon in Sarek with a license file // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) } - -process { - withLabel: 'sentieon' { - ext.sentieon_auth_mech_base64 = secrets.SENTIEON_AUTH_MECH_BASE64 - ext.sentieon_auth_data_base64 = secrets.SENTIEON_AUTH_DATA_BASE64 - } -} diff --git a/modules/nf-core/sentieon/dedup/environment.yml b/modules/nf-core/sentieon/dedup/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/dedup/environment.yml +++ b/modules/nf-core/sentieon/dedup/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/dedup/main.nf b/modules/nf-core/sentieon/dedup/main.nf index 5735df734..321c0712f 100644 --- a/modules/nf-core/sentieon/dedup/main.nf +++ b/modules/nf-core/sentieon/dedup/main.nf @@ -1,12 +1,12 @@ process SENTIEON_DEDUP { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(bam), path(bai) @@ -14,14 +14,14 @@ process SENTIEON_DEDUP { tuple val(meta3), path(fasta_fai) output: - tuple val(meta), path("*.cram") , emit: cram, optional: true - tuple val(meta), path("*.crai") , emit: crai, optional: true - tuple val(meta), path("*.bam") , emit: bam , optional: true - tuple val(meta), path("*.bai") , emit: bai - tuple val(meta), path("*.score") , emit: score - tuple val(meta), path("*.metrics") , emit: metrics + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.bai"), emit: bai + tuple val(meta), path("*.score"), emit: score + tuple val(meta), path("*.metrics"), emit: metrics tuple val(meta), path("*.metrics.multiqc.tsv"), emit: metrics_multiqc_tsv - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when @@ -33,25 +33,20 @@ process SENTIEON_DEDUP { def args4 = task.ext.args4 ?: '' def prefix = task.ext.prefix ?: "${meta.id}.cram" def metrics = task.ext.metrics ?: "${prefix}.metrics" - def input_list = bam.collect{"-i $it"}.join(' ') + def input_list = bam.collect {input -> "-i ${input}" }.join(' ') def prefix_basename = prefix.substring(0, prefix.lastIndexOf(".")) - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} - sentieon driver $args -t $task.cpus $input_list -r ${fasta} --algo LocusCollector $args2 --fun score_info ${prefix_basename}.score - sentieon driver $args3 -t $task.cpus $input_list -r ${fasta} --algo Dedup $args4 --score_info ${prefix_basename}.score --metrics ${metrics} ${prefix} + sentieon driver ${args} -t ${task.cpus} ${input_list} -r ${fasta} --algo LocusCollector ${args2} --fun score_info ${prefix_basename}.score + sentieon driver ${args3} -t ${task.cpus} ${input_list} -r ${fasta} --algo Dedup ${args4} --score_info ${prefix_basename}.score --metrics ${metrics} ${prefix} # This following tsv-file is produced in order to get a proper tsv-file with Dedup-metrics for importing in MultiQC as "custom content". # It should be removed once MultiQC has a module for displaying Dedup-metrics. head -3 ${metrics} > ${metrics}.multiqc.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ stub: @@ -66,10 +61,5 @@ process SENTIEON_DEDUP { touch "${metrics}" touch "${metrics}.multiqc.tsv" touch "${prefix_basename}.score" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/dedup/meta.yml b/modules/nf-core/sentieon/dedup/meta.yml index 003d74bef..af4541ce7 100644 --- a/modules/nf-core/sentieon/dedup/meta.yml +++ b/modules/nf-core/sentieon/dedup/meta.yml @@ -27,10 +27,12 @@ input: type: file description: BAM file. pattern: "*.bam" + ontologies: [] - bai: type: file description: BAI file pattern: "*.bai" + ontologies: [] - - meta2: type: map description: | @@ -40,6 +42,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -49,9 +52,10 @@ input: type: file description: The index of the FASTA reference. pattern: "*.fai" + ontologies: [] output: - - cram: - - meta: + cram: + - - meta: type: map description: | Groovy Map containing reference information. @@ -60,8 +64,9 @@ output: type: file description: CRAM file pattern: "*.cram" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing reference information. @@ -70,8 +75,9 @@ output: type: file description: CRAM index file pattern: "*.crai" - - bam: - - meta: + ontologies: [] + bam: + - - meta: type: map description: | Groovy Map containing reference information. @@ -80,8 +86,9 @@ output: type: file description: BAM file. pattern: "*.bam" - - bai: - - meta: + ontologies: [] + bai: + - - meta: type: map description: | Groovy Map containing reference information. @@ -90,19 +97,21 @@ output: type: file description: BAI file pattern: "*.bai" - - score: - - meta: + ontologies: [] + score: + - - meta: type: map description: | Groovy Map containing reference information. e.g. [ id:'test', single_end:false ] - "*.score": type: file - description: The score file indicates which reads LocusCollector finds are likely - duplicates. + description: The score file indicates which reads LocusCollector finds are + likely duplicates. pattern: "*.score" - - metrics: - - meta: + ontologies: [] + metrics: + - - meta: type: map description: | Groovy Map containing reference information. @@ -111,8 +120,9 @@ output: type: file description: Output file containing Dedup metrics incl. histogram data. pattern: "*.metrics" - - metrics_multiqc_tsv: - - meta: + ontologies: [] + metrics_multiqc_tsv: + - - meta: type: map description: | Groovy Map containing reference information. @@ -121,11 +131,30 @@ output: type: file description: Output tsv-file containing Dedup metrics excl. histogram data. pattern: "*.metrics.multiqc.tsv" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool authors: - "@asp8200" maintainers: diff --git a/modules/nf-core/sentieon/dedup/tests/main.nf.test b/modules/nf-core/sentieon/dedup/tests/main.nf.test index c842a4a00..9e5179d61 100644 --- a/modules/nf-core/sentieon/dedup/tests/main.nf.test +++ b/modules/nf-core/sentieon/dedup/tests/main.nf.test @@ -10,10 +10,18 @@ nextflow_process { script "../main.nf" process "SENTIEON_DEDUP" - test("Test marking duplicates") { - config "./nextflow.config" + config "./nextflow.config" + + test("Test marking duplicates, bam") { when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_args4 = '' + module_prefix = "test.dedup.bam" + } process { """ input[0] = [ @@ -28,18 +36,30 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + bam(process.out.bam[0][1]).getReadsMD5(), + file(process.out.bai[0][1]).name, + path(process.out.score[0][1]).contains("SentieonCommandLine"), + path(process.out.metrics[0][1]).contains("SentieonCommandLine"), + path(process.out.metrics_multiqc_tsv[0][1]).contains("SentieonCommandLine"), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } - test("Test removing duplicates") { - config "./nextflow_rmdup.config" + test("Test removing duplicates, cram") { when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_args4 = '--rmdup' + module_prefix = "test.dedup.cram" + } process { """ input[0] = [ @@ -54,18 +74,31 @@ nextflow_process { } then { + def fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/sarscov2/genome/genome.fasta' + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + cram(process.out.cram[0][1], fasta).getReadsMD5(), + file(process.out.crai[0][1]).name, + path(process.out.score[0][1]).contains("SentieonCommandLine"), + path(process.out.metrics[0][1]).contains("SentieonCommandLine"), + path(process.out.metrics_multiqc_tsv[0][1]).contains("SentieonCommandLine"), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("Test stub") { - config "./nextflow.config" options "-stub" when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_args4 = '' + module_prefix = '' + } process { """ input[0] = [ @@ -80,11 +113,10 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } } diff --git a/modules/nf-core/sentieon/dedup/tests/main.nf.test.snap b/modules/nf-core/sentieon/dedup/tests/main.nf.test.snap index 26117a7cd..1cf940dcc 100644 --- a/modules/nf-core/sentieon/dedup/tests/main.nf.test.snap +++ b/modules/nf-core/sentieon/dedup/tests/main.nf.test.snap @@ -1,241 +1,49 @@ { - "Test marking duplicates": { + "Test removing duplicates, cram": { "content": [ + "894549ee3ced6b5ca2eed2563a985217", + "test.dedup.cram.crai", + false, + false, + false, { - "0": [ - [ - { - "id": "test" - }, - "test.cram:md5,e46e97256846338e1cff32d862105491" - ] - ], - "1": [ - [ - { - "id": "test" - }, - "test.cram.crai:md5,4b7b2152b33c5334f9477cc3650f8c91" - ] - ], - "2": [ - - ], - "3": [ - [ - { - "id": "test" - }, - "test.cram.bai:md5,889503338dc569b24e44e5e3aec815ea" - ] - ], - "4": [ - [ - { - "id": "test" - }, - "test.score:md5,835f05ecc5d3ef5d4e31ba7f831d9a8b" - ] - ], - "5": [ - [ - { - "id": "test" - }, - "test.cram.metrics:md5,208f7c5fa2f489cfaaffbce116fed0bc" - ] - ], - "6": [ - [ - { - "id": "test" - }, - "test.cram.metrics.multiqc.tsv:md5,208f7c5fa2f489cfaaffbce116fed0bc" - ] - ], - "7": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" - ], - "bai": [ - [ - { - "id": "test" - }, - "test.cram.bai:md5,889503338dc569b24e44e5e3aec815ea" - ] - ], - "bam": [ - - ], - "crai": [ - [ - { - "id": "test" - }, - "test.cram.crai:md5,4b7b2152b33c5334f9477cc3650f8c91" - ] - ], - "cram": [ - [ - { - "id": "test" - }, - "test.cram:md5,e46e97256846338e1cff32d862105491" - ] - ], - "metrics": [ + "versions_sentieon": [ [ - { - "id": "test" - }, - "test.cram.metrics:md5,208f7c5fa2f489cfaaffbce116fed0bc" + "SENTIEON_DEDUP", + "sentieon", + "202503.02" ] - ], - "metrics_multiqc_tsv": [ - [ - { - "id": "test" - }, - "test.cram.metrics.multiqc.tsv:md5,208f7c5fa2f489cfaaffbce116fed0bc" - ] - ], - "score": [ - [ - { - "id": "test" - }, - "test.score:md5,835f05ecc5d3ef5d4e31ba7f831d9a8b" - ] - ], - "versions": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:28:10.570152622" + "timestamp": "2026-01-21T11:42:11.871897434" }, - "Test removing duplicates": { + "Test marking duplicates, bam": { "content": [ + "894549ee3ced6b5ca2eed2563a985217", + "test.dedup.bam.bai", + false, + false, + false, { - "0": [ - [ - { - "id": "test" - }, - "test.cram:md5,8075d3e7c66d36fdbb81270eefc996d4" - ] - ], - "1": [ - [ - { - "id": "test" - }, - "test.cram.crai:md5,c617398ead281c1339d78d5df0d606e9" - ] - ], - "2": [ - - ], - "3": [ - [ - { - "id": "test" - }, - "test.cram.bai:md5,a1ea729eca4732ca3a5dee946a70fbc8" - ] - ], - "4": [ - [ - { - "id": "test" - }, - "test.score:md5,835f05ecc5d3ef5d4e31ba7f831d9a8b" - ] - ], - "5": [ - [ - { - "id": "test" - }, - "test.cram.metrics:md5,2a41239de0275a8321f4658286d97d65" - ] - ], - "6": [ - [ - { - "id": "test" - }, - "test.cram.metrics.multiqc.tsv:md5,2a41239de0275a8321f4658286d97d65" - ] - ], - "7": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" - ], - "bai": [ + "versions_sentieon": [ [ - { - "id": "test" - }, - "test.cram.bai:md5,a1ea729eca4732ca3a5dee946a70fbc8" - ] - ], - "bam": [ - - ], - "crai": [ - [ - { - "id": "test" - }, - "test.cram.crai:md5,c617398ead281c1339d78d5df0d606e9" - ] - ], - "cram": [ - [ - { - "id": "test" - }, - "test.cram:md5,8075d3e7c66d36fdbb81270eefc996d4" - ] - ], - "metrics": [ - [ - { - "id": "test" - }, - "test.cram.metrics:md5,2a41239de0275a8321f4658286d97d65" - ] - ], - "metrics_multiqc_tsv": [ - [ - { - "id": "test" - }, - "test.cram.metrics.multiqc.tsv:md5,2a41239de0275a8321f4658286d97d65" + "SENTIEON_DEDUP", + "sentieon", + "202503.02" ] - ], - "score": [ - [ - { - "id": "test" - }, - "test.score:md5,835f05ecc5d3ef5d4e31ba7f831d9a8b" - ] - ], - "versions": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:28:19.377946074" + "timestamp": "2026-01-21T11:41:33.04379133" }, "Test stub": { "content": [ @@ -292,7 +100,11 @@ ] ], "7": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" + [ + "SENTIEON_DEDUP", + "sentieon", + "202503.02" + ] ], "bai": [ [ @@ -345,15 +157,19 @@ "test.score:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,763463853476be96846b6da5aecfacf4" + "versions_sentieon": [ + [ + "SENTIEON_DEDUP", + "sentieon", + "202503.02" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:28:28.792696026" + "timestamp": "2026-01-19T18:07:52.331783324" } } \ No newline at end of file diff --git a/modules/nf-core/sentieon/dedup/tests/nextflow.config b/modules/nf-core/sentieon/dedup/tests/nextflow.config index 09a068ee6..a4f002090 100644 --- a/modules/nf-core/sentieon/dedup/tests/nextflow.config +++ b/modules/nf-core/sentieon/dedup/tests/nextflow.config @@ -1,9 +1,21 @@ env { // NOTE This is how nf-core/sarek users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how nf-core/sarek users will test out Sentieon in Sarek with a license file + // NOTE This is how users will test out Sentieon in Sarek with a license file // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) } + +process { + withName: 'SENTIEON_DEDUP' { + ext.args = params.module_args + ext.args2 = params.module_args2 + ext.args3 = params.module_args3 + ext.args4 = params.module_args4 + ext.prefix = params.module_prefix + } +} diff --git a/modules/nf-core/sentieon/dedup/tests/nextflow_rmdup.config b/modules/nf-core/sentieon/dedup/tests/nextflow_rmdup.config deleted file mode 100644 index 21e7b945d..000000000 --- a/modules/nf-core/sentieon/dedup/tests/nextflow_rmdup.config +++ /dev/null @@ -1,15 +0,0 @@ -env { - // NOTE This is how nf-core/sarek users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" - // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" - SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how nf-core/sarek users will test out Sentieon in Sarek with a license file - // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) -} - -process { - withName: 'SENTIEON_DEDUP' { - ext.args4 = '--rmdup' - } -} diff --git a/modules/nf-core/sentieon/dnamodelapply/environment.yml b/modules/nf-core/sentieon/dnamodelapply/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/dnamodelapply/environment.yml +++ b/modules/nf-core/sentieon/dnamodelapply/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/dnamodelapply/main.nf b/modules/nf-core/sentieon/dnamodelapply/main.nf index 85fd601b3..eed1a0fe8 100644 --- a/modules/nf-core/sentieon/dnamodelapply/main.nf +++ b/modules/nf-core/sentieon/dnamodelapply/main.nf @@ -1,12 +1,12 @@ process SENTIEON_DNAMODELAPPLY { - tag "$meta.id" + tag "${meta.id}" label 'process_high' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(vcf), path(idx) @@ -15,46 +15,37 @@ process SENTIEON_DNAMODELAPPLY { tuple val(meta4), path(ml_model) output: - tuple val(meta), path("*.vcf.gz") , emit: vcf - tuple val(meta), path("*.vcf.gz.tbi"), emit: index - path "versions.yml" , emit: versions + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val(meta), path("*.vcf.gz.tbi"), emit: tbi + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}_applied" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} sentieon driver \\ - -t $task.cpus \\ - -r $fasta \\ - $args \\ + -t ${task.cpus} \\ + -r ${fasta} \\ + ${args} \\ --algo DNAModelApply \\ - --model $ml_model \\ - -v $vcf \\ + --model ${ml_model} \\ + -v ${vcf} \\ ${prefix}.vcf.gz - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}_applied" """ - touch ${prefix}.vcf.gz + echo | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g" ) - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/dnamodelapply/meta.yml b/modules/nf-core/sentieon/dnamodelapply/meta.yml index 2505aff74..ab1d6e0fe 100644 --- a/modules/nf-core/sentieon/dnamodelapply/meta.yml +++ b/modules/nf-core/sentieon/dnamodelapply/meta.yml @@ -23,10 +23,12 @@ input: type: file description: INPUT VCF file pattern: "*.{vcf,vcf.gz}" + ontologies: [] - idx: type: file description: Index of the input VCF file pattern: "*.{tbi}" + ontologies: [] - - meta2: type: map description: | @@ -36,6 +38,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -45,6 +48,7 @@ input: type: file description: Index of the genome fasta file pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -54,9 +58,10 @@ input: type: file description: machine learning model file pattern: "*.model" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -65,8 +70,9 @@ output: type: file description: INPUT VCF file pattern: "*.{vcf,vcf.gz}" - - index: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -75,11 +81,28 @@ output: type: file description: Index of the input VCF file pattern: "*.{tbi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test b/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test new file mode 100644 index 000000000..4dbb8776e --- /dev/null +++ b/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test @@ -0,0 +1,86 @@ +nextflow_process { + + name "Test Process SENTIEON_DNAMODELAPPLY" + config "./nextflow.config" + script "../main.nf" + process "SENTIEON_DNAMODELAPPLY" + + tag "modules" + tag "modules_nfcore" + tag "sentieon" + tag "sentieon/dnascope" + tag "sentieon/dnamodelapply" + + setup { + run("SENTIEON_DNASCOPE") { + script "../../dnascope/main.nf" + + process { + """ + input[0] = [ + [id:'test',single_end:false],// meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true), + []// no intervals + ] + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],[]] + input[4] = [[:],[]] + input[5] = [[:],file("https://s3.amazonaws.com/sentieon-release/other/SentieonDNAscopeModel1.1.model", checkIfExists:true)] + input[6] = 'CONSERVATIVE' + input[7] = 'variant' + input[8] = false + """ + } + } + } + + test("apply model") { + + when { + process { + """ + input[0] = SENTIEON_DNASCOPE.out.vcf.join(SENTIEON_DNASCOPE.out.vcf_tbi) + input[1] = [[id:'test'],file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'],file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],file("https://s3.amazonaws.com/sentieon-release/other/SentieonDNAscopeModel1.1.model", checkIfExists:true)] + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf[0][1]).vcf.summary, + file(process.out.tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + + test("apply model -- stub") { + options '-stub' + when { + process { + """ + input[0] = SENTIEON_DNASCOPE.out.vcf.join(SENTIEON_DNASCOPE.out.vcf_tbi) + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],file("https://s3.amazonaws.com/sentieon-release/other/SentieonDNAscopeModel1.1.model", checkIfExists:true)] + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test.snap b/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test.snap new file mode 100644 index 000000000..884357723 --- /dev/null +++ b/modules/nf-core/sentieon/dnamodelapply/tests/main.nf.test.snap @@ -0,0 +1,92 @@ +{ + "apply model": { + "content": [ + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=5, phased=false, phasedAutodetect=false]", + "test_applied.vcf.gz.tbi", + { + "versions_sentieon": [ + [ + "SENTIEON_DNAMODELAPPLY", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T16:33:14.121445833" + }, + "apply model -- stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_applied.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_applied.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "SENTIEON_DNAMODELAPPLY", + "sentieon", + "202503.02" + ] + ], + "tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_applied.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_applied.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_DNAMODELAPPLY", + "sentieon", + "202503.02" + ] + ] + }, + { + "versions_sentieon": [ + [ + "SENTIEON_DNAMODELAPPLY", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T16:33:27.190638415" + } +} \ No newline at end of file diff --git a/modules/nf-core/sentieon/dnamodelapply/tests/nextflow.config b/modules/nf-core/sentieon/dnamodelapply/tests/nextflow.config new file mode 100644 index 000000000..9a93f5007 --- /dev/null +++ b/modules/nf-core/sentieon/dnamodelapply/tests/nextflow.config @@ -0,0 +1,11 @@ +env { + // NOTE This is how nf-core/sarek users will use Sentieon in real world use + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') + // NOTE This should only happen in GitHub actions or nf-core MegaTests + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') + SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA + // NOTE This is how users will test out Sentieon in Sarek with a license file + // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) +} diff --git a/modules/nf-core/sentieon/dnascope/environment.yml b/modules/nf-core/sentieon/dnascope/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/dnascope/environment.yml +++ b/modules/nf-core/sentieon/dnascope/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/dnascope/main.nf b/modules/nf-core/sentieon/dnascope/main.nf index bdeb62521..341264ec2 100644 --- a/modules/nf-core/sentieon/dnascope/main.nf +++ b/modules/nf-core/sentieon/dnascope/main.nf @@ -1,12 +1,12 @@ process SENTIEON_DNASCOPE { - tag "$meta.id" + tag "${meta.id}" label 'process_high' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(bam), path(bai), path(intervals) @@ -15,66 +15,71 @@ process SENTIEON_DNASCOPE { tuple val(meta4), path(dbsnp) tuple val(meta5), path(dbsnp_tbi) tuple val(meta6), path(ml_model) - val(pcr_indel_model) - val(emit_vcf) - val(emit_gvcf) + val pcr_indel_model + val emit_vcf + val emit_gvcf output: - tuple val(meta), path("*.unfiltered.vcf.gz") , optional:true, emit: vcf // added the substring ".unfiltered" in the filename of the vcf-files since without that the g.vcf.gz-files were ending up in the vcf-channel - tuple val(meta), path("*.unfiltered.vcf.gz.tbi"), optional:true, emit: vcf_tbi - tuple val(meta), path("*.g.vcf.gz") , optional:true, emit: gvcf // these output-files have to have the extension ".vcf.gz", otherwise the subsequent GATK-MergeVCFs will fail. - tuple val(meta), path("*.g.vcf.gz.tbi") , optional:true, emit: gvcf_tbi - path "versions.yml" , emit: versions + // added the substring ".unfiltered" in the filename of the vcf-files since without that the g.vcf.gz-files were ending up in the vcf-channel + tuple val(meta), path("*.unfiltered.vcf.gz"), emit: vcf, optional: true + tuple val(meta), path("*.unfiltered.vcf.gz.tbi"), emit: vcf_tbi, optional: true + // these output-files have to have the extension ".vcf.gz", otherwise the subsequent GATK-MergeVCFs will fail. + tuple val(meta), path("*.g.vcf.gz"), emit: gvcf, optional: true + tuple val(meta), path("*.g.vcf.gz.tbi"), emit: gvcf_tbi, optional: true + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' // options for the driver - def args2 = task.ext.args2 ?: '' // options for the vcf generation - def args3 = task.ext.args3 ?: '' // options for the gvcf generation - def interval = intervals ? "--interval ${intervals}" : '' - def dbsnp_cmd = dbsnp ? "-d ${dbsnp}" : '' - def model_cmd = ml_model ? " --model ${ml_model}" : '' - def pcr_indel_model_cmd = pcr_indel_model ? " --pcr_indel_model ${pcr_indel_model}" : '' - def prefix = task.ext.prefix ?: "${meta.id}" - def vcf_cmd = "" - def gvcf_cmd = "" - def base_cmd = '--algo DNAscope ' + dbsnp_cmd + ' ' + def args = task.ext.args ?: '' + // options for the driver + def args2 = task.ext.args2 ?: '' + // options for the vcf generation + def args3 = task.ext.args3 ?: '' + // options for the gvcf generation + def interval = intervals ? "--interval ${intervals}" : '' + def dbsnp_cmd = dbsnp ? "-d ${dbsnp}" : '' + def model_cmd = ml_model ? " --model ${ml_model}" : '' + def pcr_indel_model_cmd = pcr_indel_model ? " --pcr_indel_model ${pcr_indel_model}" : '' + def prefix = task.ext.prefix ?: "${meta.id}" + def vcf_cmd = "" + def gvcf_cmd = "" + def base_cmd = '--algo DNAscope ' + dbsnp_cmd + ' ' - if (emit_vcf) { // emit_vcf can be the empty string, 'variant', 'confident' or 'all' but NOT 'gvcf' + if (emit_vcf) { + // emit_vcf can be the empty string, 'variant', 'confident' or 'all' but NOT 'gvcf' vcf_cmd = base_cmd + args2 + ' ' + model_cmd + pcr_indel_model_cmd + ' --emit_mode ' + emit_vcf + ' ' + prefix + '.unfiltered.vcf.gz' } - if (emit_gvcf) { // emit_gvcf can be either true or false + if (emit_gvcf) { + // emit_gvcf can be either true or false gvcf_cmd = base_cmd + args3 + ' ' + model_cmd + pcr_indel_model_cmd + ' --emit_mode gvcf ' + prefix + '.g.vcf.gz' } - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense - - sentieon driver $args -r $fasta -t $task.cpus -i $bam $interval $vcf_cmd $gvcf_cmd + ${sentieonLicense} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS + sentieon driver \\ + ${args} \\ + -r ${fasta} \\ + -t ${task.cpus} \\ + -i ${bam} \\ + ${interval} \\ + ${vcf_cmd} \\ + ${gvcf_cmd} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" + def gvcf_cmd = emit_gvcf ? "echo | gzip > ${prefix}.g.vcf.gz; touch ${prefix}.g.vcf.gz.tbi" : "" + """ - touch ${prefix}.unfiltered.vcf.gz + echo | gzip > ${prefix}.unfiltered.vcf.gz touch ${prefix}.unfiltered.vcf.gz.tbi - touch ${prefix}.g.vcf.gz - touch ${prefix}.g.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g" ) - END_VERSIONS + ${gvcf_cmd} """ } diff --git a/modules/nf-core/sentieon/dnascope/meta.yml b/modules/nf-core/sentieon/dnascope/meta.yml index e3e0eba8c..e499927da 100644 --- a/modules/nf-core/sentieon/dnascope/meta.yml +++ b/modules/nf-core/sentieon/dnascope/meta.yml @@ -23,15 +23,18 @@ input: type: file description: BAM file. pattern: "*.bam" + ontologies: [] - bai: type: file description: BAI file pattern: "*.bai" + ontologies: [] - intervals: type: file description: bed or interval_list file containing interval in the reference that will be used in the analysis pattern: "*.{bed,interval_list}" + ontologies: [] - - meta2: type: map description: | @@ -40,6 +43,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -48,6 +52,7 @@ input: type: file description: Index of the genome fasta file pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -56,6 +61,8 @@ input: type: file description: Single Nucleotide Polymorphism database (dbSNP) file pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format - - meta5: type: map description: | @@ -64,6 +71,7 @@ input: type: file description: Index of the Single Nucleotide Polymorphism database (dbSNP) file pattern: "*.vcf.gz.tbi" + ontologies: [] - - meta6: type: map description: | @@ -72,24 +80,25 @@ input: type: file description: machine learning model file pattern: "*.model" - - - pcr_indel_model: - type: string - description: | - Controls the option pcr_indel_model for Dnascope. - The possible options are "NONE" (used for PCR free samples), and "HOSTILE", "AGGRESSIVE" and "CONSERVATIVE". - See Sentieons documentation for further explanation. - - - emit_vcf: - type: string - description: | - Controls the vcf output from Dnascope. - Possible options are "all", "confident" and "variant". - See Sentieons documentation for further explanation. - - - emit_gvcf: - type: boolean - description: If true, the haplotyper will output a gvcf + ontologies: [] + - pcr_indel_model: + type: string + description: | + Controls the option pcr_indel_model for Dnascope. + The possible options are "NONE" (used for PCR free samples), and "HOSTILE", "AGGRESSIVE" and "CONSERVATIVE". + See Sentieons documentation for further explanation. + - emit_vcf: + type: string + description: | + Controls the vcf output from Dnascope. + Possible options are "all", "confident" and "variant". + See Sentieons documentation for further explanation. + - emit_gvcf: + type: boolean + description: If true, the haplotyper will output a gvcf output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing reference information. @@ -98,8 +107,10 @@ output: type: file description: Compressed VCF file pattern: "*.unfiltered.vcf.gz" - - vcf_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + vcf_tbi: + - - meta: type: map description: | Groovy Map containing reference information. @@ -108,8 +119,9 @@ output: type: file description: Index of VCF file pattern: "*.unfiltered.vcf.gz.tbi" - - gvcf: - - meta: + ontologies: [] + gvcf: + - - meta: type: map description: | Groovy Map containing reference information. @@ -118,8 +130,10 @@ output: type: file description: Compressed GVCF file pattern: "*.g.vcf.gz" - - gvcf_tbi: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + gvcf_tbi: + - - meta: type: map description: | Groovy Map containing reference information. @@ -128,11 +142,28 @@ output: type: file description: Index of GVCF file pattern: "*.g.vcf.gz.tbi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/sentieon/dnascope/tests/main.nf.test b/modules/nf-core/sentieon/dnascope/tests/main.nf.test new file mode 100644 index 000000000..0d4dc14b5 --- /dev/null +++ b/modules/nf-core/sentieon/dnascope/tests/main.nf.test @@ -0,0 +1,176 @@ +nextflow_process { + + name "Test Process SENTIEON_DNASCOPE" + config "./nextflow.config" + script "../main.nf" + process "SENTIEON_DNASCOPE" + + tag "modules" + tag "modules_nfcore" + tag "sentieon" + tag "sentieon/dnascope" + config './nextflow.config' + + test("conservative indel model - variant") { + + when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_prefix = '' + } + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true), + []// no intervals + ] + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],[]] + input[4] = [[:],[]] + input[5] = [[:],file("https://s3.amazonaws.com/sentieon-release/other/SentieonDNAscopeModel1.0.model", checkIfExists: true)] + input[6] = 'CONSERVATIVE' + input[7] = 'variant' + input[8] = false + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf[0][1]).vcf.summary, + file(process.out.vcf_tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + + test("conservative indel model - all") { + + when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_prefix = '' + } + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true), + []// no intervals + ] + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],[]] + input[4] = [[:],[]] + input[5] = [[:],file("https://s3.amazonaws.com/sentieon-release/other/SentieonDNAscopeModel1.0.model", checkIfExists: true)] + input[6] = 'AGGRESSIVE' + input[7] = 'all' + input[8] = false + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf[0][1]).vcf.summary, + file(process.out.vcf_tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + + test("hostile indel model - confident") { + + when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_prefix = '' + } + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true), + []// no intervals + ] + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],[]] + input[4] = [[:],[]] + input[5] = [[:],[]] + input[6] = 'HOSTILE' + input[7] = 'confident' + input[8] = true + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + path(process.out.vcf[0][1]).vcf.summary, + file(process.out.vcf_tbi[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + + test("conversative indel model - variant - stub") { + options '-stub' + when { + params { + module_args = '' + module_args2 = '' + module_args3 = '' + module_prefix = '' + } + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true), + []// no intervals + ] + input[1] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)] + input[2] = [[id:'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists:true)] + input[3] = [[:],[]] + input[4] = [[:],[]] + input[5] = [[:],[]] + input[6] = 'CONSERVATIVE' + input[7] = 'variant' + input[8] = false + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } + ) + } + } +} diff --git a/modules/nf-core/sentieon/dnascope/tests/main.nf.test.snap b/modules/nf-core/sentieon/dnascope/tests/main.nf.test.snap new file mode 100644 index 000000000..c3522735b --- /dev/null +++ b/modules/nf-core/sentieon/dnascope/tests/main.nf.test.snap @@ -0,0 +1,140 @@ +{ + "hostile indel model - confident": { + "content": [ + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=5, phased=false, phasedAutodetect=false]", + "test.unfiltered.vcf.gz.tbi", + { + "versions_sentieon": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-22T06:46:27.438392862" + }, + "conservative indel model - variant": { + "content": [ + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=5, phased=false, phasedAutodetect=false]", + "test.unfiltered.vcf.gz.tbi", + { + "versions_sentieon": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-22T06:46:06.432231055" + }, + "conversative indel model - variant - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.unfiltered.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.unfiltered.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ], + "gvcf": [ + + ], + "gvcf_tbi": [ + + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.unfiltered.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test" + }, + "test.unfiltered.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ] + }, + { + "versions_sentieon": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-22T06:46:35.277276222" + }, + "conservative indel model - all": { + "content": [ + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=8, phased=false, phasedAutodetect=false]", + "test.unfiltered.vcf.gz.tbi", + { + "versions_sentieon": [ + [ + "SENTIEON_DNASCOPE", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-22T06:46:18.796510157" + } +} \ No newline at end of file diff --git a/modules/nf-core/sentieon/dnascope/tests/nextflow.config b/modules/nf-core/sentieon/dnascope/tests/nextflow.config new file mode 100644 index 000000000..582cf60ff --- /dev/null +++ b/modules/nf-core/sentieon/dnascope/tests/nextflow.config @@ -0,0 +1,20 @@ +env { + // NOTE This is how nf-core/sarek users will use Sentieon in real world use + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') + // NOTE This should only happen in GitHub actions or nf-core MegaTests + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') + SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA + // NOTE This is how users will test out Sentieon in Sarek with a license file + // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) +} + +process { + withName: 'SENTIEON_DNASCOPE' { + ext.args = params.module_args + ext.args2 = params.module_args2 + ext.args3 = params.module_args3 + ext.prefix = params.module_prefix ?: null + } +} diff --git a/modules/nf-core/sentieon/readwriter/environment.yml b/modules/nf-core/sentieon/readwriter/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/readwriter/environment.yml +++ b/modules/nf-core/sentieon/readwriter/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/readwriter/main.nf b/modules/nf-core/sentieon/readwriter/main.nf index 7e00b9e98..1a59eba88 100644 --- a/modules/nf-core/sentieon/readwriter/main.nf +++ b/modules/nf-core/sentieon/readwriter/main.nf @@ -1,12 +1,12 @@ process SENTIEON_READWRITER { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(input), path(index) @@ -17,7 +17,7 @@ process SENTIEON_READWRITER { tuple val(meta), path("${prefix}"), emit: output tuple val(meta), path("${prefix}.${index}"), emit: index tuple val(meta), path("${prefix}"), path("${prefix}.${index}"), emit: output_index - path "versions.yml", emit: versions + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when @@ -25,50 +25,42 @@ process SENTIEON_READWRITER { script: - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def input_str = input.sort{ it.getName() }.collect{"-i $it"}.join(' ') - def reference = fasta ? "-r $fasta" : '' + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def input_str = input.sort {in -> in.getName() }.collect {in -> "-i ${in}" }.join(' ') + def reference = fasta ? "-r ${fasta}" : '' // bam -> bam: prefix = ".bam" // bam -> cram: prefix = ".cram" // cram -> cram: prefix = ".cram" - prefix = task.ext.prefix ?: "${meta.id}.bam" - index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" + prefix = task.ext.prefix ?: "${meta.id}.bam" + index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} sentieon \\ driver \\ - -t $task.cpus \\ - $reference \\ - $args \\ - $input_str \\ + -t ${task.cpus} \\ + ${reference} \\ + ${args} \\ + ${input_str} \\ --algo ReadWriter \\ - $args2 \\ + ${args2} \\ ${prefix} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ stub: - prefix = task.ext.prefix ?: "${meta.id}.cram" - index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" + prefix = task.ext.prefix ?: "${meta.id}.cram" + index = prefix.tokenize('.')[-1] == "bam" ? "bai" : "crai" """ touch ${prefix} touch ${prefix}.${index} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/readwriter/meta.yml b/modules/nf-core/sentieon/readwriter/meta.yml index 6e79ea190..42373bdd9 100644 --- a/modules/nf-core/sentieon/readwriter/meta.yml +++ b/modules/nf-core/sentieon/readwriter/meta.yml @@ -24,10 +24,12 @@ input: type: file description: BAM/CRAM file. pattern: "*.{bam,cram}" + ontologies: [] - index: type: file description: BAI/CRAI file. pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -37,6 +39,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -46,9 +49,10 @@ input: type: file description: The index of the FASTA reference. pattern: "*.fai" + ontologies: [] output: - - output: - - meta: + output: + - - meta: type: map description: | Groovy Map containing reference information. @@ -58,8 +62,9 @@ output: description: BAM/CRAM file. Depends on how ext.prefix is set. BAM "ext.prefix = .bam", CRAM "ext.prefix = .cram". Defaults to cram pattern: "*.{bam,cram}" - - index: - - meta: + ontologies: [] + index: + - - meta: type: map description: | Groovy Map containing reference information. @@ -68,23 +73,45 @@ output: type: file description: BAM/CRAM index file pattern: "*.{bai,crai}" - - output_index: - - meta: + ontologies: [] + output_index: + - - meta: type: map description: | Groovy Map containing reference information. e.g. [ id:'test', single_end:false ] - ${prefix}: type: file - description: BAM/CRAM alignment and the corresponding index file + description: BAM/CRAM file. Depends on how ext.prefix is set. BAM "ext.prefix + = .bam", CRAM "ext.prefix = .cram". Defaults to cram + pattern: "*.{bam,cram}" + ontologies: [] - ${prefix}.${index}: type: file - description: BAM/CRAM alignment and the corresponding index file - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + description: BAM/CRAM index file + pattern: "*.{bai,crai}" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - sentieon driver --version | sed "s/.*-//g": + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/sentieon/readwriter/tests/main.nf.test b/modules/nf-core/sentieon/readwriter/tests/main.nf.test index 9a787b44c..ec341879d 100644 --- a/modules/nf-core/sentieon/readwriter/tests/main.nf.test +++ b/modules/nf-core/sentieon/readwriter/tests/main.nf.test @@ -4,15 +4,18 @@ nextflow_process { script "../main.nf" process "SENTIEON_READWRITER" + config "./nextflow.config" tag "modules" tag "modules_nfcore" tag "sentieon" tag "sentieon/readwriter" test("merge bam") { - config "./nextflow.config" when { + params { + module_prefix = '' + } process { """ input[0] = [ [id: 'test' ], @@ -26,22 +29,22 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - bam(process.out.output[0][1], stringency: "lenient").getReadsMD5(), - file(process.out.index.get(0).get(1)).name, - process.out.versions - ).match() } - + bam(process.out.output[0][1], stringency: "lenient").getReadsMD5(), + file(process.out.index.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("cram") { - config "./nextflow_outputcram.config" when { + params { + module_prefix = 'test.cram' + } process { """ input[0] = [ [id: 'test', fasta: params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta' ], @@ -55,22 +58,23 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - bam(process.out.output[0][1], process.out.output[0][0].fasta).getReadsMD5(), - file(process.out.index.get(0).get(1)).name, - process.out.versions - ).match() } - + bam(process.out.output[0][1], process.out.output[0][0].fasta).getReadsMD5(), + file(process.out.index.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } test("merging - output bam") { - config "./nextflow.config" when { + params { + module_prefix = '' + } process { """ input[0] = [ [id: 'test' ], @@ -90,23 +94,23 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - bam(process.out.output[0][1], stringency: "lenient").getReadsMD5(), - file(process.out.index.get(0).get(1)).name, - process.out.versions - ).match() } - + bam(process.out.output[0][1], stringency: "lenient").getReadsMD5(), + file(process.out.index.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("merging - output bam to cram") { - config "./nextflow_outputcram.config" when { + params { + module_prefix = 'test.cram' + } process { """ input[0] = [ [id: 'test', fasta: params.modules_testdata_base_path + '/genomics/sarscov2/genome/genome.fasta' ], @@ -126,24 +130,24 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot( - bam(process.out.output[0][1], process.out.output[0][0].fasta).getReadsMD5(), - file(process.out.index.get(0).get(1)).name, - process.out.versions - ).match() } - + bam(process.out.output[0][1], process.out.output[0][0].fasta).getReadsMD5(), + file(process.out.index.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } test("sentieon readwriter - stub") { options "-stub" - config "./nextflow.config" when { + params { + module_prefix = '' + } process { """ input[0] = [ [id: 'test' ], @@ -157,12 +161,10 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/sentieon/readwriter/tests/main.nf.test.snap b/modules/nf-core/sentieon/readwriter/tests/main.nf.test.snap index 0af607892..ba6695c00 100644 --- a/modules/nf-core/sentieon/readwriter/tests/main.nf.test.snap +++ b/modules/nf-core/sentieon/readwriter/tests/main.nf.test.snap @@ -3,57 +3,81 @@ "content": [ "2f11e4fe3390b8ad0a1852616fd1da04", "test.bam.bai", - [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" - ] + { + "versions_sentieon": [ + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:32:10.696224516" + "timestamp": "2026-01-22T06:50:06.653644023" }, "cram": { "content": [ "2f11e4fe3390b8ad0a1852616fd1da04", "test.cram.crai", - [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" - ] + { + "versions_sentieon": [ + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:32:23.080911465" + "timestamp": "2026-01-22T06:50:15.682983539" }, "merging - output bam": { "content": [ "ed89d81d2d6adafdbb819a1a4ec86493", "test.bam.bai", - [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" - ] + { + "versions_sentieon": [ + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:32:36.741074568" + "timestamp": "2026-01-22T06:50:24.255987992" }, "merging - output bam to cram": { "content": [ "ed89d81d2d6adafdbb819a1a4ec86493", "test.cram.crai", - [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" - ] + { + "versions_sentieon": [ + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:33:50.523887508" + "timestamp": "2026-01-22T06:50:34.625552047" }, "sentieon readwriter - stub": { "content": [ @@ -84,7 +108,11 @@ ] ], "3": [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] ], "index": [ [ @@ -111,15 +139,19 @@ "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,914cac5a1fad066362698afc9419ecb2" + "versions_sentieon": [ + [ + "SENTIEON_READWRITER", + "sentieon", + "202503.02" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-10-02T10:34:00.856232997" + "timestamp": "2026-01-22T06:50:41.960295919" } } \ No newline at end of file diff --git a/modules/nf-core/sentieon/readwriter/tests/nextflow.config b/modules/nf-core/sentieon/readwriter/tests/nextflow.config index c1e9e4864..bb68b37fe 100644 --- a/modules/nf-core/sentieon/readwriter/tests/nextflow.config +++ b/modules/nf-core/sentieon/readwriter/tests/nextflow.config @@ -1,9 +1,17 @@ env { // NOTE This is how pipeline users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how pipeline users will test out Sentieon with a license file + // NOTE This is how users will test out Sentieon in Sarek with a license file // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) } + +process { + withName: 'SENTIEON_READWRITER' { + ext.prefix = params.module_prefix + } +} diff --git a/modules/nf-core/sentieon/readwriter/tests/nextflow_outputcram.config b/modules/nf-core/sentieon/readwriter/tests/nextflow_outputcram.config deleted file mode 100644 index 56c30c265..000000000 --- a/modules/nf-core/sentieon/readwriter/tests/nextflow_outputcram.config +++ /dev/null @@ -1,16 +0,0 @@ -env { - // NOTE This is how pipeline users will use Sentieon in real world use - SENTIEON_LICENSE = "$SENTIEON_LICSRVR_IP" - // NOTE This should only happen in GitHub actions or nf-core MegaTests - SENTIEON_AUTH_MECH = "$SENTIEON_AUTH_MECH" - SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA - // NOTE This is how pipeline users will test out Sentieon with a license file - // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) -} - - -process { - withName: "SENTIEON_READWRITER" { - ext.prefix = { "${meta.id}.cram" } - } -} diff --git a/modules/nf-core/sentieon/wgsmetrics/environment.yml b/modules/nf-core/sentieon/wgsmetrics/environment.yml index d7abf668e..6b8bb5232 100644 --- a/modules/nf-core/sentieon/wgsmetrics/environment.yml +++ b/modules/nf-core/sentieon/wgsmetrics/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::sentieon=202308.03 + - bioconda::sentieon=202503.02 diff --git a/modules/nf-core/sentieon/wgsmetrics/main.nf b/modules/nf-core/sentieon/wgsmetrics/main.nf index 9f268f5a8..d0a641c13 100644 --- a/modules/nf-core/sentieon/wgsmetrics/main.nf +++ b/modules/nf-core/sentieon/wgsmetrics/main.nf @@ -1,12 +1,12 @@ process SENTIEON_WGSMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' label 'sentieon' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a6/a64461f38d76bebea8e21441079e76e663e1168b0c59dafee6ee58440ad8c8ac/data' : - 'community.wave.seqera.io/library/sentieon:202308.03--59589f002351c221' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/73/73e9111552beb76e2ad3ad89eb75bed162d7c5b85b2433723ecb4fc96a02674a/data' + : 'community.wave.seqera.io/library/sentieon:202503.02--def60555294d04fa'}" input: tuple val(meta), path(bam), path(bai) @@ -16,45 +16,36 @@ process SENTIEON_WGSMETRICS { output: tuple val(meta), path('*.txt'), emit: wgs_metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('sentieon'), eval('sentieon driver --version | sed "s/.*-//g"'), topic: versions, emit: versions_sentieon when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def input = bam.sort().collect{"-i $it"}.join(' ') - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def interval = intervals_list ? "--interval ${intervals_list}" : "" - def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 ? - "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " : - "" + def input = bam.sort().collect {in -> "-i ${in}" }.join(' ') + def sentieonLicense = secrets.SENTIEON_LICENSE_BASE64 + ? "export SENTIEON_LICENSE=\$(mktemp);echo -e \"${secrets.SENTIEON_LICENSE_BASE64}\" | base64 -d > \$SENTIEON_LICENSE; " + : "" """ - $sentieonLicense + ${sentieonLicense} sentieon \\ driver \\ - -t $task.cpus \\ - -r $fasta \\ - $input \\ - $interval \\ - $args \\ - --algo WgsMetricsAlgo ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS + -t ${task.cpus} \\ + -r ${fasta} \\ + ${input} \\ + ${interval} \\ + ${args} \\ + --algo WgsMetricsAlgo \\ + ${prefix}.txt """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sentieon: \$(echo \$(sentieon driver --version 2>&1) | sed -e "s/sentieon-genomics-//g") - END_VERSIONS """ } diff --git a/modules/nf-core/sentieon/wgsmetrics/meta.yml b/modules/nf-core/sentieon/wgsmetrics/meta.yml index a8b647277..588246fab 100644 --- a/modules/nf-core/sentieon/wgsmetrics/meta.yml +++ b/modules/nf-core/sentieon/wgsmetrics/meta.yml @@ -22,10 +22,12 @@ input: type: file description: Sorted BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Index of th sorted BAM/CRAM/SAM file pattern: "*.{bai,crai,sai}" + ontologies: [] - - meta2: type: map description: | @@ -35,6 +37,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta}" + ontologies: [] - - meta3: type: map description: | @@ -44,6 +47,7 @@ input: type: file description: Index of the genome fasta file pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | @@ -52,24 +56,43 @@ input: - intervals_list: type: file description: intervals + ontologies: [] output: - - wgs_metrics: - - meta: + wgs_metrics: + - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'test', single_end:false ]` - "*.txt": type: file - description: File containing the information about mean base quality score for - each sequencing cycle + description: File containing the information about mean base quality score + for each sequencing cycle pattern: "*.txt" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_sentieon: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: - "@ramprasadn" + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - sentieon: + type: string + description: The tool name + - 'sentieon driver --version | sed "s/.*-//g"': + type: string + description: The command used to generate the version of the tool diff --git a/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test b/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test new file mode 100644 index 000000000..08179fb21 --- /dev/null +++ b/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test @@ -0,0 +1,78 @@ +nextflow_process { + + name "Test Process SENTIEON_WGSMETRICS" + config "./nextflow.config" + script "../main.nf" + process "SENTIEON_WGSMETRICS" + + tag "modules" + tag "modules_nfcore" + tag "sentieon" + tag "sentieon/wgsmetrics" + + test("sarscov2 - bam") { + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) + ] + input[3] = [[:],[]] + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.wgs_metrics[0][1]).readLines()[1..5], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sarscov2 - bam -- stub") { + options '-stub' + when { + params { + module_args = '' + } + process { + """ + input[0] = [ + [id:'test',single_end:false],// meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists:true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) + ] + input[3] = [[:],[]] + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test.snap b/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test.snap new file mode 100644 index 000000000..0c10cc9d0 --- /dev/null +++ b/modules/nf-core/sentieon/wgsmetrics/tests/main.nf.test.snap @@ -0,0 +1,70 @@ +{ + "sarscov2 - bam -- stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "SENTIEON_WGSMETRICS", + "sentieon", + "202503.02" + ] + ], + "versions_sentieon": [ + [ + "SENTIEON_WGSMETRICS", + "sentieon", + "202503.02" + ] + ], + "wgs_metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T09:28:12.500084203" + }, + "sarscov2 - bam": { + "content": [ + [ + "GENOME_TERRITORY\tMEAN_COVERAGE\tSD_COVERAGE\tMEDIAN_COVERAGE\tMAD_COVERAGE\tPCT_EXC_MAPQ\tPCT_EXC_DUPE\tPCT_EXC_UNPAIRED\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_CAPPED\tPCT_EXC_TOTAL\tPCT_1X\tPCT_5X\tPCT_10X\tPCT_15X\tPCT_20X\tPCT_25X\tPCT_30X\tPCT_40X\tPCT_50X\tPCT_60X\tPCT_70X\tPCT_80X\tPCT_90X\tPCT_100X\tHET_SNP_SENSITIVITY\tHET_SNP_Q\t", + "29829\t0.63086\t0.94268\t0\t0\t0.0054378\t0\t0.013649\t0.063246\t0.2309\t0\t0.31324\t0.41151\t0.0051963\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0.17212\t1\t", + "", + "coverage\thigh_quality_coverage_count\t", + "0\t17554" + ], + { + "versions_sentieon": [ + [ + "SENTIEON_WGSMETRICS", + "sentieon", + "202503.02" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-21T09:37:25.493486027" + } +} \ No newline at end of file diff --git a/modules/nf-core/sentieon/wgsmetrics/tests/nextflow.config b/modules/nf-core/sentieon/wgsmetrics/tests/nextflow.config new file mode 100644 index 000000000..9a93f5007 --- /dev/null +++ b/modules/nf-core/sentieon/wgsmetrics/tests/nextflow.config @@ -0,0 +1,11 @@ +env { + // NOTE This is how nf-core/sarek users will use Sentieon in real world use + // TODO: Update to `env('SENTIEON_LICSRVR_IP')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') + // NOTE This should only happen in GitHub actions or nf-core MegaTests + // TODO: Update to `env('SENTIEON_AUTH_MECH')` when minimum Nextflow version is >= 26.04.0 + SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') + SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA + // NOTE This is how users will test out Sentieon in Sarek with a license file + // nextflow secrets set SENTIEON_LICENSE_BASE64 \$(cat | base64 -w 0) +} diff --git a/modules/nf-core/seqtk/sample/environment.yml b/modules/nf-core/seqtk/sample/environment.yml new file mode 100644 index 000000000..b1d11cbd2 --- /dev/null +++ b/modules/nf-core/seqtk/sample/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::seqtk=1.4 diff --git a/modules/nf-core/seqtk/sample/main.nf b/modules/nf-core/seqtk/sample/main.nf new file mode 100644 index 000000000..1a5d8cd72 --- /dev/null +++ b/modules/nf-core/seqtk/sample/main.nf @@ -0,0 +1,48 @@ +process SEQTK_SAMPLE { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/seqtk:1.4--he4a0461_1' : + 'biocontainers/seqtk:1.4--he4a0461_1' }" + + input: + tuple val(meta), path(reads), val(sample_size) + + output: + tuple val(meta), path("*.fastq.gz"), emit: reads + tuple val("${task.process}"), val('seqtk'), eval("seqtk 2>&1 | sed -n 's/^Version: //p'"), emit: versions_seqtk, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + if (!(args ==~ /.*\ -s\ ?[0-9]+.*/)) { + args += " -s100" + } + if ( !sample_size ) { + error "SEQTK/SAMPLE must have a sample_size value included" + } + """ + printf "%s\\n" $reads | while read f; + do + seqtk \\ + sample \\ + $args \\ + \$f \\ + $sample_size \\ + | gzip --no-name > ${prefix}_\$(basename \$f) + done + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + echo "" | gzip > ${prefix}.fastq.gz + """ + +} diff --git a/modules/nf-core/seqtk/sample/meta.yml b/modules/nf-core/seqtk/sample/meta.yml new file mode 100644 index 000000000..9574c705c --- /dev/null +++ b/modules/nf-core/seqtk/sample/meta.yml @@ -0,0 +1,70 @@ +name: seqtk_sample +description: Subsample reads from FASTQ files +keywords: + - sample + - fastx + - reads +tools: + - seqtk: + description: Seqtk is a fast and lightweight tool for processing sequences + in the FASTA or FASTQ format. Seqtk sample command subsamples sequences. + homepage: https://github.com/lh3/seqtk + documentation: https://docs.csc.fi/apps/seqtk/ + tool_dev_url: https://github.com/lh3/seqtk + licence: ["MIT"] + identifier: biotools:seqtk +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: List of input FastQ files + pattern: "*.{fastq.gz}" + ontologies: [] + - sample_size: + type: float + description: Fraction (<1.0) or number (>=1) of reads to sample. +output: + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fastq.gz": + type: file + description: Subsampled FastQ files + pattern: "*.{fastq.gz}" + ontologies: [] + versions_seqtk: + - - ${task.process}: + type: string + description: The name of the process + - seqtk: + type: string + description: The name of the tool + - "seqtk 2>&1 | sed -n 's/^Version: //p'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - seqtk: + type: string + description: The name of the tool + - "seqtk 2>&1 | sed -n 's/^Version: //p'": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@kaurravneet4123" + - "@sidorov-si" + - "@adamrtalbot" +maintainers: + - "@kaurravneet4123" + - "@sidorov-si" + - "@adamrtalbot" diff --git a/modules/nf-core/seqtk/sample/tests/main.nf.test b/modules/nf-core/seqtk/sample/tests/main.nf.test new file mode 100644 index 000000000..2152ecd41 --- /dev/null +++ b/modules/nf-core/seqtk/sample/tests/main.nf.test @@ -0,0 +1,102 @@ +nextflow_process { + + name "Test Process SEQTK_SAMPLE" + script "modules/nf-core/seqtk/sample/main.nf" + process "SEQTK_SAMPLE" + config "./standard.config" + + tag "modules" + tag "modules_nfcore" + tag "seqtk" + tag "seqtk/sample" + + test("sarscov2_sample_singleend_fqgz") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + 50 + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2_sample_pairedend_fqgz") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + 50 + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2_sample_singlend_fqgz_stub") { + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + 50 + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2_sample_singleend_frac") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + 0.5 + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/seqtk/sample/tests/main.nf.test.snap b/modules/nf-core/seqtk/sample/tests/main.nf.test.snap new file mode 100644 index 000000000..c770b22e1 --- /dev/null +++ b/modules/nf-core/seqtk/sample/tests/main.nf.test.snap @@ -0,0 +1,174 @@ +{ + "sarscov2_sample_singlend_fqgz_stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_seqtk": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-14T12:29:11.92830069" + }, + "sarscov2_sample_pairedend_fqgz": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,e5f44fafd7351c5abb9925a075132941" + ] + ], + "1": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,e5f44fafd7351c5abb9925a075132941" + ] + ], + "versions_seqtk": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-14T12:29:00.582612488" + }, + "sarscov2_sample_singleend_fqgz": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,e5f44fafd7351c5abb9925a075132941" + ] + ], + "1": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,e5f44fafd7351c5abb9925a075132941" + ] + ], + "versions_seqtk": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-14T12:28:47.676166475" + }, + "sarscov2_sample_singleend_frac": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,7552511dcd914f5183d80fae459bf917" + ] + ], + "1": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sampled_test_1.fastq.gz:md5,7552511dcd914f5183d80fae459bf917" + ] + ], + "versions_seqtk": [ + [ + "SEQTK_SAMPLE", + "seqtk", + "1.4-r122" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-14T12:29:23.3474291" + } +} \ No newline at end of file diff --git a/modules/nf-core/seqtk/sample/tests/standard.config b/modules/nf-core/seqtk/sample/tests/standard.config new file mode 100644 index 000000000..8d1db62fd --- /dev/null +++ b/modules/nf-core/seqtk/sample/tests/standard.config @@ -0,0 +1,6 @@ +process { + withName: SEQTK_SAMPLE { + ext.args = '-s100' + ext.prefix = { "${meta.id}.sampled" } + } +} diff --git a/modules/nf-core/smncopynumbercaller/environment.yml b/modules/nf-core/smncopynumbercaller/environment.yml index afbc40076..6102e6333 100644 --- a/modules/nf-core/smncopynumbercaller/environment.yml +++ b/modules/nf-core/smncopynumbercaller/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/smncopynumbercaller/main.nf b/modules/nf-core/smncopynumbercaller/main.nf index efe0a639e..6fa8811f0 100644 --- a/modules/nf-core/smncopynumbercaller/main.nf +++ b/modules/nf-core/smncopynumbercaller/main.nf @@ -13,7 +13,8 @@ process SMNCOPYNUMBERCALLER { output: tuple val(meta), path("out/*.tsv"), emit: smncopynumber tuple val(meta), path("out/*.json"), emit: run_metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('smncopynumbercaller'), val('1.1.2'), topic: versions, emit: versions_smncopynumbercaller + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. when: task.ext.when == null || task.ext.when @@ -21,7 +22,6 @@ process SMNCOPYNUMBERCALLER { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.1.2" // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. """ echo $bam | tr ' ' ' ' > manifest.txt @@ -31,24 +31,13 @@ process SMNCOPYNUMBERCALLER { --prefix $prefix \\ --outDir "out" \\ --threads $task.cpus - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - SMNCopyNumberCaller: $VERSION - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = "1.1.2" """ mkdir out touch out/${prefix}.tsv touch out/${prefix}.json - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - SMNCopyNumberCaller: $VERSION - END_VERSIONS """ } diff --git a/modules/nf-core/smncopynumbercaller/meta.yml b/modules/nf-core/smncopynumbercaller/meta.yml index 9d91fc096..c0f4078bf 100644 --- a/modules/nf-core/smncopynumbercaller/meta.yml +++ b/modules/nf-core/smncopynumbercaller/meta.yml @@ -27,13 +27,15 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - bai: type: file description: BAM/CRAM index file pattern: "*.{bai,crai}" + ontologies: [] output: - - smncopynumber: - - meta: + smncopynumber: + - - meta: type: map description: | Groovy Map containing sample information @@ -42,8 +44,10 @@ output: type: file description: File containing the output of SMNCopyNumberCaller pattern: "*.{tsv}" - - run_metrics: - - meta: + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + run_metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -52,11 +56,29 @@ output: type: file description: File containing run parameters of SMNCopyNumberCaller pattern: "*.{json}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + versions_smncopynumbercaller: + - - ${task.process}: + type: string + description: The name of the process + - smncopynumbercaller: + type: string + description: The name of the tool + - 1.1.2: + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - smncopynumbercaller: + type: string + description: The name of the tool + - 1.1.2: + type: string + description: The expression to obtain the version of the tool authors: - "@peterpru" maintainers: diff --git a/modules/nf-core/smncopynumbercaller/tests/main.nf.test.snap b/modules/nf-core/smncopynumbercaller/tests/main.nf.test.snap index 834fe67b9..22c1f1fc8 100644 --- a/modules/nf-core/smncopynumbercaller/tests/main.nf.test.snap +++ b/modules/nf-core/smncopynumbercaller/tests/main.nf.test.snap @@ -19,7 +19,11 @@ ] ], "2": [ - "versions.yml:md5,084e44557eacbb00c1a24dc71ed022cf" + [ + "SMNCOPYNUMBERCALLER", + "smncopynumbercaller", + "1.1.2" + ] ], "run_metrics": [ [ @@ -37,16 +41,20 @@ "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,084e44557eacbb00c1a24dc71ed022cf" + "versions_smncopynumbercaller": [ + [ + "SMNCOPYNUMBERCALLER", + "smncopynumbercaller", + "1.1.2" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-27T12:54:27.295453" + "timestamp": "2026-02-11T21:26:46.783248" }, "test-smncopynumbercaller": { "content": [ @@ -68,7 +76,11 @@ ] ], "2": [ - "versions.yml:md5,084e44557eacbb00c1a24dc71ed022cf" + [ + "SMNCOPYNUMBERCALLER", + "smncopynumbercaller", + "1.1.2" + ] ], "run_metrics": [ [ @@ -86,15 +98,19 @@ "test.tsv:md5,0de62f196972c17e1701aa8cea0849f9" ] ], - "versions": [ - "versions.yml:md5,084e44557eacbb00c1a24dc71ed022cf" + "versions_smncopynumbercaller": [ + [ + "SMNCOPYNUMBERCALLER", + "smncopynumbercaller", + "1.1.2" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-27T12:54:21.71312" + "timestamp": "2026-02-11T21:26:43.145754" } } \ No newline at end of file diff --git a/modules/nf-core/spring/decompress/main.nf b/modules/nf-core/spring/decompress/main.nf index 86ced2690..316080482 100644 --- a/modules/nf-core/spring/decompress/main.nf +++ b/modules/nf-core/spring/decompress/main.nf @@ -4,8 +4,8 @@ process SPRING_DECOMPRESS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/spring:1.1.1--h4ac6f70_2' : - 'biocontainers/spring:1.1.1--h4ac6f70_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f6/f67f27c8cb2d1a149564f1a10f5f2b7a6acfa87ef3d3d27d2d8752dbe95e6acf/data' : + 'community.wave.seqera.io/library/spring:1.1.1--911a17b4ccfb85ee' }" input: tuple val(meta), path(spring) @@ -13,7 +13,8 @@ process SPRING_DECOMPRESS { output: tuple val(meta), path("*.fastq.gz"), emit: fastq - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('spring'), val('1.1.1'), topic: versions, emit: versions_spring + // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. when: task.ext.when == null || task.ext.when @@ -21,9 +22,7 @@ process SPRING_DECOMPRESS { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '1.1.1' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. def output = write_one_fastq_gz ? "-o ${prefix}.fastq.gz" : "-o ${prefix}_R1.fastq.gz ${prefix}_R2.fastq.gz" - """ spring \\ -d \\ @@ -32,23 +31,12 @@ process SPRING_DECOMPRESS { $args \\ -i ${spring} \\ ${output} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - spring: ${VERSION} - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '1.1.1' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. def output = write_one_fastq_gz ? "echo '' | gzip > ${prefix}.fastq.gz" : "echo '' | gzip > ${prefix}_R1.fastq.gz; echo '' | gzip > ${prefix}_R2.fastq.gz" """ ${output} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - spring: ${VERSION} - END_VERSIONS """ } diff --git a/modules/nf-core/spring/decompress/meta.yml b/modules/nf-core/spring/decompress/meta.yml index 72b72b75d..e41c4bf90 100644 --- a/modules/nf-core/spring/decompress/meta.yml +++ b/modules/nf-core/spring/decompress/meta.yml @@ -24,14 +24,15 @@ input: type: file description: Spring file to decompress. pattern: "*.{spring}" - - - write_one_fastq_gz: - type: boolean - description: | - Controls whether spring should write one fastq.gz file with reads from both directions or two fastq.gz files with reads from distinct directions - pattern: "true or false" + ontologies: [] + - write_one_fastq_gz: + type: boolean + description: | + Controls whether spring should write one fastq.gz file with reads from both directions or two fastq.gz files with reads from distinct directions + pattern: "true or false" output: - - fastq: - - meta: + fastq: + - - meta: type: map description: | Groovy Map containing sample information @@ -40,11 +41,28 @@ output: type: file description: Decompressed FASTQ file(s). pattern: "*.{fastq.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_spring: + - - ${task.process}: + type: string + description: The name of the process + - spring: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - spring: + type: string + description: The name of the tool + - 1.1.1: + type: string + description: The expression to obtain the version of the tool authors: - "@xec-cm" maintainers: diff --git a/modules/nf-core/spring/decompress/tests/main.nf.test b/modules/nf-core/spring/decompress/tests/main.nf.test index c7ac2b1f3..f960b0d5b 100644 --- a/modules/nf-core/spring/decompress/tests/main.nf.test +++ b/modules/nf-core/spring/decompress/tests/main.nf.test @@ -151,4 +151,4 @@ nextflow_process { } } -} \ No newline at end of file +} diff --git a/modules/nf-core/spring/decompress/tests/main.nf.test.snap b/modules/nf-core/spring/decompress/tests/main.nf.test.snap index 7dcadbab6..dd6cc252d 100644 --- a/modules/nf-core/spring/decompress/tests/main.nf.test.snap +++ b/modules/nf-core/spring/decompress/tests/main.nf.test.snap @@ -1,76 +1,4 @@ { - "Write-One-File stub": { - "content": [ - { - "0": [ - [ - { - "id": "test" - }, - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/2a6cfab794852e23e6324eb4955668b2/work/42/aee6c82c1ca502c3b02339f597188b/test.fastq.gz" - ] - ], - "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" - ], - "fastq": [ - [ - { - "id": "test" - }, - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/2a6cfab794852e23e6324eb4955668b2/work/42/aee6c82c1ca502c3b02339f597188b/test.fastq.gz" - ] - ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-08T10:03:50.626223289" - }, - "Write-Two-Files stub": { - "content": [ - { - "0": [ - [ - { - "id": "test2" - }, - [ - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/528557b5a81e4bffb57c38b19c7aa351/work/74/fc5d116d011bcd47d6f7de8d42ac34/test2_R1.fastq.gz", - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/528557b5a81e4bffb57c38b19c7aa351/work/74/fc5d116d011bcd47d6f7de8d42ac34/test2_R2.fastq.gz" - ] - ] - ], - "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" - ], - "fastq": [ - [ - { - "id": "test2" - }, - [ - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/528557b5a81e4bffb57c38b19c7aa351/work/74/fc5d116d011bcd47d6f7de8d42ac34/test2_R1.fastq.gz", - "/home/ramprasad.neethiraj/nextflow/modules/.nf-test/tests/528557b5a81e4bffb57c38b19c7aa351/work/74/fc5d116d011bcd47d6f7de8d42ac34/test2_R2.fastq.gz" - ] - ] - ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-08T10:03:57.417015606" - }, "Write-Two-Files": { "content": [ { @@ -86,7 +14,11 @@ ] ], "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ], "fastq": [ [ @@ -99,16 +31,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + "versions_spring": [ + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ] } ], + "timestamp": "2026-02-11T11:16:00.074323", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-21T13:41:46.090761471" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } }, "Write-One-File": { "content": [ @@ -122,7 +58,11 @@ ] ], "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ], "fastq": [ [ @@ -132,16 +72,20 @@ "test.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" ] ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + "versions_spring": [ + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ] } ], + "timestamp": "2026-02-11T11:15:54.633046", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-21T13:02:07.466039653" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } }, "Write-One-File-stub": { "content": [ @@ -155,7 +99,11 @@ ] ], "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ], "fastq": [ [ @@ -165,16 +113,20 @@ "test.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + "versions_spring": [ + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ] } ], + "timestamp": "2026-02-11T11:16:04.953817", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-08T13:55:53.594615215" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } }, "Write-Two-Files-stub": { "content": [ @@ -191,7 +143,11 @@ ] ], "1": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ], "fastq": [ [ @@ -204,15 +160,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,4711df5941f1464e3693d24dd29c705b" + "versions_spring": [ + [ + "SPRING_DECOMPRESS", + "spring", + "1.1.1" + ] ] } ], + "timestamp": "2026-02-11T11:16:09.98067", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-08T13:56:01.212228909" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } } } \ No newline at end of file diff --git a/modules/nf-core/spring/decompress/tests/nextflow.config b/modules/nf-core/spring/decompress/tests/nextflow.config index 50f50a7a3..8730f1c4b 100644 --- a/modules/nf-core/spring/decompress/tests/nextflow.config +++ b/modules/nf-core/spring/decompress/tests/nextflow.config @@ -1,5 +1,5 @@ process { publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - -} \ No newline at end of file + +} diff --git a/modules/nf-core/stranger/environment.yml b/modules/nf-core/stranger/environment.yml index 3a7f17717..0cd211c25 100644 --- a/modules/nf-core/stranger/environment.yml +++ b/modules/nf-core/stranger/environment.yml @@ -4,5 +4,8 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::stranger=0.9.4 - - bioconda::tabix=1.11 + - bioconda::htslib=1.23 + - conda-forge::pip=25.3 + - conda-forge::python=3.14.2 + - pip: + - stranger==0.10.0 diff --git a/modules/nf-core/stranger/main.nf b/modules/nf-core/stranger/main.nf index 314051fca..14170010d 100644 --- a/modules/nf-core/stranger/main.nf +++ b/modules/nf-core/stranger/main.nf @@ -4,8 +4,8 @@ process STRANGER { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/19/19f14a7c1b0ec9cbdeb6d32e3692208d559e9186b210e9a0a6922e001cb6ad32/data': - 'community.wave.seqera.io/library/stranger_tabix:847b205e87ed124b' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/90/90f7f35b37e9e31c8680c18ef59c76e74500f44664887b3c1131daf07ff3043f/data': + 'community.wave.seqera.io/library/htslib_pip_stranger:de13e0cf88d77b50' }" input: tuple val(meta), path(vcf) @@ -14,7 +14,8 @@ process STRANGER { output: tuple val(meta), path("*.vcf.gz") , emit: vcf tuple val(meta), path("*.vcf.gz.tbi"), emit: tbi - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('stranger'), eval("stranger --version | sed 's/stranger, version //g'"), topic: versions, emit: versions_stranger + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'"), topic: versions, emit: versions_tabix when: task.ext.when == null || task.ext.when @@ -37,12 +38,6 @@ process STRANGER { $args3 \\ --threads ${task.cpus} \\ ${prefix}.vcf.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - stranger: \$( stranger --version | sed 's/stranger, version //g' ) - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ stub: @@ -52,11 +47,5 @@ process STRANGER { """ echo "" | gzip > ${prefix}.vcf.gz touch ${prefix}.vcf.gz.tbi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - stranger: \$( stranger --version | sed 's/stranger, version //g' ) - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/stranger/meta.yml b/modules/nf-core/stranger/meta.yml index 0cec73af1..623b6e13d 100644 --- a/modules/nf-core/stranger/meta.yml +++ b/modules/nf-core/stranger/meta.yml @@ -1,6 +1,6 @@ name: stranger -description: Annotates output files from ExpansionHunter with the pathologic implications - of the repeat sizes. +description: Annotates output files from ExpansionHunter with the pathologic + implications of the repeat sizes. keywords: - STR - repeat_expansions @@ -25,6 +25,7 @@ input: type: file description: VCF with repeat expansions pattern: "*.{vcf.gz,vcf}" + ontologies: [] - - meta2: type: map description: | @@ -34,9 +35,11 @@ input: type: file description: json file with repeat expansion sites to genotype pattern: "*.{json}" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON output: - - vcf: - - meta: + vcf: + - - meta: type: map description: Annotated VCF file pattern: "*.{vcf.gz}" @@ -44,20 +47,59 @@ output: type: map description: Annotated VCF file pattern: "*.{vcf.gz}" - - tbi: - - meta: + tbi: + - - meta: type: map - description: Index of the annotated VCF file - pattern: "*.{vcf.gz.tbi}" + description: Annotated VCF file + pattern: "*.{vcf.gz}" - "*.vcf.gz.tbi": type: map description: Index of the annotated VCF file pattern: "*.{vcf.gz.tbi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_stranger: + - - ${task.process}: + type: string + description: The name of the process + - stranger: + type: string + description: The name of the tool + - stranger --version | sed 's/stranger, version //g': + type: eval + description: The expression to obtain the version of the tool + + versions_tabix: + - - ${task.process}: + type: string + description: The name of the process + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - stranger: + type: string + description: The name of the tool + - stranger --version | sed 's/stranger, version //g': + type: eval + description: The expression to obtain the version of the tool + + - - ${task.process}: + type: string + description: The name of the process + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + authors: - "@ljmesi" maintainers: diff --git a/modules/nf-core/stranger/tests/main.nf.test.snap b/modules/nf-core/stranger/tests/main.nf.test.snap index bb688bade..922cb7f03 100644 --- a/modules/nf-core/stranger/tests/main.nf.test.snap +++ b/modules/nf-core/stranger/tests/main.nf.test.snap @@ -19,7 +19,18 @@ ] ], "2": [ - "versions.yml:md5,85a7b3c900c0e406e2bc25e9c7d42bd5" + [ + "STRANGER", + "stranger", + "0.10.0" + ] + ], + "3": [ + [ + "STRANGER", + "tabix", + "1.23" + ] ], "tbi": [ [ @@ -37,16 +48,27 @@ "stranger.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,85a7b3c900c0e406e2bc25e9c7d42bd5" + "versions_stranger": [ + [ + "STRANGER", + "stranger", + "0.10.0" + ] + ], + "versions_tabix": [ + [ + "STRANGER", + "tabix", + "1.23" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-05-19T16:22:00.38081072" + "timestamp": "2026-01-30T15:59:31.211437829" }, "homo_sapiens - vcf, repeat_catalogue": { "content": [ @@ -56,7 +78,7 @@ { "id": "test" }, - "stranger.vcf.gz:md5,e933cd71d9f9f146265b8e8dd90b712c" + "stranger.vcf.gz:md5,5c55cbc7404f2d03b8cac82733175783" ] ], "1": [ @@ -64,18 +86,29 @@ { "id": "test" }, - "stranger.vcf.gz.tbi:md5,2445c81019fb4fa8d9c861c8e4b37196" + "stranger.vcf.gz.tbi:md5,9ac34e9ea9d9e3eee971b542629259c3" ] ], "2": [ - "versions.yml:md5,85a7b3c900c0e406e2bc25e9c7d42bd5" + [ + "STRANGER", + "stranger", + "0.10.0" + ] + ], + "3": [ + [ + "STRANGER", + "tabix", + "1.23" + ] ], "tbi": [ [ { "id": "test" }, - "stranger.vcf.gz.tbi:md5,2445c81019fb4fa8d9c861c8e4b37196" + "stranger.vcf.gz.tbi:md5,9ac34e9ea9d9e3eee971b542629259c3" ] ], "vcf": [ @@ -83,18 +116,29 @@ { "id": "test" }, - "stranger.vcf.gz:md5,e933cd71d9f9f146265b8e8dd90b712c" + "stranger.vcf.gz:md5,5c55cbc7404f2d03b8cac82733175783" ] ], - "versions": [ - "versions.yml:md5,85a7b3c900c0e406e2bc25e9c7d42bd5" + "versions_stranger": [ + [ + "STRANGER", + "stranger", + "0.10.0" + ] + ], + "versions_tabix": [ + [ + "STRANGER", + "tabix", + "1.23" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-05-19T16:21:56.946267992" + "timestamp": "2026-01-30T15:59:14.37967244" } } \ No newline at end of file diff --git a/modules/nf-core/svdb/merge/environment.yml b/modules/nf-core/svdb/merge/environment.yml index dc587136e..c64deab4d 100644 --- a/modules/nf-core/svdb/merge/environment.yml +++ b/modules/nf-core/svdb/merge/environment.yml @@ -3,7 +3,6 @@ channels: - conda-forge - bioconda - dependencies: - - bcftools=1.21 - - svdb=2.8.2 + - bioconda::bcftools=1.23 + - bioconda::svdb=2.8.4 diff --git a/modules/nf-core/svdb/merge/main.nf b/modules/nf-core/svdb/merge/main.nf index 104f5ad79..ab14c8d0f 100644 --- a/modules/nf-core/svdb/merge/main.nf +++ b/modules/nf-core/svdb/merge/main.nf @@ -1,10 +1,11 @@ process SVDB_MERGE { tag "$meta.id" label 'process_single' + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-375a758a4ca8c128fb9d38047a68a9f4322d2acd:b3615e06ef17566f2988a215ce9e10808c1d08bf-0': - 'biocontainers/mulled-v2-375a758a4ca8c128fb9d38047a68a9f4322d2acd:b3615e06ef17566f2988a215ce9e10808c1d08bf-0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f5/f59712ead354411dd8bea4918d777737ca4ef2ad1360289507fe35acb688e74f/data': + 'community.wave.seqera.io/library/bcftools_svdb:12db401acbacc624' }" input: tuple val(meta), path(vcfs) @@ -15,7 +16,8 @@ process SVDB_MERGE { tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf tuple val(meta), path("*.tbi") , emit: tbi, optional: true tuple val(meta), path("*.csi") , emit: csi, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('svdb'), eval("svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\\1/p'"), emit: versions_svdb, topic: versions + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), emit: versions_bcftools, topic: versions when: task.ext.when == null || task.ext.when @@ -35,10 +37,10 @@ process SVDB_MERGE { if (input_priority) { if (vcfs.collect().size() > 1 && sort_inputs) { // make vcf-priority pairs and sort on VCF name, so priority is also sorted the same - def pairs = vcfs.indices.collect { [vcfs[it], input_priority[it]] } + def pairs = vcfs.indices.collect { index -> [vcfs[index], input_priority[index]] } pairs = pairs.sort { a, b -> a[0].name <=> b[0].name } - vcfs = pairs.collect { it[0] } - priority = pairs.collect { it[1] } + vcfs = pairs.collect { vcf -> vcf[0] } + priority = pairs.collect { pair -> pair[1] } } else { priority = input_priority } @@ -52,7 +54,7 @@ process SVDB_MERGE { } else { // if there's no priority input just sort the vcfs by name if possible - input = (vcfs.collect().size() > 1 && sort_inputs) ? vcfs.sort { it.name } : vcfs + input = (vcfs.collect().size() > 1 && sort_inputs) ? vcfs.sort { vcf_file -> vcf_file.name } : vcfs } def extension = args2.contains("--output-type b") || args2.contains("-Ob") ? "bcf.gz" : @@ -71,11 +73,6 @@ process SVDB_MERGE { --threads ${task.cpus} \\ --output ${prefix}.${extension} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - svdb: \$( echo \$(svdb) | head -1 | sed 's/usage: SVDB-\\([0-9]\\.[0-9]\\.[0-9]\\).*/\\1/' ) - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ stub: @@ -96,10 +93,5 @@ process SVDB_MERGE { ${create_cmd} ${prefix}.${extension} ${create_index} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - svdb: \$( echo \$(svdb) | head -1 | sed 's/usage: SVDB-\\([0-9]\\.[0-9]\\.[0-9]\\).*/\\1/' ) - bcftools: \$(bcftools --version 2>&1 | head -n1 | sed 's/^.*bcftools //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/svdb/merge/meta.yml b/modules/nf-core/svdb/merge/meta.yml index c34a9cb15..48d73e47e 100644 --- a/modules/nf-core/svdb/merge/meta.yml +++ b/modules/nf-core/svdb/merge/meta.yml @@ -1,5 +1,6 @@ name: svdb_merge -description: The merge module merges structural variants within one or more vcf files. +description: The merge module merges structural variants within one or more vcf + files. keywords: - structural variants - vcf @@ -23,20 +24,20 @@ input: One or more VCF files. The order and number of files should correspond to the order and number of tags in the `priority` input channel. pattern: "*.{vcf,vcf.gz}" - - - input_priority: - type: list - description: | - Prioritize the input VCF files according to this list, - e.g ['tiddit','cnvnator']. The order and number of tags should correspond to - the order and number of VCFs in the `vcfs` input channel. - - - sort_inputs: - type: boolean - description: | - Should the input files be sorted by name. The priority tag will be sorted - together with it's corresponding VCF file. + - input_priority: + type: list + description: | + Prioritize the input VCF files according to this list, + e.g ['tiddit','cnvnator']. The order and number of tags should correspond to + the order and number of VCFs in the `vcfs` input channel. + - sort_inputs: + type: boolean + description: | + Should the input files be sorted by name. The priority tag will be sorted + together with it's corresponding VCF file. output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -45,8 +46,9 @@ output: type: file description: VCF output file pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" - - tbi: - - meta: + ontologies: [] + tbi: + - - meta: type: map description: | Groovy Map containing sample information @@ -55,8 +57,9 @@ output: type: file description: Alternative VCF file index pattern: "*.tbi" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -65,11 +68,47 @@ output: type: file description: Default VCF file index pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_svdb: + - - ${task.process}: + type: string + description: The name of the process + - svdb: + type: string + description: The name of the tool + - svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + versions_bcftools: + - - ${task.process}: + type: string + description: The name of the process + - bcftools: + type: string + description: The tool name + - bcftools --version | sed '1!d; s/^.*bcftools //': + type: eval + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - svdb: + type: string + description: The name of the tool + - svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - bcftools: + type: string + description: The tool name + - bcftools --version | sed '1!d; s/^.*bcftools //': + type: eval + description: The command used to generate the version of the tool authors: - "@ramprasadn" maintainers: diff --git a/modules/nf-core/svdb/merge/tests/main.nf.test b/modules/nf-core/svdb/merge/tests/main.nf.test index 6a79d7a09..23ea38209 100644 --- a/modules/nf-core/svdb/merge/tests/main.nf.test +++ b/modules/nf-core/svdb/merge/tests/main.nf.test @@ -31,7 +31,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -59,7 +59,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -87,7 +87,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -115,7 +115,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -146,7 +146,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -177,7 +177,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -208,7 +208,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -239,7 +239,7 @@ nextflow_process { { assert snapshot( path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } diff --git a/modules/nf-core/svdb/merge/tests/main.nf.test.snap b/modules/nf-core/svdb/merge/tests/main.nf.test.snap index e86662e53..1312ce744 100644 --- a/modules/nf-core/svdb/merge/tests/main.nf.test.snap +++ b/modules/nf-core/svdb/merge/tests/main.nf.test.snap @@ -3,15 +3,28 @@ "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=1, variantCount=9, phased=false, phasedAutodetect=false]", "60fb4cab2aa891bebef8ffdbd0e41bc3", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:00:25.9277471" + "timestamp": "2026-03-03T09:17:45.334283313" }, "2 samples, ['tiddit', 'cnvnator'], true - stub": { "content": [ @@ -31,7 +44,18 @@ ], "3": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ], + "4": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] ], "csi": [ @@ -47,114 +71,216 @@ "merged.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:05:49.325618245" + "timestamp": "2026-03-03T09:19:49.291093513" }, "2 samples, ['tiddit', 'cnvnator'], []": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=2, variantCount=9, phased=false, phasedAutodetect=false]", "254e56e4fc8356d68424828438da66e3", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:02:27.964808463" + "timestamp": "2026-03-03T09:18:53.242914408" }, "2 samples, [], []": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=2, variantCount=9, phased=false, phasedAutodetect=false]", "7ad648266e57d405b5b01aaea4613d1c", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:02:11.013532413" + "timestamp": "2026-03-03T09:18:29.326769277" }, "2 samples, ['tiddit', 'cnvnator'], true": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=2, variantCount=9, phased=false, phasedAutodetect=false]", "254e56e4fc8356d68424828438da66e3", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:02:35.956320871" + "timestamp": "2026-03-03T09:19:04.521659905" }, "1 sample, ['tiddit'], []": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=1, variantCount=9, phased=false, phasedAutodetect=false]", "9dd588cd870672b78192f48ad440b5d", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:00:42.064583463" + "timestamp": "2026-03-03T09:18:07.070476091" }, "1 sample, [], true": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=1, variantCount=9, phased=false, phasedAutodetect=false]", "60fb4cab2aa891bebef8ffdbd0e41bc3", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:00:33.88572601" + "timestamp": "2026-03-03T09:17:55.505389265" }, "1 sample, ['tiddit'], true": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=1, variantCount=9, phased=false, phasedAutodetect=false]", "9dd588cd870672b78192f48ad440b5d", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:00:50.18149857" + "timestamp": "2026-03-03T09:18:17.604155783" }, "2 samples, [], true": { "content": [ "VcfFile [chromosomes=[MT192765.1], sampleCount=2, variantCount=9, phased=false, phasedAutodetect=false]", "de0a3b56cdee89e4c9cd4fbb4ad3391d", - [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" - ] + { + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:02:19.556799178" + "timestamp": "2026-03-03T09:18:41.894600602" }, "2 samples, ['tiddit', 'cnvnator'], [] - stub": { "content": [ @@ -174,7 +300,18 @@ ], "3": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ], + "4": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] ], "csi": [ @@ -190,16 +327,27 @@ "merged.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:05:40.427970257" + "timestamp": "2026-03-03T09:19:37.850074206" }, "2 samples, [], [] - stub": { "content": [ @@ -219,7 +367,18 @@ ], "3": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ], + "4": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] ], "csi": [ @@ -235,16 +394,27 @@ "merged.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:05:24.34471465" + "timestamp": "2026-03-03T09:19:16.292841025" }, "2 samples, [], true - stub": { "content": [ @@ -264,7 +434,18 @@ ], "3": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] + ], + "4": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] ], "csi": [ @@ -280,15 +461,26 @@ "merged.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,bf8271626d334b2a827f94a2daacadd0" + "versions_bcftools": [ + [ + "SVDB_MERGE", + "bcftools", + "1.23" + ] + ], + "versions_svdb": [ + [ + "SVDB_MERGE", + "svdb", + "2.8.4" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-10-24T09:05:32.529261733" + "timestamp": "2026-03-03T09:19:26.851881345" } } \ No newline at end of file diff --git a/modules/nf-core/svdb/merge/tests/tags.yml b/modules/nf-core/svdb/merge/tests/tags.yml deleted file mode 100644 index 8501d9072..000000000 --- a/modules/nf-core/svdb/merge/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -svdb/merge: - - modules/nf-core/svdb/merge/** diff --git a/modules/nf-core/svdb/query/environment.yml b/modules/nf-core/svdb/query/environment.yml index 2af552205..c64deab4d 100644 --- a/modules/nf-core/svdb/query/environment.yml +++ b/modules/nf-core/svdb/query/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::svdb=2.8.2 + - bioconda::bcftools=1.23 + - bioconda::svdb=2.8.4 diff --git a/modules/nf-core/svdb/query/main.nf b/modules/nf-core/svdb/query/main.nf index 4ceb477a0..3f33d31c0 100644 --- a/modules/nf-core/svdb/query/main.nf +++ b/modules/nf-core/svdb/query/main.nf @@ -4,8 +4,8 @@ process SVDB_QUERY { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/svdb:2.8.2--py39h5371cbf_0': - 'biocontainers/svdb:2.8.2--py39h5371cbf_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f5/f59712ead354411dd8bea4918d777737ca4ef2ad1360289507fe35acb688e74f/data': + 'community.wave.seqera.io/library/bcftools_svdb:12db401acbacc624' }" input: tuple val(meta), path(vcf) @@ -18,7 +18,7 @@ process SVDB_QUERY { output: tuple val(meta), path("*_query.vcf") , emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('svdb'), eval("svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\\1/p'"), emit: versions_svdb, topic: versions when: task.ext.when == null || task.ext.when @@ -58,10 +58,6 @@ process SVDB_QUERY { --query_vcf $vcf \\ --prefix ${prefix} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - svdb: \$( echo \$(svdb) | head -1 | sed 's/usage: SVDB-\\([0-9]\\.[0-9]\\.[0-9]\\).*/\\1/' ) - END_VERSIONS """ stub: @@ -69,9 +65,5 @@ process SVDB_QUERY { """ touch ${prefix}_query.vcf - cat <<-END_VERSIONS > versions.yml - "${task.process}": - svdb: \$( echo \$(svdb) | head -1 | sed 's/usage: SVDB-\\([0-9]\\.[0-9]\\.[0-9]\\).*/\\1/' ) - END_VERSIONS """ } diff --git a/modules/nf-core/svdb/query/meta.yml b/modules/nf-core/svdb/query/meta.yml index f8cd33c8d..0b91c8be1 100644 --- a/modules/nf-core/svdb/query/meta.yml +++ b/modules/nf-core/svdb/query/meta.yml @@ -11,7 +11,6 @@ tools: documentation: https://github.com/J35P312/SVDB/blob/master/README.md licence: ["MIT"] identifier: "" - input: - - meta: type: map @@ -22,30 +21,34 @@ input: type: file description: query vcf file pattern: "*.{vcf,vcf.gz}" - - - in_occs: - type: list - description: A list of allele count tags - - - in_frqs: - type: list - description: A list of allele frequency tags - - - out_occs: - type: list - description: A list of allele count tags - - - out_frqs: - type: list - description: A list of allele frequency tags - - - vcf_dbs: - type: file - description: path to a database vcf, or a comma separated list of vcfs - pattern: "*.{vcf,vcf.gz}" - - - bedpe_dbs: - type: file - description: path to a SV database of the following format chrA-posA-chrB-posB-type-count-frequency, - or a comma separated list of files - pattern: "*.{bedpe}" + ontologies: [] + - in_occs: + type: list + description: A list of allele count tags + - in_frqs: + type: list + description: A list of allele frequency tags + - out_occs: + type: list + description: A list of allele count tags + - out_frqs: + type: list + description: A list of allele frequency tags + - vcf_dbs: + type: file + description: path to a database vcf, or a comma separated list of vcfs + pattern: "*.{vcf,vcf.gz}" + ontologies: [] + - bedpe_dbs: + type: file + description: path to a SV database of the following format + chrA-posA-chrB-posB-type-count-frequency, or a comma separated list of + files + pattern: "*.{bedpe}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information @@ -54,10 +57,27 @@ output: type: file description: Annotated output VCF file pattern: "*_query.vcf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_svdb: + - - ${task.process}: + type: string + description: The name of the process + - svdb: + type: string + description: The name of the tool + - svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\1/p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - svdb: + type: string + description: The name of the tool + - svdb | sed -nE 's/.*SVDB-([0-9.]+).*/\1/p': + type: eval + description: The expression to obtain the version of the tool authors: - "@ramprasadn" diff --git a/modules/nf-core/svdb/query/tests/main.nf.test b/modules/nf-core/svdb/query/tests/main.nf.test index 72e829158..aed1be8eb 100644 --- a/modules/nf-core/svdb/query/tests/main.nf.test +++ b/modules/nf-core/svdb/query/tests/main.nf.test @@ -29,7 +29,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(file(process.out.vcf[0][1]).name, file(process.out.versions[0]).name).match()} + { assert snapshot(path(process.out.vcf[0][1]).vcf.variantsMD5, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + } ) } } diff --git a/modules/nf-core/svdb/query/tests/main.nf.test.snap b/modules/nf-core/svdb/query/tests/main.nf.test.snap index 65f2fcfaa..47ccc233f 100644 --- a/modules/nf-core/svdb/query/tests/main.nf.test.snap +++ b/modules/nf-core/svdb/query/tests/main.nf.test.snap @@ -1,13 +1,21 @@ { "svdb query": { "content": [ - "test_query.vcf", - "versions.yml" + "eee99ddfe9ab0a94a2be80e3c1757fdf", + { + "versions_svdb": [ + [ + "SVDB_QUERY", + "svdb", + "2.8.4" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2023-11-22T14:56:08.90223505" + "timestamp": "2026-03-03T09:20:00.331166694" } } \ No newline at end of file diff --git a/modules/nf-core/svdb/query/tests/tags.yml b/modules/nf-core/svdb/query/tests/tags.yml deleted file mode 100644 index f40963780..000000000 --- a/modules/nf-core/svdb/query/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -svdb/query: - - modules/nf-core/svdb/query/** diff --git a/modules/nf-core/tabix/bgzip/environment.yml b/modules/nf-core/tabix/bgzip/environment.yml index 017c259da..771b13870 100644 --- a/modules/nf-core/tabix/bgzip/environment.yml +++ b/modules/nf-core/tabix/bgzip/environment.yml @@ -1,7 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.20 - - bioconda::tabix=1.11 + - bioconda::htslib=1.21 diff --git a/modules/nf-core/tabix/bgzip/main.nf b/modules/nf-core/tabix/bgzip/main.nf index 67991c74b..e80919bfd 100644 --- a/modules/nf-core/tabix/bgzip/main.nf +++ b/modules/nf-core/tabix/bgzip/main.nf @@ -4,16 +4,16 @@ process TABIX_BGZIP { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/htslib:1.20--h5efdd21_2' : - 'biocontainers/htslib:1.20--h5efdd21_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/92/92859404d861ae01afb87e2b789aebc71c0ab546397af890c7df74e4ee22c8dd/data' : + 'community.wave.seqera.io/library/htslib:1.21--ff8e28a189fbecaa' }" input: tuple val(meta), path(input) output: - tuple val(meta), path("${output}") , emit: output - tuple val(meta), path("${output}.gzi"), emit: gzi, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("${output}"), emit: output + tuple val(meta), path("*.gzi") , emit: gzi, optional: true + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'") , topic: versions , emit: versions_tabix when: task.ext.when == null || task.ext.when @@ -26,16 +26,13 @@ process TABIX_BGZIP { output = in_bgzip ? "${prefix}.${extension}" : "${prefix}.${extension}.gz" command = in_bgzip ? '-d' : '' // Name the index according to $prefix, unless a name has been requested - if ((args.matches("(^| )-i\\b") || args.matches("(^| )--index(\$| )")) && !args.matches("(^| )-I\\b") && !args.matches("(^| )--index-name\\b")) { + split_args = args.split(' +|=') + if ((split_args.contains('-i') || split_args.contains('--index')) && !split_args.contains('-I') && !split_args.contains('--index-name')) { args = args + " -I ${output}.gzi" } """ bgzip $command -c $args -@${task.cpus} $input > ${output} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ stub: @@ -47,9 +44,5 @@ process TABIX_BGZIP { echo "" | gzip > ${output} touch ${output}.gzi - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/tabix/bgzip/meta.yml b/modules/nf-core/tabix/bgzip/meta.yml index 131e92cfd..7b56e897c 100644 --- a/modules/nf-core/tabix/bgzip/meta.yml +++ b/modules/nf-core/tabix/bgzip/meta.yml @@ -23,9 +23,10 @@ input: - input: type: file description: file to compress or to decompress + ontologies: [] output: - - output: - - meta: + output: + - - meta: type: map description: | Groovy Map containing sample information @@ -34,21 +35,41 @@ output: type: file description: Output compressed/decompressed file pattern: "*." - - gzi: - - meta: + ontologies: [] + gzi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - ${output}.gzi: + - "*.gzi": type: file description: Optional gzip index file for compressed inputs pattern: "*.gzi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_tabix: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/tabix/bgzip/tests/main.nf.test b/modules/nf-core/tabix/bgzip/tests/main.nf.test index d784aa070..00e7c0984 100644 --- a/modules/nf-core/tabix/bgzip/tests/main.nf.test +++ b/modules/nf-core/tabix/bgzip/tests/main.nf.test @@ -1,7 +1,7 @@ nextflow_process { name "Test Process TABIX_BGZIP" - script "modules/nf-core/tabix/bgzip/main.nf" + script "../main.nf" process "TABIX_BGZIP" tag "modules" diff --git a/modules/nf-core/tabix/bgzip/tests/main.nf.test.snap b/modules/nf-core/tabix/bgzip/tests/main.nf.test.snap index 0748143f0..28388109f 100644 --- a/modules/nf-core/tabix/bgzip/tests/main.nf.test.snap +++ b/modules/nf-core/tabix/bgzip/tests/main.nf.test.snap @@ -24,7 +24,11 @@ ], "2": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ], "gzi": [ @@ -37,16 +41,20 @@ "bedgz_test.bed:md5,87a15eb9c2ff20ccd5cd8735a28708f7" ] ], - "versions": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + "versions_tabix": [ + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-07-19T11:28:34.159992362" + "timestamp": "2026-01-27T15:05:31.678626" }, "test_stub": { "content": [ @@ -73,7 +81,11 @@ ], "2": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ], "gzi": [ @@ -86,16 +98,20 @@ "bgzip_test.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + "versions_tabix": [ + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-07-19T11:28:22.087769106" + "timestamp": "2026-01-27T15:05:27.928712" }, "sarscov2_vcf_bgzip_compress_gzi": { "content": [ @@ -117,7 +133,11 @@ ] ], "2": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ], "gzi": [ [ @@ -135,16 +155,20 @@ "gzi_compress_test.vcf.gz:md5,8e722884ffb75155212a3fc053918766" ] ], - "versions": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + "versions_tabix": [ + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-07-19T11:28:57.15091665" + "timestamp": "2026-01-27T15:05:39.49628" }, "bgzip_test": { "content": [ @@ -186,7 +210,11 @@ ] ], "2": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ], "gzi": [ [ @@ -204,15 +232,19 @@ "test_stub.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,753c29916d45debdde52f4ac7c745f61" + "versions_tabix": [ + [ + "TABIX_BGZIP", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-07-19T11:28:45.219404786" + "timestamp": "2026-01-27T15:05:35.726067" } } \ No newline at end of file diff --git a/modules/nf-core/tabix/bgzip/tests/tags.yml b/modules/nf-core/tabix/bgzip/tests/tags.yml deleted file mode 100644 index de0eec86f..000000000 --- a/modules/nf-core/tabix/bgzip/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -tabix/bgzip: - - "modules/nf-core/tabix/bgzip/**" diff --git a/modules/nf-core/tabix/bgziptabix/environment.yml b/modules/nf-core/tabix/bgziptabix/environment.yml index 017c259da..771b13870 100644 --- a/modules/nf-core/tabix/bgziptabix/environment.yml +++ b/modules/nf-core/tabix/bgziptabix/environment.yml @@ -1,7 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.20 - - bioconda::tabix=1.11 + - bioconda::htslib=1.21 diff --git a/modules/nf-core/tabix/bgziptabix/main.nf b/modules/nf-core/tabix/bgziptabix/main.nf index 22f37a773..30eae745f 100644 --- a/modules/nf-core/tabix/bgziptabix/main.nf +++ b/modules/nf-core/tabix/bgziptabix/main.nf @@ -4,16 +4,16 @@ process TABIX_BGZIPTABIX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/htslib:1.20--h5efdd21_2' : - 'biocontainers/htslib:1.20--h5efdd21_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/92/92859404d861ae01afb87e2b789aebc71c0ab546397af890c7df74e4ee22c8dd/data' : + 'community.wave.seqera.io/library/htslib:1.21--ff8e28a189fbecaa' }" input: tuple val(meta), path(input) output: - tuple val(meta), path("*.gz"), path("*.tbi"), optional: true, emit: gz_tbi - tuple val(meta), path("*.gz"), path("*.csi"), optional: true, emit: gz_csi - path "versions.yml" , emit: versions + tuple val(meta), path("*.gz"), path("*.{tbi,csi}"), emit: gz_index + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'") , topic: versions , emit: versions_tabix + tuple val("${task.process}"), val('bgzip'), eval("bgzip --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_bgzip when: task.ext.when == null || task.ext.when @@ -23,13 +23,9 @@ process TABIX_BGZIPTABIX { def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" """ - bgzip --threads ${task.cpus} -c $args $input > ${prefix}.${input.getExtension()}.gz + bgzip --threads ${task.cpus} -c $args $input > ${prefix}.${input.getExtension()}.gz tabix --threads ${task.cpus} $args2 ${prefix}.${input.getExtension()}.gz - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ stub: @@ -40,9 +36,5 @@ process TABIX_BGZIPTABIX { echo "" | gzip > ${prefix}.${input.getExtension()}.gz touch ${prefix}.${input.getExtension()}.gz.${index} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/tabix/bgziptabix/meta.yml b/modules/nf-core/tabix/bgziptabix/meta.yml index 806fbc121..2a3078c55 100644 --- a/modules/nf-core/tabix/bgziptabix/meta.yml +++ b/modules/nf-core/tabix/bgziptabix/meta.yml @@ -1,5 +1,6 @@ name: tabix_bgziptabix -description: bgzip a sorted tab-delimited genome file and then create tabix index +description: bgzip a sorted tab-delimited genome file and then create tabix + index keywords: - bgzip - compress @@ -23,9 +24,10 @@ input: - input: type: file description: Sorted tab-delimited genome file + ontologies: [] output: - - gz_tbi: - - meta: + gz_index: + - - meta: type: map description: | Groovy Map containing sample information @@ -34,29 +36,55 @@ output: type: file description: bgzipped tab-delimited genome file pattern: "*.gz" - - "*.tbi": + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + - "*.{tbi,csi}": type: file - description: tabix index file - pattern: "*.tbi" - - gz_csi: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.gz": - type: file - description: bgzipped tab-delimited genome file - pattern: "*.gz" - - "*.csi": - type: file - description: csi index file - pattern: "*.csi" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + description: Tabix index file (either tbi or csi) + pattern: "*.{tbi,csi}" + ontologies: [] + versions_tabix: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + versions_bgzip: + - - ${task.process}: + type: string + description: The process the versions were collected from + - bgzip: + type: string + description: The tool name + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The process the versions were collected from + - bgzip: + type: string + description: The tool name + - bgzip --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + authors: - "@maxulysse" - "@DLBPointon" diff --git a/modules/nf-core/tabix/bgziptabix/tests/main.nf.test b/modules/nf-core/tabix/bgziptabix/tests/main.nf.test index 4d4130dc0..1955b143e 100644 --- a/modules/nf-core/tabix/bgziptabix/tests/main.nf.test +++ b/modules/nf-core/tabix/bgziptabix/tests/main.nf.test @@ -1,7 +1,7 @@ nextflow_process { name "Test Process TABIX_BGZIPTABIX" - script "modules/nf-core/tabix/bgziptabix/main.nf" + script "../main.nf" process "TABIX_BGZIPTABIX" tag "modules" @@ -9,10 +9,13 @@ nextflow_process { tag "tabix" tag "tabix/bgziptabix" - test("sarscov2_bed_tbi") { - config "./tabix_tbi.config" + config "./nextflow.config" + test("sarscov2_bed_tbi") { when { + params { + module_args = '-p vcf' + } process { """ input[0] = [ @@ -26,19 +29,16 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, - { assert snapshot( - file(process.out.gz_tbi[0][1]).name - ).match("tbi_test") - } + { assert snapshot(process.out).match() } ) } } test("sarscov2_bed_csi") { - config "./tabix_csi.config" - when { + params { + module_args = '-p vcf --csi' + } process { """ input[0] = [ @@ -52,22 +52,19 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, - { assert snapshot( - file(process.out.gz_csi[0][1]).name - ).match("csi_test") - } + { assert snapshot(process.out).match() } ) } } test("sarscov2_bed_csi_stub") { - config "./tabix_csi.config" - options "-stub" when { + params { + module_args = '-p vcf --csi' + } process { """ input[0] = [ @@ -81,22 +78,19 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, - { assert snapshot( - file(process.out.gz_csi[0][1]).name - ).match("csi_stub") - } + { assert snapshot(process.out).match() } ) } } test("sarscov2_bed_tbi_stub") { - config "./tabix_tbi.config" - options "-stub" when { + params { + module_args = '-p vcf' + } process { """ input[0] = [ @@ -110,11 +104,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, - { assert snapshot( - file(process.out.gz_tbi[0][1]).name - ).match("tbi_stub") - } + { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/tabix/bgziptabix/tests/main.nf.test.snap b/modules/nf-core/tabix/bgziptabix/tests/main.nf.test.snap index fb87799b2..cf3ce8aa8 100644 --- a/modules/nf-core/tabix/bgziptabix/tests/main.nf.test.snap +++ b/modules/nf-core/tabix/bgziptabix/tests/main.nf.test.snap @@ -12,15 +12,20 @@ ] ], "1": [ - + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ], "2": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" - ], - "gz_csi": [ - + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "gz_tbi": [ + "gz_index": [ [ { "id": "tbi_test" @@ -29,24 +34,32 @@ "tbi_test.bed.gz.tbi:md5,ca06caf88b1e3c67d5fcba0a1460b52c" ] ], - "versions": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + "versions_bgzip": [ + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] + ], + "versions_tabix": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-07-19T11:29:16.053817543" + "timestamp": "2026-01-29T23:36:32.823417" }, "sarscov2_bed_csi": { "content": [ { "0": [ - - ], - "1": [ [ { "id": "csi_test" @@ -55,10 +68,21 @@ "csi_test.bed.gz.csi:md5,c9c0377de58fdc89672bb3005a0d69f5" ] ], + "1": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] + ], "2": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "gz_csi": [ + "gz_index": [ [ { "id": "csi_test" @@ -67,29 +91,27 @@ "csi_test.bed.gz.csi:md5,c9c0377de58fdc89672bb3005a0d69f5" ] ], - "gz_tbi": [ - + "versions_bgzip": [ + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "versions": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + "versions_tabix": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-19T11:29:27.667745444" - }, - "csi_test": { - "content": [ - "csi_test.bed.gz" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-02-19T14:51:00.548801" + "timestamp": "2026-01-29T23:36:36.715208" }, "sarscov2_bed_tbi_stub": { "content": [ @@ -104,15 +126,20 @@ ] ], "1": [ - + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ], "2": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" - ], - "gz_csi": [ - + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "gz_tbi": [ + "gz_index": [ [ { "id": "test" @@ -121,54 +148,32 @@ "test.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + "versions_bgzip": [ + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] + ], + "versions_tabix": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-25T14:45:18.533169949" - }, - "csi_stub": { - "content": [ - "test.bed.gz" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-02-19T14:51:09.218454" - }, - "tbi_stub": { - "content": [ - "test.bed.gz" - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-25T14:45:18.550930179" - }, - "tbi_test": { - "content": [ - "tbi_test.bed.gz" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-02-19T14:50:51.579654" + "timestamp": "2026-01-29T23:36:45.016007" }, "sarscov2_bed_csi_stub": { "content": [ { "0": [ - - ], - "1": [ [ { "id": "test" @@ -177,10 +182,21 @@ "test.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "1": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] + ], "2": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "gz_csi": [ + "gz_index": [ [ { "id": "test" @@ -189,18 +205,26 @@ "test.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "gz_tbi": [ - + "versions_bgzip": [ + [ + "TABIX_BGZIPTABIX", + "bgzip", + "1.21" + ] ], - "versions": [ - "versions.yml:md5,736e7c3b16a3ac525253e5b5f5d8fdfa" + "versions_tabix": [ + [ + "TABIX_BGZIPTABIX", + "tabix", + "1.21" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-25T14:44:19.786135972" + "timestamp": "2026-01-29T23:36:40.5401" } } \ No newline at end of file diff --git a/modules/nf-core/tabix/bgziptabix/tests/tabix_csi.config b/modules/nf-core/tabix/bgziptabix/tests/nextflow.config similarity index 56% rename from modules/nf-core/tabix/bgziptabix/tests/tabix_csi.config rename to modules/nf-core/tabix/bgziptabix/tests/nextflow.config index fb41a3142..5b2316c88 100644 --- a/modules/nf-core/tabix/bgziptabix/tests/tabix_csi.config +++ b/modules/nf-core/tabix/bgziptabix/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: TABIX_BGZIPTABIX { - ext.args2 = '-p vcf --csi' + ext.args2 = params.module_args } } diff --git a/modules/nf-core/tabix/bgziptabix/tests/tabix_tbi.config b/modules/nf-core/tabix/bgziptabix/tests/tabix_tbi.config deleted file mode 100644 index c1915dc4b..000000000 --- a/modules/nf-core/tabix/bgziptabix/tests/tabix_tbi.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: TABIX_BGZIPTABIX { - ext.args2 = '-p vcf' - } -} \ No newline at end of file diff --git a/modules/nf-core/tabix/bgziptabix/tests/tags.yml b/modules/nf-core/tabix/bgziptabix/tests/tags.yml deleted file mode 100644 index 5052b4d70..000000000 --- a/modules/nf-core/tabix/bgziptabix/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -tabix/bgziptabix: - - "modules/nf-core/tabix/bgziptabix/**" diff --git a/modules/nf-core/tabix/tabix/environment.yml b/modules/nf-core/tabix/tabix/environment.yml index 017c259da..771b13870 100644 --- a/modules/nf-core/tabix/tabix/environment.yml +++ b/modules/nf-core/tabix/tabix/environment.yml @@ -1,7 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.20 - - bioconda::tabix=1.11 + - bioconda::htslib=1.21 diff --git a/modules/nf-core/tabix/tabix/main.nf b/modules/nf-core/tabix/tabix/main.nf index 13acd670e..c8bcef64e 100644 --- a/modules/nf-core/tabix/tabix/main.nf +++ b/modules/nf-core/tabix/tabix/main.nf @@ -4,16 +4,15 @@ process TABIX_TABIX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/htslib:1.20--h5efdd21_2' : - 'biocontainers/htslib:1.20--h5efdd21_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/92/92859404d861ae01afb87e2b789aebc71c0ab546397af890c7df74e4ee22c8dd/data' : + 'community.wave.seqera.io/library/htslib:1.21--ff8e28a189fbecaa' }" input: tuple val(meta), path(tab) output: - tuple val(meta), path("*.tbi"), optional:true, emit: tbi - tuple val(meta), path("*.csi"), optional:true, emit: csi - path "versions.yml" , emit: versions + tuple val(meta), path("*.{tbi,csi}"), emit: index + tuple val("${task.process}"), val('tabix'), eval("tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+'") , topic: versions , emit: versions_tabix when: task.ext.when == null || task.ext.when @@ -26,20 +25,11 @@ process TABIX_TABIX { $args \\ $tab - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS """ - stub: + def args = task.ext.args ?: '' + def index = args.contains("-C ") || args.contains("--csi") ? "csi" : "tbi" """ - touch ${tab}.tbi - touch ${tab}.csi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tabix: \$(echo \$(tabix -h 2>&1) | sed 's/^.*Version: //; s/ .*\$//') - END_VERSIONS + touch ${tab}.${index} """ } diff --git a/modules/nf-core/tabix/tabix/meta.yml b/modules/nf-core/tabix/tabix/meta.yml index 7864832d9..f5b6b3c16 100644 --- a/modules/nf-core/tabix/tabix/meta.yml +++ b/modules/nf-core/tabix/tabix/meta.yml @@ -22,32 +22,42 @@ input: type: file description: TAB-delimited genome position file compressed with bgzip pattern: "*.{bed.gz,gff.gz,sam.gz,vcf.gz}" + ontologies: [] output: - - tbi: - - meta: + index: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.tbi": + - "*.{tbi,csi}": type: file - description: tabix index file - pattern: "*.{tbi}" - - csi: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.csi": - type: file - description: coordinate sorted index file - pattern: "*.{csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + description: Tabix index file (either tbi or csi) + pattern: "*.{tbi,csi}" + ontologies: [] + versions_tabix: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - tabix: + type: string + description: The tool name + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/tabix/tabix/tests/main.nf.test b/modules/nf-core/tabix/tabix/tests/main.nf.test index 102b0d7bf..19eefab87 100644 --- a/modules/nf-core/tabix/tabix/tests/main.nf.test +++ b/modules/nf-core/tabix/tabix/tests/main.nf.test @@ -1,7 +1,7 @@ nextflow_process { name "Test Process TABIX_TABIX" - script "modules/nf-core/tabix/tabix/main.nf" + script "../main.nf" process "TABIX_TABIX" tag "modules" @@ -9,9 +9,13 @@ nextflow_process { tag "tabix" tag "tabix/tabix" + config "./nextflow.config" + test("sarscov2_bedgz_tbi") { - config "./tabix_bed.config" when { + params { + module_args = '-p bed' + } process { """ input[0] = [ @@ -25,17 +29,16 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot( - process.out, - file(process.out.tbi[0][1]).name - ).match() } + { assert snapshot(process.out).match() } ) } } test("sarscov2_gff_tbi") { - config "./tabix_gff.config" when { + params { + module_args = '-p gff' + } process { """ input[0] = [ @@ -49,17 +52,17 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot( - process.out, - file(process.out.tbi[0][1]).name).match() } + { assert snapshot(process.out).match() } ) } } test("sarscov2_vcf_tbi") { - config "./tabix_vcf_tbi.config" when { + params { + module_args = '-p vcf' + } process { """ input[0] = [ @@ -73,18 +76,17 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot( - process.out, - file(process.out.tbi[0][1]).name - ).match() } + { assert snapshot(process.out).match() } ) } } test("sarscov2_vcf_csi") { - config "./tabix_vcf_csi.config" when { + params { + module_args = '-p vcf --csi' + } process { """ input[0] = [ @@ -98,19 +100,18 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot( - process.out, - file(process.out.csi[0][1]).name - ).match() } + { assert snapshot(process.out).match() } ) } } test("sarscov2_vcf_csi_stub") { - config "./tabix_vcf_csi.config" options "-stub" when { + params { + module_args = '-p vcf --csi' + } process { """ input[0] = [ @@ -124,13 +125,9 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot( - process.out, - file(process.out.csi[0][1]).name - ).match() } + { assert snapshot(process.out).match() } ) } - } } diff --git a/modules/nf-core/tabix/tabix/tests/main.nf.test.snap b/modules/nf-core/tabix/tabix/tests/main.nf.test.snap index c2b9ed0b8..91a3a66de 100644 --- a/modules/nf-core/tabix/tabix/tests/main.nf.test.snap +++ b/modules/nf-core/tabix/tabix/tests/main.nf.test.snap @@ -11,15 +11,13 @@ ] ], "1": [ - - ], - "2": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" - ], - "csi": [ - + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ], - "tbi": [ + "index": [ [ { "id": "tbi_gff" @@ -27,17 +25,20 @@ "genome.gff3.gz.tbi:md5,f79a67d95a98076e04fbe0455d825926" ] ], - "versions": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" + "versions_tabix": [ + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ] - }, - "genome.gff3.gz.tbi" + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.04.7" }, - "timestamp": "2024-07-19T12:06:25.653807564" + "timestamp": "2025-11-20T13:47:34.055936" }, "sarscov2_bedgz_tbi": { "content": [ @@ -51,15 +52,13 @@ ] ], "1": [ - - ], - "2": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" - ], - "csi": [ - + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ], - "tbi": [ + "index": [ [ { "id": "tbi_bed" @@ -67,17 +66,20 @@ "test.bed.gz.tbi:md5,9a761d51cc81835fd1199201fdbcdd5d" ] ], - "versions": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" + "versions_tabix": [ + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ] - }, - "test.bed.gz.tbi" + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.04.7" }, - "timestamp": "2024-07-19T12:06:09.754082161" + "timestamp": "2025-11-20T13:47:29.90469" }, "sarscov2_vcf_tbi": { "content": [ @@ -91,15 +93,13 @@ ] ], "1": [ - - ], - "2": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" - ], - "csi": [ - + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ], - "tbi": [ + "index": [ [ { "id": "tbi_vcf" @@ -107,17 +107,20 @@ "test.vcf.gz.tbi:md5,d22e5b84e4fcd18792179f72e6da702e" ] ], - "versions": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" + "versions_tabix": [ + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ] - }, - "test.vcf.gz.tbi" + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.04.7" }, - "timestamp": "2024-07-19T12:06:40.042648294" + "timestamp": "2025-11-20T13:47:38.044307" }, "sarscov2_vcf_csi_stub": { "content": [ @@ -127,21 +130,17 @@ { "id": "vcf_csi_stub" }, - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ [ - { - "id": "vcf_csi_stub" - }, - "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "TABIX_TABIX", + "tabix", + "1.21" ] ], - "2": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" - ], - "csi": [ + "index": [ [ { "id": "vcf_csi_stub" @@ -149,33 +148,25 @@ "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "tbi": [ + "versions_tabix": [ [ - { - "id": "vcf_csi_stub" - }, - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + "TABIX_TABIX", + "tabix", + "1.21" ] - ], - "versions": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" ] - }, - "test.vcf.gz.csi" + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.2", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-19T12:07:08.700367261" + "timestamp": "2025-12-10T14:31:29.90297082" }, "sarscov2_vcf_csi": { "content": [ { "0": [ - - ], - "1": [ [ { "id": "vcf_csi" @@ -183,10 +174,14 @@ "test.vcf.gz.csi:md5,04b41c1efd9ab3c6b1e008a286e27d2b" ] ], - "2": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" + "1": [ + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ], - "csi": [ + "index": [ [ { "id": "vcf_csi" @@ -194,19 +189,19 @@ "test.vcf.gz.csi:md5,04b41c1efd9ab3c6b1e008a286e27d2b" ] ], - "tbi": [ - - ], - "versions": [ - "versions.yml:md5,07064637fb8a217174052be8e40234e2" + "versions_tabix": [ + [ + "TABIX_TABIX", + "tabix", + "1.21" + ] ] - }, - "test.vcf.gz.csi" + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.04.7" }, - "timestamp": "2024-07-19T12:06:55.362067748" + "timestamp": "2025-11-20T13:47:42.013054" } } \ No newline at end of file diff --git a/modules/nf-core/tabix/tabix/tests/tabix_vcf_csi.config b/modules/nf-core/tabix/tabix/tests/nextflow.config similarity index 54% rename from modules/nf-core/tabix/tabix/tests/tabix_vcf_csi.config rename to modules/nf-core/tabix/tabix/tests/nextflow.config index eb4f2d7e2..96685ef28 100644 --- a/modules/nf-core/tabix/tabix/tests/tabix_vcf_csi.config +++ b/modules/nf-core/tabix/tabix/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: TABIX_TABIX { - ext.args = '-p vcf --csi' + ext.args = params.module_args } } diff --git a/modules/nf-core/tabix/tabix/tests/tabix_bed.config b/modules/nf-core/tabix/tabix/tests/tabix_bed.config deleted file mode 100644 index 7ff059056..000000000 --- a/modules/nf-core/tabix/tabix/tests/tabix_bed.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: TABIX_TABIX { - ext.args = '-p bed' - } -} \ No newline at end of file diff --git a/modules/nf-core/tabix/tabix/tests/tabix_gff.config b/modules/nf-core/tabix/tabix/tests/tabix_gff.config deleted file mode 100644 index 20c0a1e34..000000000 --- a/modules/nf-core/tabix/tabix/tests/tabix_gff.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: TABIX_TABIX { - ext.args = '-p gff' - } -} \ No newline at end of file diff --git a/modules/nf-core/tabix/tabix/tests/tabix_vcf_tbi.config b/modules/nf-core/tabix/tabix/tests/tabix_vcf_tbi.config deleted file mode 100644 index 2774c8a90..000000000 --- a/modules/nf-core/tabix/tabix/tests/tabix_vcf_tbi.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: TABIX_TABIX { - ext.args = '-p vcf' - } -} \ No newline at end of file diff --git a/modules/nf-core/tabix/tabix/tests/tags.yml b/modules/nf-core/tabix/tabix/tests/tags.yml deleted file mode 100644 index 6eda06537..000000000 --- a/modules/nf-core/tabix/tabix/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -tabix/tabix: - - "modules/nf-core/tabix/tabix/**" diff --git a/modules/nf-core/tiddit/cov/environment.yml b/modules/nf-core/tiddit/cov/environment.yml index 2fd01cfd4..d00f5e363 100644 --- a/modules/nf-core/tiddit/cov/environment.yml +++ b/modules/nf-core/tiddit/cov/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::tiddit=3.6.1 + - bioconda::tiddit=3.9.5 diff --git a/modules/nf-core/tiddit/cov/main.nf b/modules/nf-core/tiddit/cov/main.nf index 20d4720e7..6ef2f8525 100644 --- a/modules/nf-core/tiddit/cov/main.nf +++ b/modules/nf-core/tiddit/cov/main.nf @@ -4,48 +4,38 @@ process TIDDIT_COV { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/tiddit:3.6.1--py38h24c8ff8_0' : - 'biocontainers/tiddit:3.6.1--py38h24c8ff8_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/6a/6a427ef9929eb787b83224b3c8dd5d1dd7f7897e6921c60ecc5e58ef705daf6b/data' : + 'community.wave.seqera.io/library/tiddit:3.9.5--3fb6c287f34e6ab0' }" input: - tuple val(meta), path(input) + tuple val(meta), path(input), path(index) tuple val(meta2), path(fasta) output: - tuple val(meta), path("*.bed"), optional: true, emit: cov - tuple val(meta), path("*.wig"), optional: true, emit: wig - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.bed"), optional: true, emit: cov + tuple val(meta), path("${prefix}.wig"), optional: true, emit: wig + tuple val("${task.process}"), val('tiddit'), eval("tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'"), topic: versions, emit: versions_tiddit when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--ref $fasta" : "" + prefix = task.ext.prefix ?: "${meta.id}" + def reference = fasta ? "--ref ${fasta}" : "" """ tiddit \\ --cov \\ - -o $prefix \\ - $args \\ - --bam $input \\ - $reference - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tiddit: \$(echo \$(tiddit 2>&1) | sed 's/^.*tiddit-//; s/ .*\$//') - END_VERSIONS + -o ${prefix} \\ + ${args} \\ + --bam ${input} \\ + ${reference} """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.wig - touch ${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tiddit: \$(echo \$(tiddit 2>&1) | sed 's/^.*tiddit-//; s/ .*\$//') - END_VERSIONS + echo "" > ${prefix}.wig + echo "" > ${prefix}.bed """ } diff --git a/modules/nf-core/tiddit/cov/meta.yml b/modules/nf-core/tiddit/cov/meta.yml index 88b72641d..0f28625d9 100644 --- a/modules/nf-core/tiddit/cov/meta.yml +++ b/modules/nf-core/tiddit/cov/meta.yml @@ -11,7 +11,8 @@ tools: homepage: https://github.com/SciLifeLab/TIDDIT documentation: https://github.com/SciLifeLab/TIDDIT/blob/master/README.md doi: "10.12688/f1000research.11168.1" - licence: ["GPL v3"] + licence: + - "GPL v3" identifier: biotools:tiddit input: - - meta: @@ -23,6 +24,13 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] + - index: + type: file + description: Index of BAM/CRAM file + pattern: "*.{bai,crai,csi}" + ontologies: + - edam: http://edamontology.org/format_3327 - - meta2: type: map description: | @@ -34,32 +42,51 @@ input: Reference genome file. Only needed when passing in CRAM instead of BAM. If not using CRAM, please pass an empty file instead. pattern: "*.fasta" + ontologies: [] output: - - cov: - - meta: + cov: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.bed": + - ${prefix}.bed: type: file description: The coverage of different regions in bed format. Optional. pattern: "*.bed" - - wig: - - meta: + ontologies: [] + wig: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.wig": + - ${prefix}.wig: type: file description: The coverage of different regions in WIG format. Optional. pattern: "*.wig" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_tiddit: + - - ${task.process}: + type: string + description: The name of the process + - tiddit: + type: string + description: The name of the tool + - "tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - tiddit: + type: string + description: The name of the tool + - "tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'": + type: eval + description: The expression to obtain the version of the tool authors: - "@projectoriented" - "@ramprasadn" diff --git a/modules/nf-core/tiddit/cov/tests/main.nf.test b/modules/nf-core/tiddit/cov/tests/main.nf.test index 24c273d86..97d386460 100644 --- a/modules/nf-core/tiddit/cov/tests/main.nf.test +++ b/modules/nf-core/tiddit/cov/tests/main.nf.test @@ -16,7 +16,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] ] input[1] = [ @@ -33,7 +34,7 @@ nextflow_process { { assert process.out.cov[0][1] ==~ ".*/test.bed" }, { assert snapshot( process.out.cov, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -48,7 +49,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] ] input[1] = [ [:], [] ] """ @@ -61,7 +63,7 @@ nextflow_process { { assert process.out.cov[0][1] ==~ ".*/test.bed" }, { assert snapshot( process.out.cov, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -78,7 +80,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] ] input[1] = [ @@ -95,7 +98,7 @@ nextflow_process { { assert process.out.wig[0][1] ==~ ".*/test.wig" }, { assert snapshot( process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -112,7 +115,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] ] input[1] = [ [:], [] ] @@ -126,7 +130,7 @@ nextflow_process { { assert process.out.wig[0][1] ==~ ".*/test.wig" }, { assert snapshot( process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -145,7 +149,8 @@ nextflow_process { input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] ] input[1] = [ @@ -159,14 +164,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert process.out.cov[0][1] ==~ ".*/test.bed" }, - { assert process.out.wig[0][1] ==~ ".*/test.wig" }, - { assert snapshot( - process.out.cov, - process.out.wig, - process.out.versions - ).match() - } + { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/tiddit/cov/tests/main.nf.test.snap b/modules/nf-core/tiddit/cov/tests/main.nf.test.snap index 5067886d6..c5c6f8c32 100644 --- a/modules/nf-core/tiddit/cov/tests/main.nf.test.snap +++ b/modules/nf-core/tiddit/cov/tests/main.nf.test.snap @@ -10,15 +10,21 @@ "test.wig:md5,7c46b6ef30574acdce0ad854f40126ae" ] ], - [ - "versions.yml:md5,49dfdb5a33d1c11db488fb02d1c95c5a" - ] + { + "versions_tiddit": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T15:59:36.336058", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-30T09:44:07.66262" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens - cram - wig": { "content": [ @@ -31,45 +37,82 @@ "test.wig:md5,7c46b6ef30574acdce0ad854f40126ae" ] ], - [ - "versions.yml:md5,49dfdb5a33d1c11db488fb02d1c95c5a" - ] + { + "versions_tiddit": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T15:59:31.464109", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-30T09:44:01.397993" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.wig:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "2": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ], + "cov": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_tiddit": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ], + "wig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.wig:md5,68b329da9893e34099c7d8ad5cb9c940" + ] ] - ], - [ - "versions.yml:md5,49dfdb5a33d1c11db488fb02d1c95c5a" - ] + } ], + "timestamp": "2026-03-23T15:59:42.352822", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-30T09:44:12.873466" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens - bam - bed": { "content": [ @@ -82,15 +125,21 @@ "test.bed:md5,caf0742f2d4a6f713ceb85268dd48c14" ] ], - [ - "versions.yml:md5,49dfdb5a33d1c11db488fb02d1c95c5a" - ] + { + "versions_tiddit": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T15:59:26.294427", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-30T09:43:54.542951" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens - cram - bed": { "content": [ @@ -103,14 +152,20 @@ "test.bed:md5,caf0742f2d4a6f713ceb85268dd48c14" ] ], - [ - "versions.yml:md5,49dfdb5a33d1c11db488fb02d1c95c5a" - ] + { + "versions_tiddit": [ + [ + "TIDDIT_COV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T15:59:20.487446", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" - }, - "timestamp": "2024-07-30T09:43:47.441318" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/tiddit/cov/tests/tags.yml b/modules/nf-core/tiddit/cov/tests/tags.yml deleted file mode 100644 index d5831f1d1..000000000 --- a/modules/nf-core/tiddit/cov/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -tiddit/cov: - - "modules/nf-core/tiddit/cov/**" diff --git a/modules/nf-core/tiddit/sv/environment.yml b/modules/nf-core/tiddit/sv/environment.yml index 2fd01cfd4..d00f5e363 100644 --- a/modules/nf-core/tiddit/sv/environment.yml +++ b/modules/nf-core/tiddit/sv/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::tiddit=3.6.1 + - bioconda::tiddit=3.9.5 diff --git a/modules/nf-core/tiddit/sv/main.nf b/modules/nf-core/tiddit/sv/main.nf index f350e3144..ff097942d 100644 --- a/modules/nf-core/tiddit/sv/main.nf +++ b/modules/nf-core/tiddit/sv/main.nf @@ -4,53 +4,43 @@ process TIDDIT_SV { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/tiddit:3.6.1--py38h24c8ff8_0' : - 'biocontainers/tiddit:3.6.1--py38h24c8ff8_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/6a/6a427ef9929eb787b83224b3c8dd5d1dd7f7897e6921c60ecc5e58ef705daf6b/data' : + 'community.wave.seqera.io/library/tiddit:3.9.5--3fb6c287f34e6ab0' }" input: tuple val(meta), path(input), path(input_index) - tuple val(meta2), path(fasta) + tuple val(meta2), path(fasta), path(fai) tuple val(meta3), path(bwa_index) output: - tuple val(meta), path("*.vcf") , emit: vcf - tuple val(meta), path("*.ploidies.tab"), emit: ploidy - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.vcf") , emit: vcf + tuple val(meta), path("${prefix}.ploidies.tab"), emit: ploidy + tuple val("${task.process}"), val('tiddit'), eval("tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'"), topic: versions, emit: versions_tiddit when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def bwa_command = bwa_index ? "[[ -d $bwa_index ]] && for i in $bwa_index/*; do [[ -f $fasta && ! \"\$i\" =~ .*\"$fasta.\".* ]] && ln -s \$i ${fasta}.\${i##*.} || ln -s \$i .; done" : "" + prefix = task.ext.prefix ?: "${meta.id}" + def bwa_command = bwa_index ? "[[ -d ${bwa_index} ]] && for i in ${bwa_index}/*; do [[ -f ${fasta} && ! \"\$i\" =~ .*\"${fasta}.\".* ]] && ln -s \$i ${fasta}.\${i##*.} || ln -s \$i .; done" : "" """ $bwa_command tiddit \\ --sv \\ - $args \\ + ${args} \\ --threads $task.cpus \\ - --bam $input \\ - --ref $fasta \\ - -o $prefix - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tiddit: \$(echo \$(tiddit 2>&1) | sed 's/^.*tiddit-//; s/ .*\$//') - END_VERSIONS + --bam ${input} \\ + --ref ${fasta} \\ + -o ${prefix} """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf - touch ${prefix}.ploidies.tab - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - tiddit: \$(echo \$(tiddit 2>&1) | sed 's/^.*tiddit-//; s/ .*\$//') - END_VERSIONS + echo "" > ${prefix}.vcf + echo "" > ${prefix}.ploidies.tab """ } diff --git a/modules/nf-core/tiddit/sv/meta.yml b/modules/nf-core/tiddit/sv/meta.yml index 21527baf1..78232760c 100644 --- a/modules/nf-core/tiddit/sv/meta.yml +++ b/modules/nf-core/tiddit/sv/meta.yml @@ -10,7 +10,8 @@ tools: homepage: https://github.com/SciLifeLab/TIDDIT documentation: https://github.com/SciLifeLab/TIDDIT/blob/master/README.md doi: 10.12688/f1000research.11168.1 - licence: ["GPL-3.0-or-later"] + licence: + - "GPL-3.0-or-later" identifier: biotools:tiddit input: - - meta: @@ -22,10 +23,12 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - input_index: type: file description: BAM/CRAM index file pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -35,6 +38,12 @@ input: type: file description: Input FASTA file pattern: "*.{fasta,fa}" + ontologies: [] + - fai: + type: file + description: Input FASTA index file + pattern: "*.{fai}" + ontologies: [] - - meta3: type: map description: | @@ -44,32 +53,51 @@ input: type: file description: BWA genome index files pattern: "Directory containing BWA index *.{amb,ann,bwt,pac,sa}" + ontologies: [] output: - - vcf: - - meta: + vcf: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.vcf": + - "${prefix}.vcf": type: file description: vcf pattern: "*.{vcf}" - - ploidy: - - meta: + ontologies: [] + ploidy: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.ploidies.tab": + - "${prefix}.ploidies.tab": type: file description: tab pattern: "*.{ploidies.tab}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_tiddit: + - - ${task.process}: + type: string + description: The name of the process + - tiddit: + type: string + description: The name of the tool + - "tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - tiddit: + type: string + description: The name of the tool + - "tiddit | sed -n 's/^usage: tiddit-//; s/ .*//p'": + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" maintainers: diff --git a/modules/nf-core/tiddit/sv/tests/main.nf.test b/modules/nf-core/tiddit/sv/tests/main.nf.test index 6e32b9e1c..3b136b3f5 100644 --- a/modules/nf-core/tiddit/sv/tests/main.nf.test +++ b/modules/nf-core/tiddit/sv/tests/main.nf.test @@ -35,7 +35,8 @@ nextflow_process { ] // fasta input[1] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] // bwa_index input[2] = BWA_INDEX.out.index @@ -46,9 +47,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.vcf.get(0).get(1)).readLines().contains("##fileformat=VCFv4.1") }, - { assert path(process.out.ploidy.get(0).get(1)).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, - { assert snapshot(process.out.versions).match("bam_bwa_version") } + { assert path(process.out.ploidy[0][1]).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, + { assert snapshot(path(process.out.vcf[0][1]).vcf.header.getColumnCount(), process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } @@ -67,7 +67,8 @@ nextflow_process { ] // fasta input[1] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] // bwa_index input[2] = [ [], [] ] @@ -78,9 +79,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.vcf.get(0).get(1)).readLines().contains("##fileformat=VCFv4.1") }, - { assert path(process.out.ploidy.get(0).get(1)).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, - { assert snapshot(process.out.versions).match("bam_version") } + { assert path(process.out.ploidy[0][1]).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, + { assert snapshot(path(process.out.vcf[0][1]).vcf.header.getColumnCount(), process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } @@ -95,7 +95,8 @@ nextflow_process { process { """ input[0] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] """ } @@ -111,7 +112,8 @@ nextflow_process { ] // fasta input[1] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] // bwa_index input[2] = BWA_INDEX.out.index @@ -122,11 +124,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.vcf.get(0).get(1)).readLines().contains("##fileformat=VCFv4.1") }, - { assert path(process.out.ploidy.get(0).get(1)).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, - { assert snapshot(process.out.versions).match("cram_bwa_version") }) + { assert path(process.out.ploidy[0][1]).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, + { assert snapshot(path(process.out.vcf[0][1]).vcf.header.getColumnCount(), process.out.findAll { key, val -> key.startsWith("versions") }).match() } + ) } - } test("human - cram - no_bwa") { @@ -142,7 +143,8 @@ nextflow_process { ] // fasta input[1] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] // bwa_index input[2] = [ [], [] ] @@ -153,11 +155,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert path(process.out.vcf.get(0).get(1)).readLines().contains("##fileformat=VCFv4.1") }, - { assert path(process.out.ploidy.get(0).get(1)).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, - { assert snapshot(process.out.versions).match("cram_version") }) + { assert path(process.out.ploidy[0][1]).readLines().contains("Chromosome Ploidy Ploidy_rounded Mean_coverage") }, + { assert snapshot(path(process.out.vcf[0][1]).vcf.header.getColumnCount(), process.out.findAll { key, val -> key.startsWith("versions") }).match() } + ) } - } test("sarscov2 - bam - stub") { @@ -173,7 +174,8 @@ nextflow_process { ] // fasta input[1] = [ [id: 'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] // bwa_index input[2] = [ [], [] ] diff --git a/modules/nf-core/tiddit/sv/tests/main.nf.test.snap b/modules/nf-core/tiddit/sv/tests/main.nf.test.snap index 541c48bbd..92da4db74 100644 --- a/modules/nf-core/tiddit/sv/tests/main.nf.test.snap +++ b/modules/nf-core/tiddit/sv/tests/main.nf.test.snap @@ -1,28 +1,4 @@ { - "cram_bwa_version": { - "content": [ - [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-03-22T10:33:01.300519" - }, - "cram_version": { - "content": [ - [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-03-22T10:27:12.52902" - }, "sarscov2 - bam - stub": { "content": [ { @@ -31,7 +7,7 @@ { "id": "test" }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.vcf:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ @@ -39,18 +15,22 @@ { "id": "test" }, - "test.ploidies.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.ploidies.tab:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "2": [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] ], "ploidy": [ [ { "id": "test" }, - "test.ploidies.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.ploidies.tab:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "vcf": [ @@ -58,42 +38,98 @@ { "id": "test" }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.vcf:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" + "versions_tiddit": [ + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] + ] + } + ], + "timestamp": "2026-03-23T16:00:24.346829", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - bam - bwa": { + "content": [ + 10, + { + "versions_tiddit": [ + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] + ] + } + ], + "timestamp": "2026-03-23T15:59:52.928838", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "human - cram - bwa": { + "content": [ + 10, + { + "versions_tiddit": [ + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] ] } ], + "timestamp": "2026-03-23T16:00:10.285571", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-03-22T10:21:51.950503" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, - "bam_bwa_version": { + "sarscov2 - bam - no_bwa": { "content": [ - [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" - ] + 10, + { + "versions_tiddit": [ + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T16:00:01.097762", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-03-22T10:31:40.918479" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, - "bam_version": { + "human - cram - no_bwa": { "content": [ - [ - "versions.yml:md5,0ffcce416e40bcc98da2243f1d7e348a" - ] + 10, + { + "versions_tiddit": [ + [ + "TIDDIT_SV", + "tiddit", + "3.9.5" + ] + ] + } ], + "timestamp": "2026-03-23T16:00:18.226844", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.0" - }, - "timestamp": "2024-03-22T10:21:38.449053" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/tiddit/sv/tests/tags.yml b/modules/nf-core/tiddit/sv/tests/tags.yml deleted file mode 100644 index aac5351ec..000000000 --- a/modules/nf-core/tiddit/sv/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -tiddit/sv: - - "modules/nf-core/tiddit/sv/**" diff --git a/modules/nf-core/ucsc/wigtobigwig/environment.yml b/modules/nf-core/ucsc/wigtobigwig/environment.yml index 331ad3b27..6bd9f2509 100644 --- a/modules/nf-core/ucsc/wigtobigwig/environment.yml +++ b/modules/nf-core/ucsc/wigtobigwig/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::ucsc-wigtobigwig=447 + - bioconda::ucsc-wigtobigwig=482 diff --git a/modules/nf-core/ucsc/wigtobigwig/main.nf b/modules/nf-core/ucsc/wigtobigwig/main.nf index 4b7adb62f..e7c4c6cb8 100644 --- a/modules/nf-core/ucsc/wigtobigwig/main.nf +++ b/modules/nf-core/ucsc/wigtobigwig/main.nf @@ -5,46 +5,35 @@ process UCSC_WIGTOBIGWIG { // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ucsc-wigtobigwig:447--h2a80c09_1' : - 'biocontainers/ucsc-wigtobigwig:447--h2a80c09_1' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/03/0394161be68e8dd5b30a47f0b19ffa00cb3226bb2e6c9fe3ec89e571a50b871d/data' : + 'community.wave.seqera.io/library/ucsc-wigtobigwig:482--7b910cc21c32327e' }" input: tuple val(meta), path(wig) path sizes output: - tuple val(meta), path("*.bw"), emit: bw - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}.bw"), emit: bw + tuple val("${task.process}"), val('ucsc'), val('482'), topic: versions, emit: versions_ucsc + // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '447' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" """ wigToBigWig \\ $args \\ $wig \\ $sizes \\ ${prefix}.bw - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ucsc: $VERSION - END_VERSIONS """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '447' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.bw - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - ucsc: $VERSION - END_VERSIONS """ } diff --git a/modules/nf-core/ucsc/wigtobigwig/meta.yml b/modules/nf-core/ucsc/wigtobigwig/meta.yml index 97bf98b16..3bbd3e312 100644 --- a/modules/nf-core/ucsc/wigtobigwig/meta.yml +++ b/modules/nf-core/ucsc/wigtobigwig/meta.yml @@ -10,7 +10,8 @@ tools: Convert ascii format wig file (in fixedStep, variableStep or bedGraph format) to binary big wig format homepage: http://www.genome.ucsc.edu/goldenPath/help/bigWig.html - licence: ["varies; see http://genome.ucsc.edu/license"] + licence: + - "varies; see http://genome.ucsc.edu/license" identifier: "" input: - - meta: @@ -22,24 +23,44 @@ input: type: file description: wig file pattern: "*.{wig}" - - - sizes: - type: file - description: Chromosome sizes file + ontologies: [] + - sizes: + type: file + description: Chromosome sizes file + ontologies: [] output: - - bw: - - meta: + bw: + - - meta: type: file description: bigwig file pattern: "*.{bw}" - - "*.bw": + ontologies: [] + - ${prefix}.bw: type: file description: bigwig file pattern: "*.{bw}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_ucsc: + - - ${task.process}: + type: string + description: The name of the process + - ucsc: + type: string + description: The name of the tool + - "482": + type: string + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - ucsc: + type: string + description: The name of the tool + - "482": + type: string + description: The expression to obtain the version of the tool authors: - "@jianhong" - "@projectoriented" diff --git a/modules/nf-core/ucsc/wigtobigwig/tests/main.nf.test.snap b/modules/nf-core/ucsc/wigtobigwig/tests/main.nf.test.snap index acc59555c..ee8704437 100644 --- a/modules/nf-core/ucsc/wigtobigwig/tests/main.nf.test.snap +++ b/modules/nf-core/ucsc/wigtobigwig/tests/main.nf.test.snap @@ -12,7 +12,11 @@ ] ], "1": [ - "versions.yml:md5,e99b51033a14e1602fe195965a109feb" + [ + "UCSC_WIGTOBIGWIG", + "ucsc", + "482" + ] ], "bw": [ [ @@ -23,16 +27,20 @@ "test.bw:md5,b64af7003665dc51fae958216b06ed95" ] ], - "versions": [ - "versions.yml:md5,e99b51033a14e1602fe195965a109feb" + "versions_ucsc": [ + [ + "UCSC_WIGTOBIGWIG", + "ucsc", + "482" + ] ] } ], + "timestamp": "2026-02-16T09:50:37.235738", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-27T11:54:03.735102" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-ucsc-wigtobigwig-stub": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,e99b51033a14e1602fe195965a109feb" + [ + "UCSC_WIGTOBIGWIG", + "ucsc", + "482" + ] ], "bw": [ [ @@ -58,15 +70,19 @@ "test.bw:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,e99b51033a14e1602fe195965a109feb" + "versions_ucsc": [ + [ + "UCSC_WIGTOBIGWIG", + "ucsc", + "482" + ] ] } ], + "timestamp": "2026-02-16T09:50:41.464164", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-27T11:54:07.924401" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/untar/environment.yml b/modules/nf-core/untar/environment.yml index c7794856d..9b926b1ff 100644 --- a/modules/nf-core/untar/environment.yml +++ b/modules/nf-core/untar/environment.yml @@ -1,7 +1,12 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: + - conda-forge::coreutils=9.5 - conda-forge::grep=3.11 + - conda-forge::gzip=1.13 + - conda-forge::lbzip2=2.5 - conda-forge::sed=4.8 - conda-forge::tar=1.34 diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf index 9bd8f5546..b9c324dac 100644 --- a/modules/nf-core/untar/main.nf +++ b/modules/nf-core/untar/main.nf @@ -1,56 +1,52 @@ process UNTAR { - tag "$archive" + tag "${archive}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ubuntu:22.04' : - 'nf-core/ubuntu:22.04' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' + : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: tuple val(meta), path(archive) output: - tuple val(meta), path("$prefix"), emit: untar - path "versions.yml" , emit: versions + tuple val(meta), path("${prefix}"), emit: untar + tuple val("${task.process}"), val('untar'), eval('tar --version 2>&1 | head -1 | sed "s/tar (GNU tar) //; s/ Copyright.*//"'), emit: versions_untar, topic: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - prefix = task.ext.prefix ?: ( meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) + prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) """ - mkdir $prefix + mkdir ${prefix} ## Ensures --strip-components only applied when top level of tar contents is a directory ## If just files or multiple directories, place all in prefix if [[ \$(tar -taf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then tar \\ - -C $prefix --strip-components 1 \\ + -C ${prefix} --strip-components 1 \\ -xavf \\ - $args \\ - $archive \\ - $args2 + ${args} \\ + ${archive} \\ + ${args2} else tar \\ - -C $prefix \\ + -C ${prefix} \\ -xavf \\ - $args \\ - $archive \\ - $args2 + ${args} \\ + ${archive} \\ + ${args2} fi - cat <<-END_VERSIONS > versions.yml - "${task.process}": - untar: \$(echo \$(tar --version 2>&1) | sed 's/^.*(GNU tar) //; s/ Copyright.*\$//') - END_VERSIONS """ stub: - prefix = task.ext.prefix ?: ( meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) + prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) """ mkdir ${prefix} ## Dry-run untaring the archive to get the files and place all in prefix @@ -75,10 +71,5 @@ process UNTAR { fi done fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - untar: \$(echo \$(tar --version 2>&1) | sed 's/^.*(GNU tar) //; s/ Copyright.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/untar/meta.yml b/modules/nf-core/untar/meta.yml index 290346b3f..571d8078a 100644 --- a/modules/nf-core/untar/meta.yml +++ b/modules/nf-core/untar/meta.yml @@ -1,5 +1,5 @@ name: untar -description: Extract files. +description: Extract files from tar, tar.gz, tar.bz2, tar.xz archives keywords: - untar - uncompress @@ -7,7 +7,7 @@ keywords: tools: - untar: description: | - Extract tar.gz files. + Extract tar, tar.gz, tar.bz2, tar.xz files. documentation: https://www.gnu.org/software/tar/manual/ licence: ["GPL-3.0-or-later"] identifier: "" @@ -19,24 +19,48 @@ input: e.g. [ id:'test', single_end:false ] - archive: type: file - description: File to be untar - pattern: "*.{tar}.{gz}" + description: File to be untarred + pattern: "*.{tar,tar.gz,tar.bz2,tar.xz}" + ontologies: + - edam: http://edamontology.org/format_3981 # TAR format + - edam: http://edamontology.org/format_3989 # GZIP format output: - - untar: - - meta: + untar: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*/" + - ${prefix}: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - $prefix: - type: directory - description: Directory containing contents of archive pattern: "*/" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_untar: + - - ${task.process}: + type: string + description: The name of the process + - untar: + type: string + description: The name of the tool + - tar --version 2>&1 | head -1 | sed "s/tar (GNU tar) //; s/ Copyright.*//": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - untar: + type: string + description: The name of the tool + - tar --version 2>&1 | head -1 | sed "s/tar (GNU tar) //; s/ Copyright.*//": + type: eval + description: The expression to obtain the version of the tool + authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/untar/tests/main.nf.test b/modules/nf-core/untar/tests/main.nf.test index c957517aa..fde8db16a 100644 --- a/modules/nf-core/untar/tests/main.nf.test +++ b/modules/nf-core/untar/tests/main.nf.test @@ -20,7 +20,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, ) } } @@ -38,7 +41,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, ) } } @@ -58,7 +64,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, ) } } @@ -78,7 +87,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, ) } } diff --git a/modules/nf-core/untar/tests/main.nf.test.snap b/modules/nf-core/untar/tests/main.nf.test.snap index ceb91b792..51a414dd4 100644 --- a/modules/nf-core/untar/tests/main.nf.test.snap +++ b/modules/nf-core/untar/tests/main.nf.test.snap @@ -1,158 +1,118 @@ { "test_untar_onlyfiles": { "content": [ - { - "0": [ + [ + [ + [ + + ], [ - [ - - ], - [ - "hello.txt:md5,e59ff97941044f85df5297e1c302d260" - ] + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" ] - ], - "1": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" - ], - "untar": [ + ] + ], + { + "versions_untar": [ [ - [ - - ], - [ - "hello.txt:md5,e59ff97941044f85df5297e1c302d260" - ] + "UNTAR", + "untar", + "1.34" ] - ], - "versions": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-10T12:04:28.231047" + "timestamp": "2026-01-28T17:49:32.000491" }, "test_untar_onlyfiles - stub": { "content": [ - { - "0": [ + [ + [ + [ + + ], [ - [ - - ], - [ - "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "1": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" - ], - "untar": [ + ] + ], + { + "versions_untar": [ [ - [ - - ], - [ - "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "UNTAR", + "untar", + "1.34" ] - ], - "versions": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-10T12:04:45.773103" + "timestamp": "2026-01-28T17:49:58.812479" }, "test_untar - stub": { "content": [ - { - "0": [ + [ + [ + [ + + ], [ - [ - - ], - [ - "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", - "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", - "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "1": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" - ], - "untar": [ + ] + ], + { + "versions_untar": [ [ - [ - - ], - [ - "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", - "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", - "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "UNTAR", + "untar", + "1.34" ] - ], - "versions": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-10T12:04:36.777441" + "timestamp": "2026-01-28T17:49:48.119456" }, "test_untar": { "content": [ - { - "0": [ + [ + [ + [ + + ], [ - [ - - ], - [ - "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", - "opts.k2d:md5,a033d00cf6759407010b21700938f543", - "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" - ] + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" ] - ], - "1": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" - ], - "untar": [ + ] + ], + { + "versions_untar": [ [ - [ - - ], - [ - "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", - "opts.k2d:md5,a033d00cf6759407010b21700938f543", - "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" - ] + "UNTAR", + "untar", + "1.34" ] - ], - "versions": [ - "versions.yml:md5,6063247258c56fd271d076bb04dd7536" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-10T12:04:19.377674" + "timestamp": "2026-01-28T17:49:17.252494" } } \ No newline at end of file diff --git a/modules/nf-core/untar/tests/tags.yml b/modules/nf-core/untar/tests/tags.yml deleted file mode 100644 index feb6f15c0..000000000 --- a/modules/nf-core/untar/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -untar: - - modules/nf-core/untar/** diff --git a/modules/nf-core/upd/environment.yml b/modules/nf-core/upd/environment.yml index 307f13b37..a45a25cd9 100644 --- a/modules/nf-core/upd/environment.yml +++ b/modules/nf-core/upd/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/upd/main.nf b/modules/nf-core/upd/main.nf index c4bcaf175..1196a03c8 100644 --- a/modules/nf-core/upd/main.nf +++ b/modules/nf-core/upd/main.nf @@ -9,14 +9,14 @@ process UPD { 'biocontainers/upd:0.1.1--pyhdfd78af_0' }" input: - tuple val(meta), path(vcf) + tuple val(meta), path(vcf) output: - tuple val(meta), path("*.bed"), emit: bed - path "versions.yml" , emit: versions + tuple val(meta), path("*.bed"), emit: bed + tuple val("${task.process}"), val('upd'), eval("upd --version 2>&1 | sed 's/upd, version //'"), topic: versions, emit: versions_upd when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' @@ -26,22 +26,12 @@ process UPD { --vcf $vcf \\ $args \\ | sort -k 1,1 -k 2,2n >${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - upd: \$( upd --version 2>&1 | sed 's/upd, version //' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - upd: \$( upd --version 2>&1 | sed 's/upd, version //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/upd/meta.yml b/modules/nf-core/upd/meta.yml index a0e900632..650cf217d 100644 --- a/modules/nf-core/upd/meta.yml +++ b/modules/nf-core/upd/meta.yml @@ -24,9 +24,10 @@ input: type: file description: VCF file pattern: "*.{vcf,vcf.gz}" + ontologies: [] output: - - bed: - - meta: + bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -35,11 +36,28 @@ output: type: file description: BED file pattern: "*.{bed}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_upd: + - - ${task.process}: + type: string + description: The name of the process + - upd: + type: string + description: The name of the tool + - upd --version 2>&1 | sed 's/upd, version //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - upd: + type: string + description: The name of the tool + - upd --version 2>&1 | sed 's/upd, version //': + type: eval + description: The expression to obtain the version of the tool authors: - "@hrydbeck" maintainers: diff --git a/modules/nf-core/upd/tests/main.nf.test.snap b/modules/nf-core/upd/tests/main.nf.test.snap index 866792f11..d6af9ef77 100644 --- a/modules/nf-core/upd/tests/main.nf.test.snap +++ b/modules/nf-core/upd/tests/main.nf.test.snap @@ -12,7 +12,11 @@ ] ], "1": [ - "versions.yml:md5,3fef0b4c41b8cbf95be59f62771e38ea" + [ + "UPD", + "upd", + "0.1" + ] ], "bed": [ [ @@ -23,16 +27,20 @@ "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,3fef0b4c41b8cbf95be59f62771e38ea" + "versions_upd": [ + [ + "UPD", + "upd", + "0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-27T11:51:33.816939" + "timestamp": "2026-02-04T15:38:45.859374" }, "test-upd": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,3fef0b4c41b8cbf95be59f62771e38ea" + [ + "UPD", + "upd", + "0.1" + ] ], "bed": [ [ @@ -58,15 +70,19 @@ "test.bed:md5,beea3890636075d5c99db1b0d74f9ff5" ] ], - "versions": [ - "versions.yml:md5,3fef0b4c41b8cbf95be59f62771e38ea" + "versions_upd": [ + [ + "UPD", + "upd", + "0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-08-27T11:51:29.35452" + "timestamp": "2026-02-04T15:38:42.052606" } } \ No newline at end of file diff --git a/modules/nf-core/vcf2cytosure/environment.yml b/modules/nf-core/vcf2cytosure/environment.yml index d078bfaed..32517278a 100644 --- a/modules/nf-core/vcf2cytosure/environment.yml +++ b/modules/nf-core/vcf2cytosure/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::vcf2cytosure=0.9.1 + - bioconda::vcf2cytosure=0.9.3 diff --git a/modules/nf-core/vcf2cytosure/main.nf b/modules/nf-core/vcf2cytosure/main.nf index 92351337a..f356456b3 100644 --- a/modules/nf-core/vcf2cytosure/main.nf +++ b/modules/nf-core/vcf2cytosure/main.nf @@ -4,8 +4,8 @@ process VCF2CYTOSURE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/vcf2cytosure:0.9.1--pyh7cba7a3_1': - 'biocontainers/vcf2cytosure:0.9.1--pyh7cba7a3_1' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/58/584cf1de62ed0d65a064456ec0d052d6b657b3245c8f10c626bca7131884c0fc/data': + 'community.wave.seqera.io/library/pip_vcf2cytosure:6852c55eb4c9d406' }" input: tuple val(meta), path(sv_vcf) @@ -16,7 +16,7 @@ process VCF2CYTOSURE { output: tuple val(meta), path("*.cgh"), emit: cgh - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('vcf2cytosure'), eval("vcf2cytosure --version 2>&1 | sed -n 's/.*cytosure //p'"), topic: versions, emit: versions_vcf2cytosure when: task.ext.when == null || task.ext.when @@ -40,27 +40,11 @@ process VCF2CYTOSURE { $snv \\ $blacklist \\ $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - vcf2cytosure: \$(echo \$(vcf2cytosure --version 2>&1) | sed 's/^.* cytosure //' ) - END_VERSIONS """ stub: - def args = task.ext.args ?: '' - def coverage = coverage_bed ? "--coverage ${coverage_bed}" : '' - def cnvkit = cns ? ( coverage_bed ? '' : "--cn ${cns}" ) : '' - def snv = snv_vcf ? ( coverage_bed ? '' : "--snv ${snv_vcf}" ) : '' - def blacklist = blacklist_bed ? "--blacklist ${blacklist_bed}" : '' def prefix = task.ext.prefix ?: "${meta.id}" - """ touch ${prefix}.cgh - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - vcf2cytosure: \$(echo \$(vcf2cytosure --version 2>&1) | sed 's/^.* cytosure //' ) - END_VERSIONS """ } diff --git a/modules/nf-core/vcf2cytosure/meta.yml b/modules/nf-core/vcf2cytosure/meta.yml index 0c38d9c8d..517f80fdd 100644 --- a/modules/nf-core/vcf2cytosure/meta.yml +++ b/modules/nf-core/vcf2cytosure/meta.yml @@ -25,6 +25,7 @@ input: type: file description: VCF file with structural variants pattern: "*.{vcf,vcf.gz}" + ontologies: [] - - meta2: type: map description: | @@ -34,6 +35,7 @@ input: type: file description: Bed file with coverage data pattern: "*.bed" + ontologies: [] - - meta3: type: map description: | @@ -42,6 +44,7 @@ input: - cns: type: file description: CN file from CNVkit, not compatible with coverage_bed file + ontologies: [] - - meta4: type: map description: | @@ -53,13 +56,15 @@ input: VCF file with SNVs to calculate probe coverage, not compatible with coverage_bed pattern: "*.{vcf,vcf.gz}" - - - blacklist_bed: - type: file - description: Bed file with regions to exclude - pattern: "*.bed" + ontologies: [] + - blacklist_bed: + type: file + description: Bed file with regions to exclude + pattern: "*.bed" + ontologies: [] output: - - cgh: - - meta: + cgh: + - - meta: type: map description: | Groovy Map containing sample information @@ -68,10 +73,27 @@ output: type: file description: SV:s in CytoSure format pattern: "*.cgh" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_vcf2cytosure: + - - ${task.process}: + type: string + description: The name of the process + - vcf2cytosure: + type: string + description: The name of the tool + - vcf2cytosure --version 2>&1 | sed -n 's/.*cytosure //p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - vcf2cytosure: + type: string + description: The name of the tool + - vcf2cytosure --version 2>&1 | sed -n 's/.*cytosure //p': + type: eval + description: The expression to obtain the version of the tool authors: - "@jemten" diff --git a/modules/nf-core/vcf2cytosure/tests/main.nf.test b/modules/nf-core/vcf2cytosure/tests/main.nf.test index edd3063d6..a6d4bcd34 100644 --- a/modules/nf-core/vcf2cytosure/tests/main.nf.test +++ b/modules/nf-core/vcf2cytosure/tests/main.nf.test @@ -31,8 +31,9 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.cgh).match("cgh") }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot( + process.out.cgh, + process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } @@ -63,8 +64,9 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.cgh).match("cgh - stub") }, - { assert snapshot(process.out.versions).match("versions - stub") } + { assert snapshot( + process.out.cgh, + process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } diff --git a/modules/nf-core/vcf2cytosure/tests/main.nf.test.snap b/modules/nf-core/vcf2cytosure/tests/main.nf.test.snap index 0a0fae292..d0e0b8135 100644 --- a/modules/nf-core/vcf2cytosure/tests/main.nf.test.snap +++ b/modules/nf-core/vcf2cytosure/tests/main.nf.test.snap @@ -1,26 +1,31 @@ { - "cgh": { + "homo sapiens - vcf - bed": { "content": [ [ [ { "id": "test" }, - "test.cgh:md5,fc3f1ffac5b797881d992994d5d56550" + "test.cgh:md5,c9bcda3fafe67359e353bedf02d041e8" ] - ] - ], - "timestamp": "2023-12-21T18:33:25.202806" - }, - "versions": { - "content": [ - [ - "versions.yml:md5,a1850e66d57cee0b98adb056c1dc3ebb" - ] + ], + { + "versions_vcf2cytosure": [ + [ + "VCF2CYTOSURE", + "vcf2cytosure", + "0.9.3" + ] + ] + } ], - "timestamp": "2023-12-21T18:33:25.205826" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:29:44.501025" }, - "cgh - stub": { + "homo sapiens - vcf - bed - stub": { "content": [ [ [ @@ -29,16 +34,21 @@ }, "test.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ] - ], - "timestamp": "2023-12-21T18:38:06.660655" - }, - "versions - stub": { - "content": [ - [ - "versions.yml:md5,a1850e66d57cee0b98adb056c1dc3ebb" - ] + ], + { + "versions_vcf2cytosure": [ + [ + "VCF2CYTOSURE", + "vcf2cytosure", + "0.9.3" + ] + ] + } ], - "timestamp": "2023-12-21T18:38:06.663571" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:29:50.263249" } } \ No newline at end of file diff --git a/modules/nf-core/vcf2cytosure/tests/tags.yml b/modules/nf-core/vcf2cytosure/tests/tags.yml deleted file mode 100644 index 88ff60385..000000000 --- a/modules/nf-core/vcf2cytosure/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -vcf2cytosure: - - "modules/nf-core/vcf2cytosure/**" diff --git a/modules/nf-core/vcfanno/environment.yml b/modules/nf-core/vcfanno/environment.yml index 32c48b15b..a625e831c 100644 --- a/modules/nf-core/vcfanno/environment.yml +++ b/modules/nf-core/vcfanno/environment.yml @@ -1,5 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda + dependencies: - - bioconda::vcfanno=0.3.5 + - bioconda::htslib=1.23 + - bioconda::vcfanno=0.3.7 diff --git a/modules/nf-core/vcfanno/main.nf b/modules/nf-core/vcfanno/main.nf index 25c131b1d..8c5e466f4 100644 --- a/modules/nf-core/vcfanno/main.nf +++ b/modules/nf-core/vcfanno/main.nf @@ -4,8 +4,8 @@ process VCFANNO { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/vcfanno:0.3.5--h9ee0642_0': - 'biocontainers/vcfanno:0.3.5--h9ee0642_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b23fffa38d9740616e3b414df24e44c22fbc0510264f79b5062b3eecd619393f/data': + 'community.wave.seqera.io/library/htslib_vcfanno:c88d6077509197fe' }" input: tuple val(meta), path(vcf), path(tbi), path(specific_resources) @@ -14,15 +14,18 @@ process VCFANNO { path resources output: - tuple val(meta), path("*.vcf") , emit: vcf - path "versions.yml" , emit: versions + tuple val(meta), path("*.vcf.gz") , emit: vcf + tuple val(meta), path("*.vcf.gz.tbi") , emit: tbi + tuple val("${task.process}"), val('vcfanno'), eval("vcfanno 2>&1 | sed -n 's/.*version \\([0-9.]\\+\\).*/\\1/p'"), topic: versions, emit: versions_vcfanno when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def args3 = task.ext.args3 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def lua_cmd = lua ? "--lua ${lua}" : "" """ vcfanno \\ @@ -31,22 +34,17 @@ process VCFANNO { ${lua_cmd} \\ ${toml} \\ ${vcf} \\ - > ${prefix}.vcf + | bgzip ${args2} --threads ${task.cpus} \\ + > ${prefix}.vcf.gz \\ + && tabix ${args3} ${prefix}.vcf.gz - cat <<-END_VERSIONS > versions.yml - "${task.process}": - vcfanno: \$(echo \$(vcfanno 2>&1 | grep version | cut -f3 -d' ' )) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf + echo "" | gzip > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi - cat <<-END_VERSIONS > versions.yml - "${task.process}": - vcfanno: \$(echo \$(vcfanno 2>&1 | grep version | cut -f3 -d' ' )) - END_VERSIONS """ } diff --git a/modules/nf-core/vcfanno/meta.yml b/modules/nf-core/vcfanno/meta.yml index 18d27127c..70d5e4f7e 100644 --- a/modules/nf-core/vcfanno/meta.yml +++ b/modules/nf-core/vcfanno/meta.yml @@ -1,6 +1,6 @@ name: vcfanno -description: quickly annotate your VCF with any number of INFO fields from any number - of VCFs or BED files +description: quickly annotate your VCF with any number of INFO fields from any + number of VCFs or BED files keywords: - vcf - bed @@ -26,45 +26,83 @@ input: type: file description: query VCF file pattern: "*.{vcf, vcf.gz}" + ontologies: [] - tbi: type: file description: tabix index file for the query VCF pattern: "*.tbi" + ontologies: [] - specific_resources: type: map - description: A list of sample specific reference files defined in toml config, - must also include indices if bgzipped. - - - toml: - type: file - description: configuration file with reference file basenames - pattern: "*.toml" - - - lua: - type: file - description: Lua file for custom annotations - pattern: "*.lua" - - - resources: - type: map - description: List of reference files defined in toml config, must also include - indices if bgzipped. + description: A list of sample specific reference files defined in toml + config, must also include indices if bgzipped. + - toml: + type: file + description: configuration file with reference file basenames + pattern: "*.toml" + ontologies: [] + - lua: + type: file + description: Lua file for custom annotations + pattern: "*.lua" + ontologies: [] + - resources: + type: map + description: List of reference files defined in toml config, must also + include indices if bgzipped. output: - - vcf: - - meta: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz" + - "*.vcf.gz": + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz" + tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz" + - "*.vcf.gz.tbi": type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.vcf": - type: file - description: Annotated VCF file - pattern: "*.vcf" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + pattern: "*.vcf.gz.tbi" + versions_vcfanno: + - - ${task.process}: + type: string + description: The name of the process + - vcfanno: + type: string + description: The name of the tool + - vcfanno 2>&1 | sed -n 's/.*version \([0-9.]\+\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - vcfanno: + type: string + description: The name of the tool + - vcfanno 2>&1 | sed -n 's/.*version \([0-9.]\+\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool authors: - "@projectoriented" - "@matthdsm" + - "@nvnieuwk" maintainers: - "@projectoriented" - "@matthdsm" + - "@nvnieuwk" diff --git a/modules/nf-core/vcfanno/tests/main.nf.test b/modules/nf-core/vcfanno/tests/main.nf.test index 8bbcfd894..ef6eb4b5d 100644 --- a/modules/nf-core/vcfanno/tests/main.nf.test +++ b/modules/nf-core/vcfanno/tests/main.nf.test @@ -24,7 +24,7 @@ nextflow_process { input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz.tbi",checkIfExists: true) - ] + ] """ } } @@ -54,7 +54,7 @@ nextflow_process { input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz.tbi",checkIfExists: true) - ] + ] """ } } @@ -86,7 +86,7 @@ nextflow_process { input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz.tbi",checkIfExists: true) - ] + ] """ } } diff --git a/modules/nf-core/vcfanno/tests/main.nf.test.snap b/modules/nf-core/vcfanno/tests/main.nf.test.snap index 7e5f737c5..731848b5d 100644 --- a/modules/nf-core/vcfanno/tests/main.nf.test.snap +++ b/modules/nf-core/vcfanno/tests/main.nf.test.snap @@ -1,12 +1,14 @@ { "sarscov2 - [vcf(gz), tbi, vcf], [], toml, [vcf, tbi] - stub": { "content": [ - "test_compressed.vcf", - [ - "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" - ] + "test_compressed.vcf.gz", + null ], - "timestamp": "2023-12-06T12:18:25.69588598" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T13:57:00.201785" }, "sarscov2 - [vcf(gz), tbi, vcf], [], toml, [vcf, tbi]": { "content": [ @@ -17,11 +19,33 @@ "id": "test_compressed", "single_end": false }, - "test_compressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_compressed.vcf.gz:md5,f816458edc4df57f2617070fe1b939ea" ] ], "1": [ - "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" + [ + { + "id": "test_compressed", + "single_end": false + }, + "test_compressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], + "2": [ + [ + "VCFANNO", + "vcfanno", + "0.3.7" + ] + ], + "tbi": [ + [ + { + "id": "test_compressed", + "single_end": false + }, + "test_compressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] ], "vcf": [ [ @@ -29,15 +53,23 @@ "id": "test_compressed", "single_end": false }, - "test_compressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_compressed.vcf.gz:md5,f816458edc4df57f2617070fe1b939ea" ] ], - "versions": [ - "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" + "versions_vcfanno": [ + [ + "VCFANNO", + "vcfanno", + "0.3.7" + ] ] } ], - "timestamp": "2023-12-06T12:21:13.209704154" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:57:31.157631" }, "sarscov2 - [vcf, [], vcf], [], toml, [vcf, tbi]": { "content": [ @@ -48,11 +80,33 @@ "id": "test_uncompressed", "single_end": false }, - "test_uncompressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_uncompressed.vcf.gz:md5,f816458edc4df57f2617070fe1b939ea" ] ], "1": [ - "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" + [ + { + "id": "test_uncompressed", + "single_end": false + }, + "test_uncompressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], + "2": [ + [ + "VCFANNO", + "vcfanno", + "0.3.7" + ] + ], + "tbi": [ + [ + { + "id": "test_uncompressed", + "single_end": false + }, + "test_uncompressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] ], "vcf": [ [ @@ -60,14 +114,22 @@ "id": "test_uncompressed", "single_end": false }, - "test_uncompressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_uncompressed.vcf.gz:md5,f816458edc4df57f2617070fe1b939ea" ] ], - "versions": [ - "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" + "versions_vcfanno": [ + [ + "VCFANNO", + "vcfanno", + "0.3.7" + ] ] } ], - "timestamp": "2023-12-06T12:21:19.255212216" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:57:35.91459" } } \ No newline at end of file diff --git a/modules/nf-core/vcfanno/tests/nextflow.config b/modules/nf-core/vcfanno/tests/nextflow.config index af28ad82e..b22599fc2 100644 --- a/modules/nf-core/vcfanno/tests/nextflow.config +++ b/modules/nf-core/vcfanno/tests/nextflow.config @@ -1,4 +1,4 @@ process { - - -} \ No newline at end of file + + +} diff --git a/modules/nf-core/vcfanno/tests/tags.yml b/modules/nf-core/vcfanno/tests/tags.yml deleted file mode 100644 index e861bd53e..000000000 --- a/modules/nf-core/vcfanno/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -vcfanno: - - "modules/nf-core/vcfanno/**" diff --git a/modules/nf-core/verifybamid/verifybamid2/main.nf b/modules/nf-core/verifybamid/verifybamid2/main.nf index 9568fee95..7bf68ce98 100644 --- a/modules/nf-core/verifybamid/verifybamid2/main.nf +++ b/modules/nf-core/verifybamid/verifybamid2/main.nf @@ -3,9 +3,9 @@ process VERIFYBAMID_VERIFYBAMID2 { label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/verifybamid2:2.0.1--hbb20b25_6' : - 'biocontainers/verifybamid2:2.0.1--h19d48f6_8' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/97/9700eb810dc7a72011c9149b8ab6cc7fa9d273795632ddd00af019ab32816811/data' + : 'community.wave.seqera.io/library/verifybamid2:2.0.1--166cf392bec584ce'}" input: tuple val(meta), path(bam), path(bai) @@ -20,7 +20,7 @@ process VERIFYBAMID_VERIFYBAMID2 { tuple val(meta), path("*.mu") , optional:true, emit: mu tuple val(meta), path("*.selfSM") , optional:true, emit: self_sm tuple val(meta), path("*.Ancestry") , optional:true, emit: ancestry - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('verifybamid2'), eval("verifybamid2 --help 2>&1 | sed -n '3s/.*Version://p'"), topic: versions, emit: versions_verifybamid2 when: task.ext.when == null || task.ext.when @@ -36,23 +36,19 @@ process VERIFYBAMID_VERIFYBAMID2 { "--SVDPrefix ${svd_ud.baseName}" : "--UDPath ${svd_ud} --MeanPath ${svd_mu} --BedPath ${svd_bed}" def refvcf_args = "${refvcf}".endsWith(".vcf") ? "--RefVCF ${refvcf}" : "" - def reference_args = ("$references".endsWith('.fasta')) ? - "--Reference ${references}" : '' + def reference_args = "${references}".matches(/.+((fasta)|(fa)|(fna))(\.gz)*$/) + ? "--Reference ${references}" + : '' """ verifybamid2 \\ - --NumThread $task.cpus \\ + --NumThread ${task.cpus} \\ ${svd_args} \\ ${bam_file} \\ ${refvcf_args} \\ ${reference_args} \\ ${args_list.join(' ')} \\ > ${prefix}.log - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - verifybamid: \$(echo \$(verifybamid2 --help 2>&1 | sed -e '3p;d' | sed -e 's/ Version://')) - END_VERSIONS """ stub: @@ -64,10 +60,5 @@ process VERIFYBAMID_VERIFYBAMID2 { touch ${prefix}.mu touch ${prefix}.selfSM touch ${prefix}.Ancestry - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - verifybamid: \$(echo \$(verifybamid2 --help 2>&1 | sed -e '3p;d' | sed -e 's/ Version://')) - END_VERSIONS """ } diff --git a/modules/nf-core/verifybamid/verifybamid2/meta.yml b/modules/nf-core/verifybamid/verifybamid2/meta.yml index b511fc3cd..210e1e852 100644 --- a/modules/nf-core/verifybamid/verifybamid2/meta.yml +++ b/modules/nf-core/verifybamid/verifybamid2/meta.yml @@ -1,7 +1,7 @@ name: "VERIFYBAMID_VERIFYBAMID2" -description: Detecting and estimating inter-sample DNA contamination became a crucial - quality assessment step to ensure high quality sequence reads and reliable downstream - analysis. +description: Detecting and estimating inter-sample DNA contamination became a + crucial quality assessment step to ensure high quality sequence reads and + reliable downstream analysis. keywords: - contamination - bam @@ -15,7 +15,8 @@ tools: documentation: "http://griffan.github.io/VerifyBamID" tool_dev_url: "https://github.com/Griffan/VerifyBamID" doi: "10.1101/gr.246934.118" - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:verifybamid input: - - meta: @@ -27,34 +28,42 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: BAI/CRAI/CSI index file pattern: "*.{bai,crai,csi}" + ontologies: [] - - svd_ud: type: file description: .UD matrix file from SVD result of genotype matrix pattern: "*.UD" + ontologies: [] - svd_mu: type: file description: .mu matrix file of genotype matrix pattern: "*.mu" + ontologies: [] - svd_bed: type: file - description: .Bed file for markers used in this analysis,format(chr\tpos-1\tpos\trefAllele\taltAllele)[Required] + description: .Bed file for markers used in this + analysis,format(chr\tpos-1\tpos\trefAllele\taltAllele)[Required] pattern: "*.bed" - - - refvcf: - type: file - description: Reference panel VCF with genotype information, for generation of - .UD .mu .bed files [Optional] - pattern: "*.vcf" - - - references: - type: file - description: reference file [Required] - pattern: "*.fasta" + ontologies: [] + - refvcf: + type: file + description: Reference panel VCF with genotype information, for generation + of .UD .mu .bed files [Optional] + pattern: "*.vcf" + ontologies: [] + - references: + type: file + description: reference file [Required] + pattern: "*.fasta" + ontologies: [] output: - - log: - - meta: + log: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,8 +72,9 @@ output: type: file description: Detailed summary of the VerifyBamId2 results pattern: "*.log" - - ud: - - meta: + ontologies: [] + ud: + - - meta: type: map description: | Groovy Map containing sample information @@ -73,8 +83,9 @@ output: type: file description: .UD matrix file from customized reference vcf input pattern: "*.UD" - - bed: - - meta: + ontologies: [] + bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -83,30 +94,33 @@ output: type: file description: .Bed file from customized reference marker vcf input pattern: "*.bed" - - mu: - - meta: + ontologies: [] + mu: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.mu": type: file - description: .mu matrix file of genotype matrix from customized reference vcf - input + description: .mu matrix file of genotype matrix from customized + reference vcf input pattern: "*.mu" - - self_sm: - - meta: + ontologies: [] + self_sm: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.selfSM": type: file - description: Shares the same format as legacy VB1 and the key information FREEMIX - indicates the estimated contamination level. + description: Shares the same format as legacy VB1 and the key + information FREEMIX indicates the estimated contamination level. pattern: "*.selfSM" - - ancestry: - - meta: + ontologies: [] + ancestry: + - - meta: type: map description: | Groovy Map containing sample information @@ -115,11 +129,28 @@ output: type: file description: Ancestry information pattern: "*.Ancestry" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_verifybamid2: + - - ${task.process}: + type: string + description: The name of the process + - verifybamid2: + type: string + description: The name of the tool + - verifybamid2 --help 2>&1 | sed -n '3s/.*Version://p': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - verifybamid2: + type: string + description: The name of the tool + - verifybamid2 --help 2>&1 | sed -n '3s/.*Version://p': + type: eval + description: The expression to obtain the version of the tool authors: - "@manifestoso" maintainers: diff --git a/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test b/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test index 99acd6844..e9f2e0101 100644 --- a/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test +++ b/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test @@ -60,13 +60,14 @@ nextflow_process { process.out.mu, process.out.self_sm, process.out.ancestry, - process.out.versions, + process.out.findAll { key, val -> key.startsWith("versions") }, file(process.out.ud[0][1]).name ).match() } ) } } + test("Should run with panel input") { config "./nextflow.config" @@ -90,7 +91,7 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.log[0][1]).name, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) } @@ -119,7 +120,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["log", "bed", "mu", "ud", "self_sm", "ancestry"]) + ).match() } ) } } @@ -145,7 +147,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["log", "bed", "mu", "ud", "self_sm", "ancestry"]) + ).match() } ) } } @@ -173,8 +176,68 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["log", "bed", "mu", "ud", "self_sm", "ancestry"]) + ).match() } + ) + } + } + + test("Should run with alternative .fa reference input -stub") { + config "./nextflow.config" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai') ] + input[1] = [ [], [], [] ] + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf') + input[3] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genomeGRCh38_chr21_22.fa.gz') + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.log[0][1]).name, + process.out.bed, + process.out.mu, + process.out.self_sm, + process.out.ancestry, + process.out.findAll { key, val -> key.startsWith("versions") }, + file(process.out.ud[0][1]).name + ).match() } + ) + } + } + + test("Should run with alternative .fa reference input") { + config "./nextflow.config" + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai') ] + input[1] = [ [], [], [] ] + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf') + input[3] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genomeGRCh38_chr21_22.fa.gz') + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out, unstableKeys: ["log", "bed", "mu", "ud", "self_sm", "ancestry"]) + ).match() } ) } } -} \ No newline at end of file +} diff --git a/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test.snap b/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test.snap index 9bc0853a4..31316fe0a 100644 --- a/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test.snap +++ b/modules/nf-core/verifybamid/verifybamid2/tests/main.nf.test.snap @@ -1,78 +1,77 @@ { - "Should run with panel input": { + "Should run with alternative .fa reference input -stub": { "content": [ "test.log", [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" - ] + [ + { + "id": "test", + "single_end": false + }, + "test.genome.vcf.bed:md5,47106c764019ee359b1936410e2efa1e" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.genome.vcf.mu:md5,0810db02af2a176fa5ddc0f404911b66" + ] + ], + [ + + ], + [ + + ], + { + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] + ] + }, + "test.genome.vcf.UD" ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-10-22T13:02:25.962766167" + "timestamp": "2026-02-04T15:06:31.079305" }, - "Should run with panel input - stub": { + "Should run with panel input": { "content": [ + "test.log", { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ + "versions_verifybamid2": [ [ - { - "id": "test", - "single_end": false - }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" ] - ], - "5": [ - [ - { - "id": "test", - "single_end": false - }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "6": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" - ], + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:06:11.925134" + }, + "Should run with panel input - stub": { + "content": [ + { "ancestry": [ [ { "id": "test", "single_end": false }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Ancestry" ] ], "bed": [ @@ -81,7 +80,7 @@ "id": "test", "single_end": false }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bed" ] ], "log": [ @@ -90,7 +89,7 @@ "id": "test", "single_end": false }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.log" ] ], "mu": [ @@ -99,7 +98,7 @@ "id": "test", "single_end": false }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.mu" ] ], "self_sm": [ @@ -108,84 +107,103 @@ "id": "test", "single_end": false }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.selfSM" ] ], "ud": [ ], - "versions": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-05-05T16:46:04.375799563" + "timestamp": "2026-02-04T15:12:24.048732" }, "Should run with RefVCF input - stub": { "content": [ { - "0": [ + "ancestry": [ [ { "id": "test", "single_end": false }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Ancestry" ] ], - "1": [ - - ], - "2": [ + "bed": [ [ { "id": "test", "single_end": false }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bed" ] ], - "3": [ + "log": [ [ { "id": "test", "single_end": false }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.log" ] ], - "4": [ + "mu": [ [ { "id": "test", "single_end": false }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.mu" ] ], - "5": [ + "self_sm": [ [ { "id": "test", "single_end": false }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.selfSM" ] ], - "6": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + "ud": [ + ], + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-04T15:12:19.940733" + }, + "Should run with alternative .fa reference input": { + "content": [ + { "ancestry": [ [ { "id": "test", "single_end": false }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Ancestry" ] ], "bed": [ @@ -194,7 +212,7 @@ "id": "test", "single_end": false }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bed" ] ], "log": [ @@ -203,7 +221,7 @@ "id": "test", "single_end": false }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.log" ] ], "mu": [ @@ -212,7 +230,7 @@ "id": "test", "single_end": false }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.mu" ] ], "self_sm": [ @@ -221,22 +239,26 @@ "id": "test", "single_end": false }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.selfSM" ] ], "ud": [ ], - "versions": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-05-05T16:45:57.687144464" + "timestamp": "2026-02-04T15:12:37.072815" }, "Should run with SVD input": { "content": [ @@ -278,7 +300,11 @@ ] ], "6": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] ], "ancestry": [ [ @@ -316,16 +342,20 @@ "ud": [ ], - "versions": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] ] } ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-11-05T20:51:39.853534509" + "timestamp": "2026-02-04T15:00:42.110941" }, "Should run with RefVCF input": { "content": [ @@ -354,78 +384,33 @@ [ ], - [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" - ], + { + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] + ] + }, "test.genome.vcf.UD" ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-11-20T13:43:20.984216864" + "timestamp": "2026-02-04T15:06:07.266104" }, "Should run with SVD input - stub": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - [ - { - "id": "test", - "single_end": false - }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "5": [ - [ - { - "id": "test", - "single_end": false - }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "6": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" - ], "ancestry": [ [ { "id": "test", "single_end": false }, - "test.Ancestry:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Ancestry" ] ], "bed": [ @@ -434,7 +419,7 @@ "id": "test", "single_end": false }, - "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bed" ] ], "log": [ @@ -443,7 +428,7 @@ "id": "test", "single_end": false }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.log" ] ], "mu": [ @@ -452,7 +437,7 @@ "id": "test", "single_end": false }, - "test.mu:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.mu" ] ], "self_sm": [ @@ -461,21 +446,25 @@ "id": "test", "single_end": false }, - "test.selfSM:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.selfSM" ] ], "ud": [ ], - "versions": [ - "versions.yml:md5,199f2e02b570926d6a249055c917c6b1" + "versions_verifybamid2": [ + [ + "VERIFYBAMID_VERIFYBAMID2", + "verifybamid2", + "2.0.1" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-05-05T16:40:02.231564621" + "timestamp": "2026-02-04T15:12:16.230109" } } \ No newline at end of file diff --git a/nextflow.config b/nextflow.config index c45672bb0..9991c8399 100644 --- a/nextflow.config +++ b/nextflow.config @@ -14,36 +14,50 @@ params { // References genome = 'GRCh38' + heavy_strand_origin_start = 16081 + heavy_strand_origin_end = 407 igenomes_base = 's3://ngi-igenomes/igenomes/' igenomes_ignore = false + light_strand_origin_start = 5730 + light_strand_origin_end = 5763 local_genomes = null save_reference = false mito_name = 'chrM' + mito_length = 16569 // Main options - analysis_type = 'wgs' - bwa_as_fallback = false - bait_padding = 100 - concatenate_snv_calls = false - extract_alignments = false - restrict_to_contigs = null - run_mt_for_wes = false - run_rtgvcfeval = false - save_mapped_as_cram = false - scatter_count = 20 - skip_tools = null - skip_subworkflows = null - cadd_resources = null - platform = 'illumina' + analysis_type = 'wgs' + bait_padding = 100 + cadd_resources = null + concatenate_snv_calls = false + exclude_alt = false + extract_alignments = false + mt_subsample_approach = 'reads' + mt_subsample_reads = 18000 + restrict_to_contigs = null + run_mt_for_wes = false + run_rtgvcfeval = false + run_vcfanno_db_sanity_check = false + save_all_mapped_as_cram = false + save_noalt_mapped_as_cram = false + scatter_count = 20 + skip_split_multiallelics = false + skip_subworkflows = null + skip_tools = null + platform = 'illumina' // reference file options fasta = null fai = null bwa = null + bwafastalign = null bwamem2 = null bwameme = null call_interval = null + cadd_prescored = null cadd_resources = null + manta_call_regions = null + manta_call_regions_tbi = null gcnvcaller_model = null gens_interval_list = null gens_pon_female = null @@ -51,6 +65,8 @@ params { gens_gnomad_pos = null gnomad_af = null gnomad_af_idx = null + hisat2 = null + hisat2_build_memory = null intervals_wgs = null intervals_y = null known_dbsnp = null @@ -64,6 +80,7 @@ params { reduced_penetrance = null readcount_intervals = null rtg_truthvcfs = null + sambamba_regions = null sample_id_map = null sequence_dictionary = null score_config_mt = null @@ -88,6 +105,8 @@ params { vcfanno_lua = null vep_cache = null vep_plugin_files = null + contamination_sites = null + contamination_sites_tbi = null modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease' @@ -97,7 +116,7 @@ params { // Alignment aligner = 'bwamem2' mt_aligner = 'bwamem2' - mbuffer_mem = 3072 + mbuffer_mem = 8192 samtools_sort_threads = 4 min_trimmed_length = 40 mt_subsample_rd = 150 @@ -107,19 +126,43 @@ params { // Variant calling cnvnator_binsize = 1000 variant_caller = 'deepvariant' + homoplasmy_af_threshold = 1 // variant annotation vep_cache_version = 112 // sentieon Defaults - ml_model = '' + ml_model = null // Dnascope SNV calling sentieon_dnascope_pcr_indel_model = 'CONSERVATIVE' variant_type = 'snp,indel' + // Mitosalt and saltshaker options + mitosalt_breakspan = 15 + mitosalt_breakthreshold = 2 + mitosalt_cluster_threshold = 5 + mitosalt_deletion_threshold_max = 30000 + mitosalt_deletion_threshold_min = 30 + mitosalt_evalue_threshold = 0.00001 + mitosalt_exclude = 5 + mitosalt_flank = 15 + mitosalt_heteroplasmy_limit = 0.01 + mitosalt_depth = 10000000 + mitosalt_paired_distance = 1000 + mitosalt_score_threshold = 80 + mitosalt_sizelimit = 10000 + mitosalt_split_distance_threshold = 5 + mitosalt_split_length = 15 + saltshaker_dominant_fraction = 0.5 + saltshaker_group_radius = 600 + saltshaker_high_heteroplasmy = 10 + saltshaker_multiple_threshold = 5 + saltshaker_noise_threshold = 0.3 + // MultiQC options multiqc_config = null + multiqc_samples = null multiqc_title = null multiqc_logo = null max_multiqc_email_size = '25.MB' @@ -132,13 +175,14 @@ params { email_on_fail = null plaintext_email = false monochrome_logs = false - hook_url = null help = false help_full = false show_hidden = false version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' - trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')// Config options + trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') + + // Config options config_profile_name = null config_profile_description = null @@ -151,6 +195,10 @@ 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' @@ -191,7 +239,18 @@ profiles { apptainer.enabled = false docker.runOptions = '-u $(id -u):$(id -g)' } - arm { + arm64 { + process.arch = 'arm64' + // TODO https://github.com/nf-core/modules/issues/6694 + // For now if you're using arm64 you have to use wave for the sake of the maintainers + // wave profile + apptainer.ociAutoPull = true + singularity.ociAutoPull = true + wave.enabled = true + wave.freeze = true + wave.strategy = 'conda,container' + } + emulate_amd64 { docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' } singularity { @@ -248,18 +307,6 @@ profiles { wave.freeze = true wave.strategy = 'conda,container' } - gitpod { - executor.name = 'local' - executor.cpus = 4 - executor.memory = 8.GB - process { - resourceLimits = [ - memory: 8.GB, - cpus : 4, - time : 1.h - ] - } - } test { includeConfig 'conf/test.config' } test_full { includeConfig 'conf/test_full.config' } test_singleton { includeConfig 'conf/test_singleton.config' } @@ -272,6 +319,11 @@ profiles { } } +// Set AWS client to anonymous when using the default igenomes_base +aws.client.anonymous = !params.igenomes_ignore && params.igenomes_base?.startsWith('s3://ngi-igenomes/igenomes/') ?: false +// Stage locally scoped binary scripts +// nextflow.enable.moduleBinaries = true + // Load nf-core custom profiles from different institutions // If params.custom_config_base is set AND either the NXF_OFFLINE environment variable is not set or params.custom_config_base is a local path, the nfcore_custom.config file from the specified base path is included. @@ -337,7 +389,6 @@ dag { manifest { name = 'nf-core/raredisease' - author = """Clinical Genomics Stockholm""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead contributors = [ [ name: 'Ramprasad Neethiraj', @@ -435,8 +486,8 @@ manifest { description = """call and score variants from WGS/WES of rare disease patients""" mainScript = 'main.nf' defaultBranch = 'master' - nextflowVersion = '!>=24.04.2' - version = '2.6.0' + nextflowVersion = '!>=25.10.4' + version = '3.2.0dev' doi = '10.5281/zenodo.7995798' } @@ -473,44 +524,20 @@ includeConfig 'conf/modules/call_sv_tiddit.config' includeConfig 'conf/modules/postprocess_MT_calls.config' includeConfig 'conf/modules/call_mobile_elements.config' includeConfig 'conf/modules/annotate_mobile_elements.config' -includeConfig 'conf/modules/generate_clinical_set.config' +includeConfig 'conf/modules/vcf_filter_bcftools_filtervep.config' includeConfig 'conf/modules/variant_evaluation.config' -includeConfig 'conf/modules/subsample_mt.config' +includeConfig 'conf/modules/subsample_mt_frac.config' +includeConfig 'conf/modules/subsample_mt_reads.config' includeConfig 'conf/modules/annotate_rhocallviz.config' +includeConfig 'conf/modules/contamination_check.config' + // Nextflow plugins plugins { - id 'nf-schema@2.3.0' // Validation of pipeline parameters and creation of an input channel from a sample sheet + id 'nf-schema@2.5.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet } validation { defaultIgnoreParams = ["genomes"] monochromeLogs = params.monochrome_logs - help { - enabled = true - command = "nextflow run nf-core/raredisease -profile --input samplesheet.csv --outdir " - fullParameter = "help_full" - showHiddenParameter = "show_hidden" - beforeText = """ --\033[2m----------------------------------------------------\033[0m- - \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m -\033[0;34m ___ __ __ __ ___ \033[0;32m/,-._.--~\'\033[0m -\033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m -\033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m - \033[0;32m`._,._,\'\033[0m -\033[0;35m nf-core/raredisease ${manifest.version}\033[0m --\033[2m----------------------------------------------------\033[0m- -""" - afterText = """${manifest.doi ? "\n* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} -* The nf-core framework - https://doi.org/10.1038/s41587-020-0439-x - -* Software dependencies - https://github.com/nf-core/raredisease/blob/master/CITATIONS.md -""" - } - summary { - beforeText = validation.help.beforeText - afterText = validation.help.afterText - } } diff --git a/nextflow_schema.json b/nextflow_schema.json index 8ece884bf..9ea4f58e2 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -65,6 +65,14 @@ "help_text": "If none provided, will be generated automatically from the FASTA reference.", "fa_icon": "fas fa-folder-open" }, + "bwafastalign": { + "type": "string", + "exists": true, + "format": "directory-path", + "description": "Directory for pre-built bwa-fastalign index.", + "help_text": "If none provided, will be generated automatically from the FASTA reference.", + "fa_icon": "fas fa-folder-open" + }, "bwamem2": { "type": "string", "exists": true, @@ -81,6 +89,14 @@ "help_text": "If none provided, will be generated automatically from the FASTA reference.", "fa_icon": "fas fa-folder-open" }, + "cadd_prescored": { + "type": "string", + "exists": true, + "format": "directory-path", + "fa_icon": "fas fa-folder-open", + "description": "Path to the directory containing pre-scored CADD indel annotations.", + "help_text": "This folder contains the pre-scored indel files that would otherwise be in data/prescored folder as described in https://github.com/kircherlab/CADD-scripts/#manual-installation." + }, "cadd_resources": { "type": "string", "exists": true, @@ -174,7 +190,7 @@ "exists": true, "format": "path", "fa_icon": "fas fa-file", - "pattern": "^\\S+\\.bed(\\.gz)?\\.idx$", + "pattern": "^\\S+\\.tab(\\.gz)?\\.tbi$", "description": "Path to the index file for the gnomad tab file with allele frequencies.", "help_text": "Path to the index of gnomad tab file with CHR/START/REF,ALT/AF" }, @@ -235,6 +251,23 @@ "description": "Local directory base for genome references that map to the config.", "help_text": "This folder is a flat structure with file names that map to the config." }, + "manta_call_regions": { + "type": "string", + "exists": true, + "format": "file-path", + "fa_icon": "fas fa-file", + "pattern": "^\\S+\\.bed\\.gz$", + "description": "Path to a bgzipped BED file restricting Manta SV calling to specific regions (e.g. primary chromosomes). Only applied for WGS; for WES, Manta always uses target_bed instead.", + "help_text": "Must be supplied together with --manta_call_regions_tbi. Only used when analysis_type is wgs — for wes, Manta uses the target_bed supplied via --target_bed and this parameter has no effect. Useful for reducing runtime on references with many short contigs such as GRCh38." + }, + "manta_call_regions_tbi": { + "type": "string", + "exists": true, + "format": "file-path", + "fa_icon": "fas fa-file", + "pattern": "^\\S+\\.bed\\.gz\\.tbi$", + "description": "Tabix index for the file supplied via --manta_call_regions." + }, "mito_name": { "type": "string", "description": "Name of the mitochondrial contig in the reference fasta file", @@ -323,6 +356,14 @@ "pattern": "^\\S+\\.(csv|tsv|json|yaml|yml)$", "schema": "assets/rtg_truthvcfs_schema.json" }, + "sambamba_regions": { + "type": "string", + "exists": true, + "pattern": "^\\S+\\.bed$", + "fa_icon": "fas fa-file", + "format": "file-path", + "description": "A BED file with regions of interest used in sambamba depth." + }, "save_reference": { "type": "boolean", "description": "If generated by the pipeline save the required indices/references in the results directory.", @@ -391,7 +432,7 @@ "exists": true, "format": "path", "fa_icon": "fas fa-file", - "pattern": "^\\S+\\.bed(\\.gz)?$", + "pattern": "^\\S+\\.bed$", "description": "Path to directory for target bed file.", "help_text": "If you would like to limit your analysis to specific regions of the genome, you can pass those regions in a bed file using this option" }, @@ -435,6 +476,23 @@ "description": "Path to UD matrix file from SVD result of genotype matrix. Used by verifybamid2.", "fa_icon": "fas fa-file-csv" }, + "contamination_sites": { + "type": "string", + "exists": true, + "format": "file-path", + "pattern": "^\\S+\\.vcf(\\.gz)?$", + "description": "Path to VCF file with common variants for GATK contamination detection.", + "help_text": "Use small_exac_common_3.hg38.vcf.gz for no_alt reference genomes. This file should contain common SNP sites with population allele frequencies.", + "fa_icon": "fas fa-file" + }, + "contamination_sites_tbi": { + "type": "string", + "exists": true, + "format": "file-path", + "pattern": "^\\S+\\.vcf(\\.gz)?\\.tbi$", + "description": "Index file for contamination sites VCF.", + "fa_icon": "fas fa-file" + }, "vcf2cytosure_blacklist": { "type": "string", "exists": true, @@ -523,24 +581,28 @@ "fa_icon": "fas fa-align-center", "enum": ["wgs", "wes", "mito"] }, - "bwa_as_fallback": { + "concatenate_snv_calls": { "type": "boolean", - "description": "Specifies whether or not to use bwa as a fallback aligner in case bwamem2 throws an error.", - "help_text": "errorStrategy needs to be set to ignore for the bwamem2 process for the fallback to work. Turned off by default.", + "description": "Specifies whether to generate a concatenated VCF file containing both nuclear & mitochondrial snv calls", "fa_icon": "fas fa-toggle-on" }, - "concatenate_snv_calls": { + "exclude_alt": { "type": "boolean", - "description": "Specifies whether to generate a concatenated VCF file containing both nuclear & mitochondrial snv calls", + "description": "After aligning the reads to a reference, remove alignments to alt contigs using samtools view, retaining only primary chromosomes (GRCh37: 1-22,X,Y,MT / GRCh38: chr1-chr22,chrX,chrY,chrM).", "fa_icon": "fas fa-toggle-on" }, "extract_alignments": { "type": "boolean", - "default": "false", "description": "After aligning the reads to a reference, extract alignments from specific regions/contigs and restrict the analysis to those regions/contigs.", "help_text": "Set this to true, and specify the contig(s) using `restrict_to_contigs` parameter", "fa_icon": "fas fa-toggle-on" }, + "homoplasmy_af_threshold": { + "type": "number", + "default": 1.0, + "description": "Allele frequency threshold for mitochondrial variants. Variants with an AF above this threshold will be treated as homoplasmic and assigned a 1/1 genotype. Range 0-1.0.", + "fa_icon": "fas fa-less-than" + }, "platform": { "type": "string", "default": "illumina", @@ -569,9 +631,19 @@ "description": "Specifies whether to run rtgtools' vcfeval", "fa_icon": "fas fa-toggle-on" }, - "save_mapped_as_cram": { + "run_vcfanno_db_sanity_check": { "type": "boolean", - "description": "Specifies whether to generate and publish alignment files as cram instead of bam", + "description": "Specifies whether to check vcfanno database files for zero records and remove the corresponding annotation blocks from the TOML config before running vcfanno", + "fa_icon": "fas fa-toggle-on" + }, + "save_all_mapped_as_cram": { + "type": "boolean", + "description": "Specifies whether to generate and publish all (unfiltered) alignment files as cram instead of bam", + "fa_icon": "fas fa-toggle-on" + }, + "save_noalt_mapped_as_cram": { + "type": "boolean", + "description": "Specifies whether to generate and publish alt-filtered alignment files as cram instead of bam. Requires exclude_alt to be set to true.", "fa_icon": "fas fa-toggle-on" }, "scatter_count": { @@ -580,6 +652,12 @@ "description": "Number of intervals to split your genome into (used to parallelize annotations)", "fa_icon": "fas fa-less-than" }, + "skip_split_multiallelics": { + "type": "boolean", + "fa_icon": "fas fa-forward", + "description": "Skip the split multiallelics step in SNV calling.", + "help_text": "Skips bcftools norm --multiallelics -both in CALL_SNV_SENTIEON and CALL_SNV_DEEPVARIANT. Useful for single-interval runs where the step is unnecessary and can degrade indel quality." + }, "skip_subworkflows": { "type": "string", "fa_icon": "fas fa-forward", @@ -591,8 +669,8 @@ "type": "string", "fa_icon": "fas fa-forward", "description": "Disable specified tools.", - "help_text": "Multiple tools can be specified, separated by commas.", - "pattern": "^((fastp|gens|germlinecnvcaller|haplogrep3|peddy|smncopynumbercaller|vcf2cytosure|fastqc|qualimap|ngsbits|eklipse)?,?)*(?\n \n \n \"nf-core/raredisease\"\n \n\n\n[![GitHub Actions CI Status](https://github.com/nf-core/raredisease/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/ci.yml)\n\n[![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n[![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.1)\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/raredisease)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23raredisease-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/raredisease)[![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#### TOC\n\n- [Introduction](#introduction)\n- [Pipeline summary](#pipeline-summary)\n- [Usage](#usage)\n- [Pipeline output](#pipeline-output)\n- [Credits](#credits)\n- [Contributions and Support](#contributions-and-support)\n- [Citations](#citations)\n\n## Introduction\n\n**nf-core/raredisease** is a best-practice bioinformatic pipeline for calling and scoring variants from WGS/WES data from rare disease patients. This pipeline is heavily inspired by [MIP](https://github.com/Clinical-Genomics/MIP).\n\n> [!NOTE]\n> Right now, we only support paired-end data from Illumina. If you've got other types of data and the pipeline doesn't work for you, just open an issue. We'd be happy to chat about a solution.\n\nThe pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community!\n\nOn release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/raredisease/results).\n\n## Pipeline summary\n\n \n \n \"nf-core/raredisease\n \n\n**1. Metrics:**\n\n- [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)\n- [Mosdepth](https://github.com/brentp/mosdepth)\n- [MultiQC](http://multiqc.info/)\n- [Picard's CollectMutipleMetrics, CollectHsMetrics, and CollectWgsMetrics](https://broadinstitute.github.io/picard/)\n- [Qualimap](http://qualimap.conesalab.org/)\n- [Sentieon's WgsMetricsAlgo](https://support.sentieon.com/manual/usages/general/)\n- [TIDDIT's cov](https://github.com/J35P312/)\n- [VerifyBamID2](https://github.com/Griffan/VerifyBamID)\n\n**2. Alignment:**\n\n- [Bwa-mem2](https://github.com/bwa-mem2/bwa-mem2)\n- [BWA-MEME](https://github.com/kaist-ina/BWA-MEME)\n- [BWA](https://github.com/lh3/bwa)\n- [Sentieon DNAseq](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/)\n\n**3. Variant calling - SNV:**\n\n- [DeepVariant](https://github.com/google/deepvariant)\n- [Sentieon DNAscope](https://support.sentieon.com/manual/DNAscope_usage/dnascope/)\n\n**4. Variant calling - SV:**\n\n- [Manta](https://github.com/Illumina/manta)\n- [TIDDIT's sv](https://github.com/SciLifeLab/TIDDIT)\n- Copy number variant calling:\n - [CNVnator](https://github.com/abyzovlab/CNVnator)\n - [GATK GermlineCNVCaller](https://github.com/broadinstitute/gatk)\n\n**5. Annotation - SNV:**\n\n- [bcftools roh](https://samtools.github.io/bcftools/bcftools.html#roh)\n- [vcfanno](https://github.com/brentp/vcfanno)\n- [CADD](https://cadd.gs.washington.edu/)\n- [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n- [UPD](https://github.com/bjhall/upd)\n- [Chromograph](https://github.com/Clinical-Genomics/chromograph)\n\n**6. Annotation - SV:**\n\n- [SVDB query](https://github.com/J35P312/SVDB#Query)\n- [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n\n**7. Mitochondrial analysis:**\n\n- [Alignment and variant calling - GATK Mitochondrial short variant discovery pipeline ](https://gatk.broadinstitute.org/hc/en-us/articles/4403870837275-Mitochondrial-short-variant-discovery-SNVs-Indels-)\n- [eKLIPse](https://github.com/dooguypapua/eKLIPse/tree/master)\n- Annotation:\n - [HaploGrep2](https://github.com/seppinho/haplogrep-cmd)\n - [Hmtnote](https://github.com/robertopreste/HmtNote)\n - [vcfanno](https://github.com/brentp/vcfanno)\n - [CADD](https://cadd.gs.washington.edu/)\n - [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n\n**8. Variant calling - repeat expansions:**\n\n- [Expansion Hunter](https://github.com/Illumina/ExpansionHunter)\n- [Stranger](https://github.com/Clinical-Genomics/stranger)\n\n**9. Variant calling - mobile elements:**\n\n- [RetroSeq](https://github.com/tk2/RetroSeq)\n\n**10. Rank variants - SV and SNV:**\n\n- [GENMOD](https://github.com/Clinical-Genomics/genmod)\n\n**11. Variant evaluation:**\n\n- [RTG Tools](https://github.com/RealTimeGenomics/rtg-tools)\n\nNote that it is possible to include/exclude certain tools or steps.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet with your input data that looks as follows:\n\n`samplesheet.csv`:\n\n```csv\nsample,lane,fastq_1,fastq_2,sex,phenotype,paternal_id,maternal_id,case_id\nhugelymodelbat,1,reads_1.fastq.gz,reads_2.fastq.gz,1,2,,,justhusky\n```\n\nEach row represents a pair of fastq files (paired end).\n\nSecond, ensure that you have defined the path to reference files and parameters required for the type of analysis that you want to perform. More information about this can be found [here](https://github.com/nf-core/raredisease/blob/dev/docs/usage.md).\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/raredisease \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/raredisease/usage) and the [parameter documentation](https://nf-co.re/raredisease/parameters).\n\n## Pipeline output\n\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/raredisease/output).\n\n## Credits\n\nnf-core/raredisease was written in a collaboration between the Clinical Genomics nodes in Sweden, with major contributions from [Ramprasad Neethiraj](https://github.com/ramprasadn), [Anders Jemt](https://github.com/jemten), [Lucia Pena Perez](https://github.com/Lucpen), and [Mei Wu](https://github.com/projectoriented) at Clinical Genomics Stockholm.\n\nAdditional contributors were [Sima Rahimi](https://github.com/sima-r), [Gwenna Breton](https://github.com/Gwennid) and [Emma V\u00e4sterviga](https://github.com/EmmaCAndersson) (Clinical Genomics Gothenburg); [Halfdan Rydbeck](https://github.com/hrydbeck) and [Lauri Mesilaakso](https://github.com/ljmesi) (Clinical Genomics Link\u00f6ping); [Subazini Thankaswamy Kosalai](https://github.com/sysbiocoder) (Clinical Genomics \u00d6rebro); [Annick Renevey](https://github.com/rannick), [Peter Pruisscher](https://github.com/peterpru) and [Eva Caceres](https://github.com/fevac) (Clinical Genomics Stockholm); [Ryan Kennedy](https://github.com/ryanjameskennedy) (Clinical Genomics Lund); [Anders Sune Pedersen](https://github.com/asp8200) (Danish National Genome Center) and [Lucas Taniguti](https://github.com/lmtani).\n\nWe thank the nf-core community for their extensive assistance in the development of this pipeline.\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 `#raredisease` channel](https://nfcore.slack.com/channels/raredisease) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/raredisease for your analysis, please cite it using the following doi: [10.5281/zenodo.7995798](https://doi.org/10.5281/zenodo.7995798)\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 read more about MIP's use in healthcare in,\n\n> Stranneheim H, Lagerstedt-Robinson K, Magnusson M, et al. Integration of whole genome sequencing into a healthcare setting: high diagnostic rates across multiple clinical entities in 3219 rare disease patients. Genome Med. 2021;13(1):40. doi:10.1186/s13073-021-00855-5\n", + "creativeWorkStatus": "InProgress", + "datePublished": "2026-06-25T13:47:40+00:00", + "description": "

    \n \n \n \"nf-core/raredisease\"\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/raredisease)\n[![GitHub Actions CI Status](https://github.com/nf-core/raredisease/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n[![GitHub Actions Linting Status](https://github.com/nf-core/raredisease/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/raredisease/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/raredisease/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7995798-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7995798)\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/raredisease)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23raredisease-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/raredisease)[![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#### TOC\n\n- [Introduction](#introduction)\n- [Pipeline summary](#pipeline-summary)\n- [Usage](#usage)\n- [Pipeline output](#pipeline-output)\n- [Credits](#credits)\n- [Contributions and Support](#contributions-and-support)\n- [Citations](#citations)\n\n## Introduction\n\n**nf-core/raredisease** is a best-practice bioinformatic pipeline for calling and scoring variants from WGS/WES data from rare disease patients. This pipeline is heavily inspired by [MIP](https://github.com/Clinical-Genomics/MIP).\n\n> [!NOTE]\n> Right now, we only support paired-end data from Illumina. If you've got other types of data and the pipeline doesn't work for you, just open an issue. We'd be happy to chat about a solution.\n\nThe pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community!\n\nOn release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/raredisease/results).\n\n## Pipeline summary\n\n \n \n \"nf-core/raredisease\n \n\n**1. Preprocessing:**\n\n- [fastp](https://github.com/OpenGene/fastp)\n- [Spring](https://github.com/shubhamchandak94/Spring)\n\n**2. Alignment:**\n\n- [Bwa-mem2](https://github.com/bwa-mem2/bwa-mem2)\n- [BWA-MEME](https://github.com/kaist-ina/BWA-MEME)\n- [BWA](https://github.com/lh3/bwa)\n- [Sentieon DNAseq](https://support.sentieon.com/manual/DNAseq_usage/dnaseq/)\n\n**3. Metrics:**\n\n- [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)\n- [Mosdepth](https://github.com/brentp/mosdepth)\n- [MultiQC](http://multiqc.info/)\n- [Picard's CollectMultipleMetrics, CollectHsMetrics, and CollectWgsMetrics](https://broadinstitute.github.io/picard/)\n- [Sambamba](https://github.com/biod/sambamba)\n- [Sentieon's WgsMetricsAlgo](https://support.sentieon.com/manual/usages/general/)\n- [TIDDIT's cov](https://github.com/J35P312/)\n- [VerifyBamID2](https://github.com/Griffan/VerifyBamID)\n\n**4. Sex check:**\n\n- [NGSbits SampleGender](https://github.com/imgag/ngs-bits)\n- [Peddy](https://github.com/brentp/peddy)\n\n**5. Variant calling - SNV:**\n\n- [DeepVariant](https://github.com/google/deepvariant)\n- [Sentieon DNAscope](https://support.sentieon.com/manual/DNAscope_usage/dnascope/)\n\n**6. Variant calling - SV:**\n\n- [Manta](https://github.com/Illumina/manta)\n- [TIDDIT's sv](https://github.com/SciLifeLab/TIDDIT)\n- Copy number variant calling:\n - [CNVnator](https://github.com/abyzovlab/CNVnator)\n - [GATK GermlineCNVCaller](https://github.com/broadinstitute/gatk)\n - [SMNCopyNumberCaller](https://github.com/Illumina/SMNCopyNumberCaller)\n- Mitochondrial SV calling:\n - [MitoSAlt](https://mitosalt.sourceforge.io/)\n - [Saltshaker](https://gitlab.com/genomedx/annotation/saltshaker)\n\n**7. Annotation - SNV:**\n\n- [bcftools roh](https://samtools.github.io/bcftools/bcftools.html#roh)\n- [vcfanno](https://github.com/brentp/vcfanno)\n- [CADD](https://cadd.gs.washington.edu/)\n- [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n- [UPD](https://github.com/bjhall/upd)\n- [Chromograph](https://github.com/Clinical-Genomics/chromograph)\n\n**8. Annotation - SV:**\n\n- [SVDB query](https://github.com/J35P312/SVDB#Query)\n- [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n\n**9. Mitochondrial analysis:**\n\n- [Alignment and variant calling - GATK Mitochondrial short variant discovery pipeline ](https://gatk.broadinstitute.org/hc/en-us/articles/4403870837275-Mitochondrial-short-variant-discovery-SNVs-Indels-)\n- Annotation:\n - [vcfanno](https://github.com/brentp/vcfanno)\n - [CADD](https://cadd.gs.washington.edu/)\n - [VEP](https://www.ensembl.org/info/docs/tools/vep/index.html)\n\n**10. Variant calling - repeat expansions:**\n\n- [Expansion Hunter](https://github.com/Illumina/ExpansionHunter)\n- [Stranger](https://github.com/Clinical-Genomics/stranger)\n\n**11. Variant calling - mobile elements:**\n\n- [RetroSeq](https://github.com/tk2/RetroSeq)\n\n**12. Rank variants - SV and SNV:**\n\n- [GENMOD](https://github.com/Clinical-Genomics/genmod)\n\n**13. Variant evaluation:**\n\n- [RTG Tools](https://github.com/RealTimeGenomics/rtg-tools)\n\nNote that it is possible to include/exclude certain tools or steps.\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:\n\n`samplesheet.csv`:\n\n```csv\nsample,lane,fastq_1,fastq_2,sex,phenotype,paternal_id,maternal_id,case_id\nhugelymodelbat,1,reads_1.fastq.gz,reads_2.fastq.gz,1,2,,,justhusky\n```\n\nEach row represents a pair of fastq files (paired end).\n\nSecond, ensure that you have defined the path to reference files and parameters required for the type of analysis that you want to perform. More information about this can be found [here](https://github.com/nf-core/raredisease/blob/dev/docs/usage.md).\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/raredisease \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/running/run-pipelines#using-parameter-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/raredisease/usage) and the [parameter documentation](https://nf-co.re/raredisease/parameters).\n\n## Pipeline output\n\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/raredisease/output).\n\n## Credits\n\nnf-core/raredisease was written in a collaboration between the Clinical Genomics nodes in Sweden, with major contributions from [Ramprasad Neethiraj](https://github.com/ramprasadn), [Anders Jemt](https://github.com/jemten), [Lucia Pena Perez](https://github.com/Lucpen), and [Mei Wu](https://github.com/projectoriented) at Clinical Genomics Stockholm.\n\nAdditional contributors were [Sima Rahimi](https://github.com/sima-r), [Gwenna Breton](https://github.com/Gwennid) and [Emma Västerviga](https://github.com/EmmaCAndersson) (Clinical Genomics Gothenburg); [Halfdan Rydbeck](https://github.com/hrydbeck) and [Lauri Mesilaakso](https://github.com/ljmesi) (Clinical Genomics Linköping); [Subazini Thankaswamy Kosalai](https://github.com/sysbiocoder) (Clinical Genomics Örebro); [Annick Renevey](https://github.com/rannick), [Peter Pruisscher](https://github.com/peterpru) and [Eva Caceres](https://github.com/fevac) (Clinical Genomics Stockholm); [Ryan Kennedy](https://github.com/ryanjameskennedy) (Clinical Genomics Lund); [Anders Sune Pedersen](https://github.com/asp8200) (Danish National Genome Center) and [Lucas Taniguti](https://github.com/lmtani).\n\nWe thank the nf-core community for their extensive assistance in the development of this pipeline.\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 `#raredisease` channel](https://nfcore.slack.com/channels/raredisease) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/raredisease for your analysis, please cite it using the following doi: [10.5281/zenodo.7995798](https://doi.org/10.5281/zenodo.7995798)\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 read more about MIP's use in healthcare in,\n\n> Stranneheim H, Lagerstedt-Robinson K, Magnusson M, et al. Integration of whole genome sequencing into a healthcare setting: high diagnostic rates across multiple clinical entities in 3219 rare disease patients. Genome Med. 2021;13(1):40. doi:10.1186/s13073-021-00855-5\n", "hasPart": [ { "@id": "main.nf" @@ -105,7 +105,7 @@ }, "mentions": [ { - "@id": "#54f4c43c-5277-4feb-87f6-9700f8b38e9c" + "@id": "#a2e01a09-4ed6-4e70-a220-6783a1ccde25" } ], "name": "nf-core/raredisease" @@ -118,7 +118,7 @@ }, "conformsTo": [ { - "@id": "https://w3id.org/ro/crate/1.1" + "@id": "https://w3id.org/ro/crate/1.2" }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" @@ -132,28 +132,48 @@ "SoftwareSourceCode", "ComputationalWorkflow" ], - "creator": [ + "author": [ { "@id": "https://orcid.org/0000-0001-7313-3734" }, + { + "@id": "https://orcid.org/0000-0002-2219-0197" + } + ], + "contributor": [ + { + "@id": "#dcd2346b-7e4e-4040-87ef-427100f4f902" + }, + { + "@id": "https://orcid.org/0000-0002-5044-7754" + }, + { + "@id": "https://orcid.org/0000-0002-6987-5839" + }, + { + "@id": "https://orcid.org/0009-0008-1112-841X" + }, { "@id": "https://orcid.org/0000-0002-4100-9963" }, { - "@id": "https://orcid.org/0000-0002-2219-0197" + "@id": "#sima.rahimi@med.lu.se" }, { - "@id": "https://orcid.org/0000-0003-1316-2845" + "@id": "https://orcid.org/0000-0002-9594-0710" }, { - "@id": "https://orcid.org/0000-0002-5044-7754" + "@id": "https://orcid.org/0000-0003-2827-9261" + }, + { + "@id": "#eva.caceres@scilifelab.se" }, { - "@id": "#25568561+projectoriented@users.noreply.github.com" + "@id": "https://orcid.org/0000-0003-1581-0711" } ], "dateCreated": "", - "dateModified": "2025-06-25T11:02:19Z", + "dateModified": "2026-06-25T15:47:40Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -174,17 +194,8 @@ { "@id": "https://orcid.org/0000-0001-7313-3734" }, - { - "@id": "https://orcid.org/0000-0002-4100-9963" - }, { "@id": "https://orcid.org/0000-0002-2219-0197" - }, - { - "@id": "https://orcid.org/0000-0002-5044-7754" - }, - { - "@id": "#25568561+projectoriented@users.noreply.github.com" } ], "name": [ @@ -198,10 +209,10 @@ }, "url": [ "https://github.com/nf-core/raredisease", - "https://nf-co.re/raredisease/2.6.0/" + "https://nf-co.re/raredisease/dev/" ], "version": [ - "2.6.0" + "3.2.0dev" ] }, { @@ -214,14 +225,14 @@ "url": { "@id": "https://www.nextflow.io/" }, - "version": "!>=24.04.2" + "version": "!>=25.10.4" }, { - "@id": "#54f4c43c-5277-4feb-87f6-9700f8b38e9c", + "@id": "#a2e01a09-4ed6-4e70-a220-6783a1ccde25", "@type": "TestSuite", "instance": [ { - "@id": "#d8630621-ea14-4767-9e8d-8ab89ed17c30" + "@id": "#91b318e6-0c3c-462b-9f7a-e69dc5c2f29c" } ], "mainEntity": { @@ -230,7 +241,7 @@ "name": "Test suite for nf-core/raredisease" }, { - "@id": "#d8630621-ea14-4767-9e8d-8ab89ed17c30", + "@id": "#91b318e6-0c3c-462b-9f7a-e69dc5c2f29c", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/raredisease", "resource": "repos/nf-core/raredisease/actions/workflows/nf-test.yml", @@ -371,38 +382,96 @@ { "@id": "https://orcid.org/0000-0001-7313-3734", "@type": "Person", - "email": "20065894+ramprasadn@users.noreply.github.com", - "name": "Ramprasad Neethiraj" + "affiliation": "School of Engineering sciences in Chemistry, Biotechnology and Health, KTH Royal Institute of Technology, Stockholm, Sweden; Science for Life Laboratory, Department of Microbiology, Tumour and Cell Biology, Karolinska Institutet, Stockholm, Sweden", + "email": "rne@kth.se", + "name": "Ramprasad Neethiraj", + "url": "https://github.com/ramprasadn" + }, + { + "@id": "https://orcid.org/0000-0002-2219-0197", + "@type": "Person", + "affiliation": "Genomics Medicine Center Karolinska, Karolinska University Hospital, Stockholm, Sweden; Science for Life Laboratory, Department of Microbiology, Tumour and Cell Biology, Karolinska Institutet, Stockholm, Sweden", + "email": "anders.jemt@scilifelab.se", + "name": "Anders Jemt", + "url": "https://github.com/jemten" + }, + { + "@id": "#dcd2346b-7e4e-4040-87ef-427100f4f902", + "@type": "Person", + "email": "25568561+projectoriented@users.noreply.github.com", + "name": "Mei Wu", + "url": "https://github.com/projectoriented" + }, + { + "@id": "https://orcid.org/0000-0002-5044-7754", + "@type": "Person", + "affiliation": "Center for Inherited Metabolic Diseases, Karolinska University Hospital, Stockholm, Sweden; Department of Molecular Medicine and Surgery, Karolinska Institutet, Stockholm, Sweden", + "email": "lucia.pena.perez@scilifelab.se", + "name": "Lucía Peña-Pérez", + "url": "https://github.com/Lucpen" + }, + { + "@id": "https://orcid.org/0000-0002-6987-5839", + "@type": "Person", + "affiliation": "Genomics Medicine Center Karolinska, Karolinska University Hospital, Stockholm, Sweden; Science for Life Laboratory, Department of Microbiology, Tumour and Cell Biology, Karolinska Institutet, Stockholm, Sweden", + "email": "peter.pruisscher@scilifelab.se", + "name": "Peter Pruisscher", + "url": "https://github.com/peterpru" + }, + { + "@id": "https://orcid.org/0009-0008-1112-841X", + "@type": "Person", + "affiliation": "Danish National Genome Center", + "email": "aspe@clin.au.dk", + "name": "Anders Sune Pedersen", + "url": "https://github.com/asp8200" }, { "@id": "https://orcid.org/0000-0002-4100-9963", "@type": "Person", - "email": "Gwenna.breton@gu.se", - "name": "Gwenna Breton" + "affiliation": "Clinical Genomics Gothenburg, Sahlgrenska University Hospital and University of Gothenburg", + "email": "gwenna.breton@gu.se", + "name": "Gwenna Breton", + "url": "https://github.com/Gwennid" }, { - "@id": "https://orcid.org/0000-0002-2219-0197", + "@id": "#sima.rahimi@med.lu.se", "@type": "Person", - "email": "jemten@users.noreply.github.com", - "name": "Anders Jemt" + "affiliation": "Clinical Genomics Lund, Lund University", + "email": "sima.rahimi@med.lu.se", + "name": "Sima Rahimi", + "url": "https://github.com/sima-r" }, { - "@id": "https://orcid.org/0000-0003-1316-2845", + "@id": "https://orcid.org/0000-0002-9594-0710", "@type": "Person", - "email": "raysloks@gmail.com", - "name": "Emil Bertilsson" + "affiliation": "Department of Immunology, Genetics and Pathology, Uppsala University, Sweden; Science for Life Laboratory, Department of Microbiology, Tumour and Cell Biology, Karolinska Institutet, Stockholm, Sweden", + "email": "felix.lenner@scilifelab.se", + "name": "Felix Lenner", + "url": "https://github.com/fellen31" }, { - "@id": "https://orcid.org/0000-0002-5044-7754", + "@id": "https://orcid.org/0000-0003-2827-9261", "@type": "Person", - "email": "lucia.pena.perez@scilifelab.se", - "name": "Luc\u00eda Pe\u00f1a-P\u00e9rez" + "affiliation": "Seqera", + "email": "maxime.garcia@seqera.io", + "name": "Maxime U Garcia", + "url": "https://github.com/maxulysse" }, { - "@id": "#25568561+projectoriented@users.noreply.github.com", + "@id": "#eva.caceres@scilifelab.se", "@type": "Person", - "email": "25568561+projectoriented@users.noreply.github.com", - "name": "Mei Wu" + "affiliation": "Clinical Genomics Stockholm", + "email": "eva.caceres@scilifelab.se", + "name": "Eva Caceres", + "url": "https://github.com/fevac" + }, + { + "@id": "https://orcid.org/0000-0003-1581-0711", + "@type": "Person", + "affiliation": "nf-core community", + "name": "and the nf-core/raredisease team", + "url": "https://github.com/nf-core" } ] } \ No newline at end of file diff --git a/subworkflows/local/align.nf b/subworkflows/local/align.nf deleted file mode 100644 index b88dd8627..000000000 --- a/subworkflows/local/align.nf +++ /dev/null @@ -1,169 +0,0 @@ -// -// Map to reference -// - -include { FASTP } from '../../modules/nf-core/fastp/main' -include { ALIGN_BWA_BWAMEM2_BWAMEME } from './align_bwa_bwamem2_bwameme' -include { ALIGN_SENTIEON } from './align_sentieon' -include { SAMTOOLS_VIEW } from '../../modules/nf-core/samtools/view/main' -include { ALIGN_MT } from './align_MT' -include { ALIGN_MT as ALIGN_MT_SHIFT } from './align_MT' -include { CONVERT_MT_BAM_TO_FASTQ } from './convert_mt_bam_to_fastq' - -workflow ALIGN { - take: - ch_reads // channel: [optional] [ val(meta), [path(reads)] ] - ch_alignments // channel: [optional] [ val(meta), [path(bam),path(bai)] ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_genome_bwaindex // channel: [mandatory] [ val(meta), path(index) ] - ch_genome_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] - ch_genome_bwamemeindex // channel: [mandatory] [ val(meta), path(index) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_mt_bwaindex // channel: [mandatory] [ val(meta), path(index) ] - ch_mt_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] - ch_mt_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_mt_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_mt_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_mtshift_bwaindex // channel: [mandatory] [ val(meta), path(index) ] - ch_mtshift_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] - ch_mtshift_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_mtshift_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_mtshift_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - val_mbuffer_mem // integer: [mandatory] memory in megabytes - val_platform // string: [mandatory] illumina or a different technology - val_sort_threads // integer: [mandatory] number of sorting threads - - main: - ch_bwamem2_bam = Channel.empty() - ch_bwamem2_bai = Channel.empty() - ch_fastp_json = Channel.empty() - ch_markdup_metrics = Channel.empty() - ch_mt_bam_bai = Channel.empty() - ch_mt_marked_bam = Channel.empty() - ch_mt_marked_bai = Channel.empty() - ch_mtshift_bam_bai = Channel.empty() - ch_mtshift_marked_bam = Channel.empty() - ch_mtshift_marked_bai = Channel.empty() - ch_sentieon_bam = Channel.empty() - ch_sentieon_bai = Channel.empty() - ch_versions = Channel.empty() - - if (!(params.skip_tools && params.skip_tools.split(',').contains('fastp'))) { - FASTP (ch_reads, [], false, false, false) - ch_reads = FASTP.out.reads - ch_versions = ch_versions.mix(FASTP.out.versions) - ch_fastp_json = FASTP.out.json - } - - // - // If input is bam - // - ch_alignments.map { meta, files -> - def new_id = meta.sample - def new_meta = meta + [id:new_id, read_group:"\'@RG\\tID:" + new_id + "\\tPL:" + val_platform + "\\tSM:" + new_id + "\'"] - meta.subMap('lane') - return [new_meta, files].flatten() - } - .map { it -> [it[0], it[1]] } - .set{ch_input_bam} - - ch_alignments.map { meta, files -> - def new_id = meta.sample - def new_meta = meta + [id:new_id, read_group:"\'@RG\\tID:" + new_id + "\\tPL:" + val_platform + "\\tSM:" + new_id + "\'"] - meta.subMap('lane') - return [new_meta, files].flatten() - } - .map { it -> [it[0], it[2]] } - .set{ch_input_bai} - - if (params.aligner.matches("bwamem2|bwa|bwameme")) { - ALIGN_BWA_BWAMEM2_BWAMEME ( // Triggered when params.aligner is set as bwamem2 or bwa or bwameme - ch_reads, - ch_genome_bwaindex, - ch_genome_bwamem2index, - ch_genome_bwamemeindex, - ch_genome_fasta, - ch_genome_fai, - val_mbuffer_mem, - val_platform, - val_sort_threads - ) - ch_bwamem2_bam = ALIGN_BWA_BWAMEM2_BWAMEME.out.marked_bam - ch_bwamem2_bai = ALIGN_BWA_BWAMEM2_BWAMEME.out.marked_bai - ch_markdup_metrics = ALIGN_BWA_BWAMEM2_BWAMEME.out.metrics - ch_versions = ch_versions.mix(ALIGN_BWA_BWAMEM2_BWAMEME.out.versions) - } else if (params.aligner.equals("sentieon")) { - ALIGN_SENTIEON ( // Triggered when params.aligner is set as sentieon - ch_reads, - ch_genome_fasta, - ch_genome_fai, - ch_genome_bwaindex, - val_platform - ) - ch_sentieon_bam = ALIGN_SENTIEON.out.marked_bam - ch_sentieon_bai = ALIGN_SENTIEON.out.marked_bai - ch_versions = ch_versions.mix(ALIGN_SENTIEON.out.versions) - } - - ch_genome_marked_bam = Channel.empty().mix(ch_bwamem2_bam, ch_sentieon_bam, ch_input_bam) - ch_genome_marked_bai = Channel.empty().mix(ch_bwamem2_bai, ch_sentieon_bai, ch_input_bai) - ch_genome_bam_bai = ch_genome_marked_bam.join(ch_genome_marked_bai, failOnMismatch:true, failOnDuplicate:true) - - // PREPARING READS FOR MT ALIGNMENT - - if (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) { - CONVERT_MT_BAM_TO_FASTQ ( - ch_genome_bam_bai, - ch_genome_fasta, - ch_genome_fai, - ch_genome_dictionary - ) - - ALIGN_MT ( - CONVERT_MT_BAM_TO_FASTQ.out.fastq, - CONVERT_MT_BAM_TO_FASTQ.out.bam, - ch_mt_bwaindex, - ch_mt_bwamem2index, - ch_mt_fasta, - ch_mt_dictionary, - ch_mt_fai - ) - - ALIGN_MT_SHIFT ( - CONVERT_MT_BAM_TO_FASTQ.out.fastq, - CONVERT_MT_BAM_TO_FASTQ.out.bam, - ch_mtshift_bwaindex, - ch_mtshift_bwamem2index, - ch_mtshift_fasta, - ch_mtshift_dictionary, - ch_mtshift_fai - ) - - ch_mt_marked_bam = ALIGN_MT.out.marked_bam - ch_mt_marked_bai = ALIGN_MT.out.marked_bai - ch_mt_bam_bai = ch_mt_marked_bam.join(ch_mt_marked_bai, failOnMismatch:true, failOnDuplicate:true) - ch_mtshift_marked_bam = ALIGN_MT_SHIFT.out.marked_bam - ch_mtshift_marked_bai = ALIGN_MT_SHIFT.out.marked_bai - ch_mtshift_bam_bai = ch_mtshift_marked_bam.join(ch_mtshift_marked_bai, failOnMismatch:true, failOnDuplicate:true) - ch_versions = ch_versions.mix(ALIGN_MT.out.versions, - ALIGN_MT_SHIFT.out.versions, - CONVERT_MT_BAM_TO_FASTQ.out.versions) - } - - if (params.save_mapped_as_cram) { - SAMTOOLS_VIEW( ch_genome_bam_bai, ch_genome_fasta, [] ) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW.out.versions) - } - emit: - fastp_json = ch_fastp_json // channel: [ val(meta), path(json) ] - genome_marked_bam = ch_genome_marked_bam // channel: [ val(meta), path(bam) ] - genome_marked_bai = ch_genome_marked_bai // channel: [ val(meta), path(bai) ] - genome_bam_bai = ch_genome_bam_bai // channel: [ val(meta), path(bam), path(bai) ] - markdup_metrics = ch_markdup_metrics // channel: [ val(meta), path(txt) ] - mt_marked_bam = ch_mt_marked_bam // channel: [ val(meta), path(bam) ] - mt_marked_bai = ch_mt_marked_bai // channel: [ val(meta), path(bai) ] - mt_bam_bai = ch_mt_bam_bai // channel: [ val(meta), path(bam), path(bai) ] - mtshift_marked_bam = ch_mtshift_marked_bam // channel: [ val(meta), path(bam) ] - mtshift_marked_bai = ch_mtshift_marked_bai // channel: [ val(meta), path(bai) ] - mtshift_bam_bai = ch_mtshift_bam_bai // channel: [ val(meta), path(bam), path(bai) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/align/main.nf b/subworkflows/local/align/main.nf new file mode 100644 index 000000000..71d35c87d --- /dev/null +++ b/subworkflows/local/align/main.nf @@ -0,0 +1,208 @@ +// +// Map to reference +// + +include { ALIGN_BWA_BWAMEM2_BWAMEME } from '../align_bwa_bwamem2_bwameme' +include { ALIGN_MT } from '../align_MT' +include { ALIGN_MT as ALIGN_MT_SHIFT } from '../align_MT' +include { ALIGN_SENTIEON } from '../align_sentieon' +include { CONVERT_MT_BAM_TO_FASTQ } from '../convert_mt_bam_to_fastq' +include { FASTP } from '../../../modules/nf-core/fastp/main' +include { SAMTOOLS_VIEW as CONVERTTOCRAM_ALTFILTERED } from '../../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as CONVERTTOCRAM_UNFILTERED } from '../../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_EXCLUDE_ALT } from '../../../modules/nf-core/samtools/view/main' + +workflow ALIGN { + take: + ch_alignments // channel: [optional] [ val(meta), [path(bam),path(bai)] ] + ch_genome_bwafastalignindex // channel: [mandatory] [ val(meta), path(index) ] + ch_genome_bwaindex // channel: [mandatory] [ val(meta), path(index) ] + ch_genome_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] + ch_genome_bwamemeindex // channel: [mandatory] [ val(meta), path(index) ] + ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_input_reads // channel: [optional] [ val(meta), [path(reads)] ] + ch_mt_bwaindex // channel: [mandatory] [ val(meta), path(index) ] + ch_mt_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] + ch_mt_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_mt_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_mt_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_mtshift_bwaindex // channel: [mandatory] [ val(meta), path(index) ] + ch_mtshift_bwamem2index // channel: [mandatory] [ val(meta), path(index) ] + ch_mtshift_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_mtshift_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_mtshift_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + skip_fastp // boolean + val_aligner // string: 'bwa', 'bwafastalign', 'bwamem2', 'bwameme', or 'sentieon' + val_analysis_type // string: 'wgs', 'wes', or 'mito' + val_exclude_alt // boolean + val_extract_alignments // boolean + val_mt_aligner // string: 'bwa', 'bwamem2', or 'sentieon' + val_platform // string: [mandatory] illumina or a different technology + val_run_mt_for_wes // boolean + val_save_all_mapped_as_cram // boolean + val_save_noalt_mapped_as_cram // boolean + + main: + ch_bwamem2_bam = channel.empty() + ch_bwamem2_bai = channel.empty() + ch_fastp_json = channel.empty() + ch_fastp_out = channel.empty() + ch_genome_marked_cram = channel.empty() + ch_genome_marked_crai = channel.empty() + ch_markdup_metrics = channel.empty() + ch_mt_bam_bai = channel.empty() + ch_mt_bam_bai_gatksubwf = channel.empty() + ch_mtshift_bam_bai_gatksubwf = channel.empty() + ch_sentieon_bam = channel.empty() + ch_sentieon_bai = channel.empty() + + if (!skip_fastp) { + FASTP (ch_input_reads.map {meta, reads -> return [meta, reads, []] }, false, false, false) + ch_input_reads = FASTP.out.reads + ch_fastp_json = FASTP.out.json + ch_fastp_out = FASTP.out.json + .mix(FASTP.out.html) + .mix(FASTP.out.log) + .mix(FASTP.out.reads.transpose()) + .mix(FASTP.out.reads_fail) + .mix(FASTP.out.reads_merged) + } + + // + // If input is bam + // + ch_alignments + .map { meta, files -> + def new_id = meta.sample + def new_meta = meta + [id:new_id, read_group:"\'@RG\\tID:" + new_id + "\\tPL:" + val_platform + "\\tSM:" + new_id + "\'"] - meta.subMap('lane') + return [new_meta, files].flatten() + } + .multiMap { meta, bam, bai -> + bam: [meta, bam] + bai: [meta, bai] + } + .set { ch_input_aligned } + + ch_input_bam = ch_input_aligned.bam + ch_input_bai = ch_input_aligned.bai + + if (val_aligner.matches("bwamem2|bwa|bwameme|bwafastalign")) { + ALIGN_BWA_BWAMEM2_BWAMEME ( + ch_genome_bwaindex, + ch_genome_bwafastalignindex, + ch_genome_bwamem2index, + ch_genome_bwamemeindex, + ch_genome_fai, + ch_genome_fasta, + ch_input_reads, + val_aligner, + val_extract_alignments, + val_platform + ) + ch_bwamem2_bam = ALIGN_BWA_BWAMEM2_BWAMEME.out.marked_bam + ch_bwamem2_bai = ALIGN_BWA_BWAMEM2_BWAMEME.out.marked_bai + ch_markdup_metrics = ALIGN_BWA_BWAMEM2_BWAMEME.out.markdup_metrics + } else if (val_aligner.equals("sentieon")) { + ALIGN_SENTIEON ( + ch_genome_bwaindex, + ch_genome_fai, + ch_genome_fasta, + ch_input_reads, + val_extract_alignments, + val_platform + ) + ch_sentieon_bam = ALIGN_SENTIEON.out.marked_bam + ch_sentieon_bai = ALIGN_SENTIEON.out.marked_bai + ch_markdup_metrics = ALIGN_SENTIEON.out.dedup_metrics + .mix(ALIGN_SENTIEON.out.dedup_metrics_multiqc) + .mix(ALIGN_SENTIEON.out.score) + } + + ch_genome_marked_bam_initial = channel.empty().mix(ch_bwamem2_bam, ch_sentieon_bam, ch_input_bam) + ch_genome_marked_bai_initial = channel.empty().mix(ch_bwamem2_bai, ch_sentieon_bai, ch_input_bai) + ch_genome_marked_bam_bai_initial = ch_genome_marked_bam_initial.join(ch_genome_marked_bai_initial, failOnMismatch:true, failOnDuplicate:true) + + ch_branched = ch_genome_marked_bam_bai_initial.branch { meta, bam, bai -> + exclude_alt: val_exclude_alt + return [meta, bam, bai] + keep_all: true + return [meta, bam, bai] + } + + SAMTOOLS_VIEW_EXCLUDE_ALT( + ch_branched.exclude_alt, + ch_genome_fasta.map { meta, fasta -> [meta, fasta, []] }, + [], + 'bai' + ) + + ch_genome_marked_bam = val_exclude_alt ? SAMTOOLS_VIEW_EXCLUDE_ALT.out.bam : ch_branched.keep_all.map { meta, bam, _bai -> [meta, bam] } + ch_genome_marked_bai = val_exclude_alt ? SAMTOOLS_VIEW_EXCLUDE_ALT.out.bai : ch_branched.keep_all.map { meta, _bam, bai -> [meta, bai] } + ch_genome_marked_bam_bai = ch_genome_marked_bam.join(ch_genome_marked_bai, failOnMismatch:true, failOnDuplicate:true) + + // PREPARING READS FOR MT ALIGNMENT + + if (val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) { + CONVERT_MT_BAM_TO_FASTQ ( + ch_genome_marked_bam_bai, + ch_genome_dictionary, + ch_genome_fai, + ch_genome_fasta + ) + + ALIGN_MT ( + ch_mt_bwaindex, + ch_mt_bwamem2index, + ch_mt_dictionary, + ch_mt_fai, + ch_mt_fasta, + CONVERT_MT_BAM_TO_FASTQ.out.fastq, + CONVERT_MT_BAM_TO_FASTQ.out.ubam, + val_mt_aligner + ) + + ALIGN_MT_SHIFT ( + ch_mtshift_bwaindex, + ch_mtshift_bwamem2index, + ch_mtshift_dictionary, + ch_mtshift_fai, + ch_mtshift_fasta, + CONVERT_MT_BAM_TO_FASTQ.out.fastq, + CONVERT_MT_BAM_TO_FASTQ.out.ubam, + val_mt_aligner + ) + + ch_mt_bam_bai = CONVERT_MT_BAM_TO_FASTQ.out.bam_bai // Used for subsampling and SV calling + ch_mt_bam_bai_gatksubwf = ALIGN_MT.out.marked_bam + .join(ALIGN_MT.out.marked_bai, failOnMismatch:true, failOnDuplicate:true) // Only for SNV calling + ch_mtshift_bam_bai_gatksubwf = ALIGN_MT_SHIFT.out.marked_bam + .join(ALIGN_MT_SHIFT.out.marked_bai, failOnMismatch:true, failOnDuplicate:true) // Only for SNV calling + } + + if (val_save_noalt_mapped_as_cram) { + CONVERTTOCRAM_ALTFILTERED( ch_genome_marked_bam_bai, ch_genome_fasta.map{meta, fasta -> return [meta, fasta, []]}, [], 'crai' ) + ch_genome_marked_cram = ch_genome_marked_cram.mix(CONVERTTOCRAM_ALTFILTERED.out.cram) + ch_genome_marked_crai = ch_genome_marked_crai.mix(CONVERTTOCRAM_ALTFILTERED.out.crai) + } + + if (val_save_all_mapped_as_cram) { + CONVERTTOCRAM_UNFILTERED( ch_genome_marked_bam_bai_initial, ch_genome_fasta.map{meta, fasta -> return [meta, fasta, []]}, [], 'crai' ) + ch_genome_marked_cram = ch_genome_marked_cram.mix(CONVERTTOCRAM_UNFILTERED.out.cram) + ch_genome_marked_crai = ch_genome_marked_crai.mix(CONVERTTOCRAM_UNFILTERED.out.crai) + } + + emit: + fastp_json = ch_fastp_json // channel: [ val(meta), path(json) ] + fastp_out = ch_fastp_out // channel: [ val(meta), path(json|html|log|reads|reads_fail|reads_merged) ] + genome_marked_cram = ch_genome_marked_cram // channel: [ val(meta), path(cram) ] + genome_marked_crai = ch_genome_marked_crai // channel: [ val(meta), path(crai) ] + genome_marked_bam = ch_genome_marked_bam // channel: [ val(meta), path(bam) ] + genome_marked_bai = ch_genome_marked_bai // channel: [ val(meta), path(bai) ] + genome_marked_bam_bai = ch_genome_marked_bam_bai // channel: [ val(meta), path(bam), path(bai) ] + markdup_metrics = ch_markdup_metrics // channel: [ val(meta), path(metrics) ] + mt_bam_bai = ch_mt_bam_bai // channel: [ val(meta), path(bam), path(bai) ] + mt_bam_bai_gatksubwf = ch_mt_bam_bai_gatksubwf // channel: [ val(meta), path(bam), path(bai) ] + mtshift_bam_bai_gatksubwf = ch_mtshift_bam_bai_gatksubwf // channel: [ val(meta), path(bam), path(bai) ] +} diff --git a/subworkflows/local/align/tests/main.nf.test b/subworkflows/local/align/tests/main.nf.test new file mode 100644 index 000000000..d08a1b802 --- /dev/null +++ b/subworkflows/local/align/tests/main.nf.test @@ -0,0 +1,454 @@ +nextflow_workflow { + + name "Test Workflow ALIGN" + script "subworkflows/local/align/main.nf" + workflow "ALIGN" + + tag "subworkflows" + tag "align" + tag "align_bwa_bwamem2_bwameme" + tag "bwafastalign/mem" + tag "align_sentieon" + tag "align_MT" + tag "convert_mt_bam_to_fastq" + + tag "fastp" + tag "samtools/view" + tag "samtools/view_exclude_alt" + + config "./nextflow.config" + + setup { + run("BWAMEM2_INDEX", alias: 'MT_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'mt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_mt.fa', checkIfExists: true) + ]) + """ + } + } + run("BWAMEM2_INDEX", alias: 'SHIFTMT_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'shiftmt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_shift.fasta', checkIfExists: true) + ]) + """ + } + } + } + + test("align bwamem2 - wgs") { + + setup { + run("BWAMEM2_INDEX", alias: 'GENOME_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + exclude_alt = true + genome = "GRCh37" + platform = "illumina" + min_trimmed_length = 50 + mito_name = "MT" + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.empty() + input[1] = channel.empty() + input[2] = channel.empty() + input[3] = GENOME_MEM2.out.index.collect() + input[4] = channel.empty() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[6] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[7] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[8] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ] + ) + input[9] = channel.empty() + input[10] = MT_MEM2.out.index.collect() + input[11] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[12] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[13] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[14] = channel.empty() + input[15] = SHIFTMT_MEM2.out.index.collect() + input[16] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[17] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[18] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[19] = false + input[20] = "bwamem2" + input[21] = "wgs" + input[22] = true + input[23] = false + input[24] = "bwamem2" + input[25] = "illumina" + input[26] = false + input[27] = true + input[28] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.fastp_json, + workflow.out.genome_marked_cram + .collect { meta, cramfile -> [ meta, cram(cramfile, params.pipelines_testdata_base_path + 'reference/reference.fasta').getReadsMD5() ] }, + workflow.out.genome_marked_crai + .collect { meta, craifile -> [meta, file(craifile).name] }, + workflow.out.genome_marked_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mtshift_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] } + ).match() + } + ) + } + } + test("align bwamem2 - wes, stub") { + + options "-stub" + + setup { + run("BWAMEM2_INDEX", alias: 'GENOME_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + save_noalt_mapped_as_cram = false + save_all_mapped_as_cram = true + platform = "illumina" + min_trimmed_length = 50 + mito_name = "MT" + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.empty() + input[1] = channel.empty() + input[2] = channel.empty() + input[3] = GENOME_MEM2.out.index.collect() + input[4] = channel.empty() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[6] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[7] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[8] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_2.fastq.gz', checkIfExists: true) + ] + ] + ) + input[9] = channel.empty() + input[10] = MT_MEM2.out.index.collect() + input[11] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[12] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[13] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[14] = channel.empty() + input[15] = SHIFTMT_MEM2.out.index.collect() + input[16] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[17] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[18] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[19] = false + input[20] = "bwamem2" + input[21] = "wes" + input[22] = false + input[23] = false + input[24] = "bwamem2" + input[25] = "illumina" + input[26] = false + input[27] = true + input[28] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.fastp_json, + workflow.out.genome_marked_cram + .collect { meta, cramfile -> [ meta, cram(cramfile, params.pipelines_testdata_base_path + 'reference/reference.fasta').getReadsMD5() ] }, + workflow.out.genome_marked_crai + .collect { meta, craifile -> [meta, file(craifile).name] }, + workflow.out.genome_marked_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mtshift_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] } + ).match() + } + ) + } + } + + test("align bwameme - wgs") { + + setup { + run("BWAMEME_INDEX", alias: 'GENOME_MEME') { + script "modules/nf-core/bwameme/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + platform = "illumina" + min_trimmed_length = 50 + mito_name = "MT" + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.empty() + input[1] = channel.empty() + input[2] = channel.empty() + input[3] = channel.empty() + input[4] = GENOME_MEME.out.index.collect() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[6] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[7] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[8] = channel.fromList([ + [[ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_2.fastq.gz', checkIfExists: true) + ]], + [[ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_2.fastq.gz', checkIfExists: true) + ]], + [[ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_2.fastq.gz', checkIfExists: true) + ]] + ]) + input[9] = channel.empty() + input[10] = MT_MEM2.out.index.collect() + input[11] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[12] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[13] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[14] = channel.empty() + input[15] = SHIFTMT_MEM2.out.index.collect() + input[16] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[17] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[18] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[19] = true + input[20] = "bwameme" + input[21] = "wgs" + input[22] = false + input[23] = false + input[24] = "bwamem2" + input[25] = "illumina" + input[26] = false + input[27] = true + input[28] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.genome_marked_cram + .collect { meta, cramfile -> [ meta, cram(cramfile, params.pipelines_testdata_base_path + 'reference/reference.fasta').getReadsMD5() ] }, + workflow.out.genome_marked_crai + .collect { meta, craifile -> [meta, file(craifile).name] }, + workflow.out.genome_marked_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mtshift_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] } + ).match() + } + ) + } + } + + + + test("align bwameme - wes, stub") { + + options "-stub" + + setup { + run("BWAMEME_INDEX", alias: 'GENOME_MEME') { + script "modules/nf-core/bwameme/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + + when { + params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + platform = "illumina" + min_trimmed_length = 50 + mito_name = "MT" + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.empty() + input[1] = channel.empty() + input[2] = channel.empty() + input[3] = channel.empty() + input[4] = GENOME_MEME.out.index.collect() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[6] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[7] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[8] = channel.fromList([ + [[ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_earlycasualcaiman_XXXXXX_2.fastq.gz', checkIfExists: true) + ]], + [[ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_hugelymodelbat_XXXXXX_2.fastq.gz', checkIfExists: true) + ]], + [[ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + '/testdata/1_171015_HHT5NDSXX_slowlycivilbuck_XXXXXX_2.fastq.gz', checkIfExists: true) + ]] + ]) + input[9] = channel.empty() + input[10] = MT_MEM2.out.index.collect() + input[11] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[12] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[13] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[14] = channel.empty() + input[15] = SHIFTMT_MEM2.out.index.collect() + input[16] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[17] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[18] = channel.of([id:'shiftmt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[19] = true + input[20] = "bwameme" + input[21] = "wes" + input[22] = false + input[23] = false + input[24] = "bwamem2" + input[25] = "illumina" + input[26] = false + input[27] = true + input[28] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.genome_marked_cram + .collect { meta, cramfile -> [ meta, cram(cramfile, params.pipelines_testdata_base_path + 'reference/reference.fasta').getReadsMD5() ] }, + workflow.out.genome_marked_crai + .collect { meta, craifile -> [meta, file(craifile).name] }, + workflow.out.genome_marked_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mt_bam_bai + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] }, + workflow.out.mtshift_bam_bai_gatksubwf + .collect { meta, bamfile, index -> [ meta, bam(bamfile).getReadsMD5(), file(index).name ] } + ).match() + } + + ) + } + } +} diff --git a/subworkflows/local/align/tests/main.nf.test.snap b/subworkflows/local/align/tests/main.nf.test.snap new file mode 100644 index 000000000..d42646af9 --- /dev/null +++ b/subworkflows/local/align/tests/main.nf.test.snap @@ -0,0 +1,1240 @@ +{ + "align bwamem2 - wes, stub": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "earlycasualcaiman_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "hugelymodelbat_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "slowlycivilbuck_sorted_md.cram.crai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_sorted_md.bam.bai" + ] + ], + [ + + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-12T15:08:42.696356", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwamem2 - wgs": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.fastp.json:md5,d473c195ec66e23d39a02d4566b92d75" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat.fastp.json:md5,364c1702f8e833c70fbd36c2e0634f86" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck.fastp.json:md5,7ad34e9e48159c794ce777e4e48c0b96" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d948b0bd18f6f6526f5d8832465e1542" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "bb547b29eca1afded4229826c774fc90" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "2530fd24192b09084f45011703bd4954" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "6f48b21e58c7450dd4db0bfc1268d687" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "cc1385671a27d394f628d2d7868eba80" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "e8431e5dc096f9636efd37ebfe9a5883" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "earlycasualcaiman_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "earlycasualcaiman_sorted_md_primary_contigs.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "hugelymodelbat_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "hugelymodelbat_sorted_md_primary_contigs.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "slowlycivilbuck_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "slowlycivilbuck_sorted_md_primary_contigs.cram.crai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "bb547b29eca1afded4229826c774fc90", + "earlycasualcaiman_sorted_md_primary_contigs.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "6f48b21e58c7450dd4db0bfc1268d687", + "hugelymodelbat_sorted_md_primary_contigs.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "e8431e5dc096f9636efd37ebfe9a5883", + "slowlycivilbuck_sorted_md_primary_contigs.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "df4054395a0ae4588719c34560b4e26f", + "earlycasualcaiman.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "601871c90e6b0a1f805d19ea8b60a7e5", + "hugelymodelbat.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "35da26a8d2d56b62e01b2e879cd8addd", + "slowlycivilbuck.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "9beeefe789d896c08d55e8b8d13d9623", + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "b18998c8cf7dc417ca9a122ba1c9403d", + "hugelymodelbat_sorted_merged_md_sorted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "a5d6892191a2c8c1f29966448623ca1b", + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "130fb09f419109e40a6be267bfbd8c88", + "earlycasualcaiman_sorted_merged_md_sorted_shifted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "97e6eaae1cda668da59e5c16a9bbcc1d", + "hugelymodelbat_sorted_merged_md_sorted_shifted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "427b5e476d84c5277d2d24210800ad60", + "slowlycivilbuck_sorted_merged_md_sorted_shifted.bam.bai" + ] + ] + ], + "timestamp": "2026-06-12T15:07:25.051508", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwameme - wgs": { + "content": [ + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "9266e8231917cc16ff9845e50ed22801" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "1df3c2e109a79ba4e7b8293aefbad8" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "645db4b1d55d6d42cba2b55eee1a630" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "earlycasualcaiman_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "hugelymodelbat_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "slowlycivilbuck_sorted_md.cram.crai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "9266e8231917cc16ff9845e50ed22801", + "earlycasualcaiman_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "1df3c2e109a79ba4e7b8293aefbad8", + "hugelymodelbat_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "645db4b1d55d6d42cba2b55eee1a630", + "slowlycivilbuck_sorted_md.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "c55f8bf7b7c42ad8dcef6565eff4440b", + "earlycasualcaiman.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "7fc6a7a47e90fb46daeff00093c7c498", + "hugelymodelbat.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "f0b3fe7d566ae0db56bb85e17d8ec28f", + "slowlycivilbuck.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "c96587f3323ea479aebf0a8ba3ee710b", + "earlycasualcaiman_sorted_merged_md_sorted_shifted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "9f79604c77dc54d30daff682a50399bf", + "hugelymodelbat_sorted_merged_md_sorted_shifted.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "8d810d8acecdeadc5a0e7ea159cb1343", + "slowlycivilbuck_sorted_merged_md_sorted_shifted.bam.bai" + ] + ] + ], + "timestamp": "2026-06-12T15:26:16.997745", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwameme - wes, stub": { + "content": [ + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "earlycasualcaiman_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "hugelymodelbat_sorted_md.cram.crai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "slowlycivilbuck_sorted_md.cram.crai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_sorted_md.bam.bai" + ], + [ + { + "groupSize": 1, + "groupTarget": { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + } + }, + "d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_sorted_md.bam.bai" + ] + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-25T13:17:03.89564829", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/align/tests/nextflow.config b/subworkflows/local/align/tests/nextflow.config new file mode 100644 index 000000000..5a3bc1cdf --- /dev/null +++ b/subworkflows/local/align/tests/nextflow.config @@ -0,0 +1,137 @@ +process { + + withName: 'BWAMEME_INDEX' { + ext.args = '-a meme' + } + + withName: 'FASTP' { + ext.args = { [ + params.min_trimmed_length ? "--length_required ${params.min_trimmed_length}" : '', + '--correction', + '--overrepresentation_analysis' + ].join(' ').trim() } + } + + withName: 'CONVERTTOCRAM_ALTFILTERED' { + ext.args = { '--output-fmt cram' } + ext.prefix = { "${meta.id}_sorted_md_primary_contigs" } + } + + withName: 'CONVERTTOCRAM_UNFILTERED' { + ext.args = { '--output-fmt cram' } + ext.prefix = { "${meta.id}_sorted_md" } + } + + withName: 'SAMTOOLS_VIEW_EXCLUDE_ALT' { + ext.args = { '--fetch-pairs' } + ext.args2 = { + params.genome == 'GRCh38' + ? ((1..22).collect { n -> "chr${n}" } + ['chrX', 'chrY', 'chrM']).join(' ') + : ((1..22).collect { n -> "${n}" } + ['X', 'Y', 'MT' ]).join(' ') + } + ext.prefix = { "${meta.id}_sorted_md_primary_contigs" } + } + + withName: 'BWAMEM2_MEM' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWAMEM_FALLBACK' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWAMEME_MEM' { + ext.args = { "-7 -M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWA' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'SAMTOOLS_STATS' { + ext.args = '-s --remove-overlaps' + } + + withName: 'SAMTOOLS_MERGE' { + ext.prefix = { "${meta.id}_sorted_merged" } + } + + withName: 'EXTRACT_ALIGNMENTS' { + ext.prefix = { "${meta.id}_sorted_merged_extracted" } + ext.args2 = { params.restrict_to_contigs } + } + + withName: 'MARKDUPLICATES' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_sorted_md" } + } + + withName: 'GATK4_PRINTREADS_MT' { + ext.args = { [ + "-L ${params.mito_name}", + "--read-filter MateOnSameContigOrNoMappedMateReadFilter", + "--read-filter MateUnmappedAndUnmappedReadFilter", + "--tmp-dir ." + ].join(" ").trim() } + } + + withName: 'GATK4_REVERTSAM_MT' { + ext.args = '--TMP_DIR . --OUTPUT_BY_READGROUP false --VALIDATION_STRINGENCY LENIENT --ATTRIBUTE_TO_CLEAR FT --ATTRIBUTE_TO_CLEAR CO --SORT_ORDER queryname --RESTORE_ORIGINAL_QUALITIES false' + } + + withName: 'GATK4_SAMTOFASTQ_MT' { + ext.args = '--VALIDATION_STRINGENCY LENIENT --TMP_DIR .' + } + + withName: 'BWAMEM2_MEM_MT' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWA_MEM_MT' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'SENTIEON_BWAMEM_MT' { + ext.args = { "-M -K 10000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'GATK4_MERGEBAMALIGNMENT_MT' { + ext.args = '--TMP_DIR . --CREATE_INDEX true --MAX_GAPS -1 --SORT_ORDER queryname --INCLUDE_SECONDARY_ALIGNMENTS false --PAIRED_RUN false --VALIDATION_STRINGENCY LENIENT' + ext.prefix = { "${meta.id}_sorted_merged" } + } + + withName: 'PICARD_ADDORREPLACEREADGROUPS_MT' { + ext.args = { [ + "--VALIDATION_STRINGENCY LENIENT", + "--RGLB lib", + "--RGPL ${params.platform}", + "--RGPU barcode", + "--RGSM ${meta.id}", + "--TMP_DIR ./temp_folder" + ].join(' ').trim() } + } + + withName: 'PICARD_MARKDUPLICATES_MT' { + ext.args = '--TMP_DIR . --VALIDATION_STRINGENCY LENIENT --CREATE_INDEX true' + ext.prefix = { "${meta.id}_sorted_merged_md" } + } + + withName: 'SAMTOOLS_SORT_MT' { + ext.prefix = { "${meta.id}_sorted_merged_md_sorted" } + } + +} diff --git a/subworkflows/local/align_MT/main.nf b/subworkflows/local/align_MT/main.nf index 7a0c1d2cc..75fe65c74 100644 --- a/subworkflows/local/align_MT/main.nf +++ b/subworkflows/local/align_MT/main.nf @@ -2,40 +2,36 @@ // Align MT // -include { BWA_MEM as BWA_MEM_MT } from '../../../modules/nf-core/bwa/mem/main' -include { SENTIEON_BWAMEM as SENTIEON_BWAMEM_MT } from '../../../modules/nf-core/sentieon/bwamem/main' include { BWAMEM2_MEM as BWAMEM2_MEM_MT } from '../../../modules/nf-core/bwamem2/mem/main' +include { BWA_MEM as BWA_MEM_MT } from '../../../modules/nf-core/bwa/mem/main' include { GATK4_MERGEBAMALIGNMENT as GATK4_MERGEBAMALIGNMENT_MT } from '../../../modules/nf-core/gatk4/mergebamalignment/main' include { PICARD_ADDORREPLACEREADGROUPS as PICARD_ADDORREPLACEREADGROUPS_MT } from '../../../modules/nf-core/picard/addorreplacereadgroups/main' include { PICARD_MARKDUPLICATES as PICARD_MARKDUPLICATES_MT } from '../../../modules/nf-core/picard/markduplicates/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_MT } from '../../../modules/nf-core/samtools/index/main' include { SAMTOOLS_SORT as SAMTOOLS_SORT_MT } from '../../../modules/nf-core/samtools/sort/main' +include { SENTIEON_BWAMEM as SENTIEON_BWAMEM_MT } from '../../../modules/nf-core/sentieon/bwamem/main' workflow ALIGN_MT { take: - ch_fastq // channel: [mandatory] [ val(meta), [ path(reads) ] ] - ch_ubam // channel: [mandatory] [ val(meta), path(bam) ] ch_bwaindex // channel: [mandatory for sentieon] [ val(meta), path(index) ] ch_bwamem2index // channel: [mandatory for bwamem2] [ val(meta), path(index) ] - ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_dict // channel: [mandatory] [ val(meta), path(dict) ] ch_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_fastq // channel: [mandatory] [ val(meta), [ path(reads) ] ] + ch_ubam // channel: [mandatory] [ val(meta), path(bam) ] + val_mt_aligner // string: 'bwa', 'bwamem2', or 'sentieon' main: - ch_versions = Channel.empty() - if (params.mt_aligner.equals("bwamem2")) { + if (val_mt_aligner.equals("bwamem2")) { BWAMEM2_MEM_MT (ch_fastq, ch_bwamem2index, ch_fasta, true) ch_align = BWAMEM2_MEM_MT.out.bam - ch_versions = ch_versions.mix(BWAMEM2_MEM_MT.out.versions.first()) - } else if (params.mt_aligner.equals("sentieon")) { + } else if (val_mt_aligner.equals("sentieon")) { SENTIEON_BWAMEM_MT ( ch_fastq, ch_bwaindex, ch_fasta, ch_fai ) - ch_align = SENTIEON_BWAMEM_MT.out.bam_and_bai.map{ meta, bam, bai -> [meta, bam] } - ch_versions = ch_versions.mix(SENTIEON_BWAMEM_MT.out.versions.first()) - } else if (params.mt_aligner.equals("bwa")) { + ch_align = SENTIEON_BWAMEM_MT.out.bam_and_bai.map{ meta, bam, _bai -> [meta, bam] } + } else if (val_mt_aligner.equals("bwa")) { BWA_MEM_MT ( ch_fastq, ch_bwaindex, ch_fasta, true ) ch_align = BWA_MEM_MT.out.bam - ch_versions = ch_versions.mix(BWA_MEM_MT.out.versions.first()) } ch_align .join(ch_ubam, failOnMismatch:true, failOnDuplicate:true) @@ -47,18 +43,9 @@ workflow ALIGN_MT { PICARD_MARKDUPLICATES_MT (PICARD_ADDORREPLACEREADGROUPS_MT.out.bam, ch_fasta, ch_fai) - SAMTOOLS_SORT_MT (PICARD_MARKDUPLICATES_MT.out.bam, [[:],[]]) - - SAMTOOLS_INDEX_MT(SAMTOOLS_SORT_MT.out.bam) - - ch_versions = ch_versions.mix(GATK4_MERGEBAMALIGNMENT_MT.out.versions.first()) - ch_versions = ch_versions.mix(PICARD_ADDORREPLACEREADGROUPS_MT.out.versions.first()) - ch_versions = ch_versions.mix(PICARD_MARKDUPLICATES_MT.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_SORT_MT.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_MT.out.versions.first()) + SAMTOOLS_SORT_MT (PICARD_MARKDUPLICATES_MT.out.bam, [[:],[]], 'bai') emit: + marked_bai = SAMTOOLS_SORT_MT.out.bai // channel: [ val(meta), path(bai) ] marked_bam = SAMTOOLS_SORT_MT.out.bam // channel: [ val(meta), path(bam) ] - marked_bai = SAMTOOLS_INDEX_MT.out.bai // channel: [ val(meta), path(bai) ] - versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/align_MT/tests/main.nf.test b/subworkflows/local/align_MT/tests/main.nf.test new file mode 100644 index 000000000..986daca5c --- /dev/null +++ b/subworkflows/local/align_MT/tests/main.nf.test @@ -0,0 +1,295 @@ +nextflow_workflow { + + name "Test Workflow ALIGN_MT" + script "subworkflows/local/align_MT/main.nf" + workflow "ALIGN_MT" + + tag "subworkflows" + tag "align_mt" + + tag "bwa/mem" + tag "bwamem2/mem" + tag "sentieon/bwamem" + tag "gatk4/mergebamalignment" + tag "picard/addorreplacereadgroups" + tag "picard/markduplicates" + tag "samtools/sort" + + config "./nextflow.config" + + test("align mt - bwamem2") { + + setup { + run("BWAMEM2_INDEX", alias: 'MT_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'mt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_mt.fa', checkIfExists: true) + ]) + """ + } + } + } + when { + params { + outdir = "$outputDir" + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + } + workflow { + """ + input[0] = [[:],[]] + input[1] = MT_MEM2.out.index.collect() + input[2] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)]]) + input[3] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]]) + input[4] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]]) + input[5] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_2.fastq.gz', checkIfExists: true)] + ] + ) + input[6] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mtreverted.bam', checkIfExists: true)] + ] + ) + input[7] = "bwamem2" + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + + test("align mt - bwa") { + + setup { + run("BWA_INDEX", alias: 'MT_BWA') { + script "modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'mt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_mt.fa', checkIfExists: true) + ]) + """ + } + } + } + when { + params { + outdir = "$outputDir" + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + } + workflow { + """ + input[0] = MT_BWA.out.index.collect() + input[1] = [[:],[]] + input[2] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)]]) + input[3] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]]) + input[4] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]]) + input[5] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_2.fastq.gz', checkIfExists: true)] + ] + ) + input[6] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mtreverted.bam', checkIfExists: true)] + ] + ) + input[7] = 'bwa' + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + + + test("align mt - bwamem2, stub") { + + setup { + run("BWAMEM2_INDEX", alias: 'MT_MEM2') { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'mt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_mt.fa', checkIfExists: true) + ]) + """ + } + } + } + + options "-stub" + + when { + params { + outdir = "$outputDir" + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + } + workflow { + """ + input[0] = [[:],[]] + input[1] = MT_MEM2.out.index.collect() + input[2] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)]]) + input[3] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]]) + input[4] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]]) + input[5] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_2.fastq.gz', checkIfExists: true)] + ] + ) + input[6] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mtreverted.bam', checkIfExists: true)] + ] + ) + input[7] = "bwamem2" + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + + test("align mt - bwa, stub") { + + setup { + run("BWA_INDEX", alias: 'MT_BWA') { + script "modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'mt'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/reference_mt.fa', checkIfExists: true) + ]) + """ + } + } + } + + options "-stub" + + when { + params { + outdir = "$outputDir" + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + } + workflow { + """ + input[0] = MT_BWA.out.index.collect() + input[1] = [[:],[]] + input[2] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)]]) + input[3] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]]) + input[4] = channel.value([[id:'mt'], [file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]]) + input[5] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_1.fastq.gz', checkIfExists: true), file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mt_2.fastq.gz', checkIfExists: true)] + ] + ) + input[6] = channel.of( + [ + [ id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", 'lane':1, 'sex':1, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", 'lane':1, 'sex':1, 'phenotype':2, 'paternal':'earlycasualcaiman', 'maternal':'slowlycivilbuck', 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/hugelymodelbat_mtreverted.bam', checkIfExists: true)] + ], + [ + [ id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", 'lane':1, 'sex':2, 'phenotype':1, 'paternal':0, 'maternal':0, 'case_id':'justhusky' ], // meta map + [ file(params.pipelines_testdata_base_path + '/testdata/slowlycivilbuck_mtreverted.bam', checkIfExists: true)] + ] + ) + input[7] = 'bwa' + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + +} diff --git a/subworkflows/local/align_MT/tests/main.nf.test.snap b/subworkflows/local/align_MT/tests/main.nf.test.snap new file mode 100644 index 000000000..f122b005c --- /dev/null +++ b/subworkflows/local/align_MT/tests/main.nf.test.snap @@ -0,0 +1,846 @@ +{ + "align mt - bwamem2, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-04-08T15:49:24.73309", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "align mt - bwa, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-04-08T15:51:10.749046", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "align mt - bwamem2": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,aa29752265d70e5c2ed10de503fa8b33" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,011888be5d5c6e77b48d8b8fd81155a4" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,9934e5e180a1760490bc36aaf23ec10c" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d4ea71dac6170a728c27457e4d042a17" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,eba491066ead408a1cdfd13fd353fc1d" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,3263f88b4f8987f16b81a5980bf26aad" + ] + ], + "marked_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,aa29752265d70e5c2ed10de503fa8b33" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,011888be5d5c6e77b48d8b8fd81155a4" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,9934e5e180a1760490bc36aaf23ec10c" + ] + ], + "marked_bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,d4ea71dac6170a728c27457e4d042a17" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,eba491066ead408a1cdfd13fd353fc1d" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,3263f88b4f8987f16b81a5980bf26aad" + ] + ] + } + ], + "timestamp": "2026-02-27T15:43:54.097536585", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "align mt - bwa": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,bc1e2296080bc0d6d9878d3784892ee0" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,8df5c65448c3c2f20cd8f574182f5593" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,de7d63cfa5735162d2274d877bf0b85b" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,7ee847d7f586a961a446566f8d473c30" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d294ef713b4f83c621be387294d7937e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,ffe465201f5119c2699a49cd110628d3" + ] + ], + "marked_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam.bai:md5,bc1e2296080bc0d6d9878d3784892ee0" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam.bai:md5,8df5c65448c3c2f20cd8f574182f5593" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam.bai:md5,de7d63cfa5735162d2274d877bf0b85b" + ] + ], + "marked_bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_sorted_merged_md_sorted.bam:md5,7ee847d7f586a961a446566f8d473c30" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 2, + "paternal": "earlycasualcaiman", + "maternal": "slowlycivilbuck", + "case_id": "justhusky" + }, + "hugelymodelbat_sorted_merged_md_sorted.bam:md5,d294ef713b4f83c621be387294d7937e" + ], + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:slowlycivilbuck\\tPL:illumina\\tSM:slowlycivilbuck'", + "lane": 1, + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_sorted_merged_md_sorted.bam:md5,ffe465201f5119c2699a49cd110628d3" + ] + ] + } + ], + "timestamp": "2026-02-27T15:45:57.190438488", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/align_MT/tests/nextflow.config b/subworkflows/local/align_MT/tests/nextflow.config new file mode 100644 index 000000000..d894a94c4 --- /dev/null +++ b/subworkflows/local/align_MT/tests/nextflow.config @@ -0,0 +1,46 @@ +process { + + withName: 'BWAMEM2_MEM_MT' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWA_MEM_MT' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'SENTIEON_BWAMEM_MT' { + ext.args = { "-M -K 10000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'GATK4_MERGEBAMALIGNMENT_MT' { + ext.args = '--TMP_DIR . --CREATE_INDEX true --MAX_GAPS -1 --SORT_ORDER queryname --INCLUDE_SECONDARY_ALIGNMENTS false --PAIRED_RUN false --VALIDATION_STRINGENCY LENIENT' + ext.prefix = { "${meta.id}_sorted_merged" } + } + + withName: 'PICARD_ADDORREPLACEREADGROUPS_MT' { + ext.args = { [ + "--VALIDATION_STRINGENCY LENIENT", + "--RGLB lib", + "--RGPL ${params.platform}", + "--RGPU barcode", + "--RGSM ${meta.id}", + "--TMP_DIR ./temp_folder" + ].join(' ').trim() } + } + + withName: 'PICARD_MARKDUPLICATES_MT' { + ext.args = '--TMP_DIR . --VALIDATION_STRINGENCY LENIENT --CREATE_INDEX true' + ext.prefix = { "${meta.id}_sorted_merged_md" } + } + + withName: 'SAMTOOLS_SORT_MT' { + ext.prefix = { "${meta.id}_sorted_merged_md_sorted" } + } + +} diff --git a/subworkflows/local/align_bwa_bwamem2_bwameme/main.nf b/subworkflows/local/align_bwa_bwamem2_bwameme/main.nf index 315279666..062cd645f 100644 --- a/subworkflows/local/align_bwa_bwamem2_bwameme/main.nf +++ b/subworkflows/local/align_bwa_bwamem2_bwameme/main.nf @@ -2,62 +2,46 @@ // Map to reference, fetch stats for each demultiplexed read pair, merge, mark duplicates, and index. // -include { BWA_MEM as BWA } from '../../../modules/nf-core/bwa/mem/main' -include { BWA_MEM as BWAMEM_FALLBACK } from '../../../modules/nf-core/bwa/mem/main' +include { BWAFASTALIGN_MEM } from '../../../modules/nf-core/bwafastalign/mem/main' include { BWAMEM2_MEM } from '../../../modules/nf-core/bwamem2/mem/main' include { BWAMEME_MEM } from '../../../modules/nf-core/bwameme/mem/main' +include { BWA_MEM as BWA } from '../../../modules/nf-core/bwa/mem/main' +include { PICARD_MARKDUPLICATES as MARKDUPLICATES } from '../../../modules/nf-core/picard/markduplicates/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_ALIGN } from '../../../modules/nf-core/samtools/index/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_EXTRACT } from '../../../modules/nf-core/samtools/index/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_MARKDUP } from '../../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_STATS } from '../../../modules/nf-core/samtools/stats/main' include { SAMTOOLS_MERGE } from '../../../modules/nf-core/samtools/merge/main' +include { SAMTOOLS_STATS } from '../../../modules/nf-core/samtools/stats/main' include { SAMTOOLS_VIEW as EXTRACT_ALIGNMENTS } from '../../../modules/nf-core/samtools/view/main' -include { PICARD_MARKDUPLICATES as MARKDUPLICATES } from '../../../modules/nf-core/picard/markduplicates/main' workflow ALIGN_BWA_BWAMEM2_BWAMEME { take: - ch_reads_input // channel: [mandatory] [ val(meta), path(reads_input) ] - ch_bwa_index // channel: [mandatory] [ val(meta), path(bwamem2_index) ] - ch_bwamem2_index // channel: [mandatory] [ val(meta), path(bwamem2_index) ] - ch_bwameme_index // channel: [mandatory] [ val(meta), path(bwamem2_index) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - val_mbuffer_mem // integer: [mandatory] default: 3072 - val_platform // string: [mandatory] default: illumina - val_sort_threads // integer: [mandatory] default: 4 - main: - ch_versions = Channel.empty() + ch_bwa_index // channel: [mandatory] [ val(meta), path(bwa_index) ] + ch_bwafastalign_index // channel: [mandatory] [ val(meta), path(bwafastalign_index) ] + ch_bwamem2_index // channel: [mandatory] [ val(meta), path(bwamem2_index) ] + ch_bwameme_index // channel: [mandatory] [ val(meta), path(bwameme_index) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_input_reads // channel: [mandatory] [ val(meta), path(reads_input) ] + val_aligner // string: 'bwa', 'bwafastalign', 'bwamem2', or 'bwameme' + val_extract_alignments // boolean + val_platform // string: [mandatory] default: illumina + main: // Map, sort, and index - if (params.aligner.equals("bwa")) { - BWA ( ch_reads_input, ch_bwa_index, ch_genome_fasta, true ) + if (val_aligner.equals("bwa")) { + BWA ( ch_input_reads, ch_bwa_index, ch_genome_fasta, true ) ch_align = BWA.out.bam - ch_versions = ch_versions.mix(BWA.out.versions.first()) - } else if (params.aligner.equals("bwameme")) { - BWAMEME_MEM ( ch_reads_input, ch_bwameme_index, ch_genome_fasta, true, val_mbuffer_mem, val_sort_threads ) - ch_align = BWAMEME_MEM.out.bam - ch_versions = ch_versions.mix(BWAMEME_MEM.out.versions.first()) + } else if (val_aligner.equals("bwafastalign")) { + BWAFASTALIGN_MEM ( ch_input_reads, ch_bwafastalign_index, ch_genome_fasta, true ) + ch_align = BWAFASTALIGN_MEM.out.output + } else if (val_aligner.equals("bwameme")) { + BWAMEME_MEM ( ch_input_reads, ch_bwameme_index, ch_genome_fasta, true ) + ch_align = BWAMEME_MEM.out.output } else { - BWAMEM2_MEM ( ch_reads_input, ch_bwamem2_index, ch_genome_fasta, true ) + BWAMEM2_MEM ( ch_input_reads, ch_bwamem2_index, ch_genome_fasta, true ) ch_align = BWAMEM2_MEM.out.bam - ch_versions = ch_versions.mix(BWAMEM2_MEM.out.versions.first()) - - if (params.bwa_as_fallback) { - ch_reads_input - .join(BWAMEM2_MEM.out.bam, remainder: true) - .branch { it -> - ERROR: it[2].equals(null) - return [it[0], it[1]] // return reads - SUCCESS: !it[2].equals(null) - return [it[0], it[2]] // return bam - } - .set { ch_fallback } - - BWAMEM_FALLBACK ( ch_fallback.ERROR, ch_bwa_index, ch_genome_fasta, true ) - ch_align = ch_fallback.SUCCESS.mix(BWAMEM_FALLBACK.out.bam) - ch_versions = ch_versions.mix(BWAMEM_FALLBACK.out.versions.first()) - } } SAMTOOLS_INDEX_ALIGN ( ch_align ) @@ -74,40 +58,31 @@ workflow ALIGN_BWA_BWAMEM2_BWAMEME { [groupKey(new_meta, new_meta.num_lanes), bam] } .groupTuple() - .branch{ - single: it[1].size() == 1 - multiple: it[1].size() > 1 + .branch{ _meta, bam -> + single: bam.size() == 1 + multiple: bam.size() > 1 } .set{ bams } // If there are no samples to merge, skip the process - SAMTOOLS_MERGE ( bams.multiple, ch_genome_fasta, ch_genome_fai ) + SAMTOOLS_MERGE ( bams.multiple.map { it -> it + [[]] }, ch_genome_fasta.join(ch_genome_fai).map{meta,fasta,fai-> return [meta,fasta,fai,[]]}.collect()) prepared_bam = bams.single.mix(SAMTOOLS_MERGE.out.bam) // GET ALIGNMENT FROM SELECTED CONTIGS - if (params.extract_alignments) { + if (val_extract_alignments) { SAMTOOLS_INDEX_EXTRACT ( prepared_bam ) extract_bam_sorted_indexed = prepared_bam.join(SAMTOOLS_INDEX_EXTRACT.out.bai, failOnMismatch:true, failOnDuplicate:true) - EXTRACT_ALIGNMENTS( extract_bam_sorted_indexed, ch_genome_fasta, []) + EXTRACT_ALIGNMENTS( extract_bam_sorted_indexed, ch_genome_fasta.join(ch_genome_fai).collect(), [], '') prepared_bam = EXTRACT_ALIGNMENTS.out.bam - ch_versions = ch_versions.mix(EXTRACT_ALIGNMENTS.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_EXTRACT.out.versions.first()) } // Marking duplicates MARKDUPLICATES ( prepared_bam , ch_genome_fasta, ch_genome_fai ) SAMTOOLS_INDEX_MARKDUP ( MARKDUPLICATES.out.bam ) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_ALIGN.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_STATS.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_MERGE.out.versions.first()) - ch_versions = ch_versions.mix(MARKDUPLICATES.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_MARKDUP.out.versions.first()) - emit: - stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] - metrics = MARKDUPLICATES.out.metrics // channel: [ val(meta), path(metrics) ] - marked_bam = MARKDUPLICATES.out.bam // channel: [ val(meta), path(bam) ] - marked_bai = SAMTOOLS_INDEX_MARKDUP.out.bai // channel: [ val(meta), path(bai) ] - versions = ch_versions // channel: [ path(versions.yml) ] + marked_bai = SAMTOOLS_INDEX_MARKDUP.out.bai // channel: [ val(meta), path(bai) ] + marked_bam = MARKDUPLICATES.out.bam // channel: [ val(meta), path(bam) ] + markdup_metrics = MARKDUPLICATES.out.metrics // channel: [ val(meta), path(metrics) ] + stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] } diff --git a/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test new file mode 100644 index 000000000..a48f21698 --- /dev/null +++ b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test @@ -0,0 +1,295 @@ +nextflow_workflow { + + name "Test Workflow ALIGN_BWA_BWAMEM2_BWAMEME" + script "subworkflows/local/align_bwa_bwamem2_bwameme/main.nf" + workflow "ALIGN_BWA_BWAMEM2_BWAMEME" + + tag "subworkflows" + tag "align_bwa_bwamem2_bwameme" + + tag "bwa/mem" + tag "bwafastalign/mem" + tag "bwamem2/mem" + tag "bwameme/mem" + tag "samtools/index" + tag "samtools/stats" + tag "samtools/merge" + tag "samtools/view" + tag "picard/markduplicates" + + config "./nextflow.config" + + test("align bwamem2") { + + setup { + run("BWAMEM2_INDEX") { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + restrict_to_contigs = "MT192765.1" + } + workflow { + """ + input[0] = [[:],[]] + input[1] = [[:],[]] + input[2] = BWAMEM2_INDEX.out.index + input[3] = [[:],[]] + input[4] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[5] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[6] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[7] = "bwamem2" + input[8] = true + input[9] = "illumina" + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.markdup_metrics.collect { meta, metrics -> file(metrics).name }, + workflow.out.stats, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getHeaderMD5() ] }, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] } + ).match() + } + ) + } + } + + test("align bwafastalign") { + + setup { + run("BWAFASTALIGN_INDEX") { + script "modules/nf-core/bwafastalign/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + restrict_to_contigs = "MT192765.1" + } + workflow { + """ + input[0] = [[:],[]] + input[1] = BWAFASTALIGN_INDEX.out.index + input[2] = [[:],[]] + input[3] = [[:],[]] + input[4] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[5] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[6] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[7] = "bwafastalign" + input[8] = true + input[9] = "illumina" + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.markdup_metrics.collect { meta, metrics -> file(metrics).name }, + workflow.out.stats, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getHeaderMD5() ] }, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] } + ).match() + } + ) + } + } + + test("align bwameme") { + + setup { + run("BWAMEME_INDEX") { + script "modules/nf-core/bwameme/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + restrict_to_contigs = "MT192765.1" + } + workflow { + """ + input[0] = [[:],[]] + input[1] = [[:],[]] + input[2] = [[:],[]] + input[3] = BWAMEME_INDEX.out.index + input[4] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[5] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[6] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group:"\'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test\'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[7] = "bwameme" + input[8] = true + input[9] = "illumina" + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.markdup_metrics.collect { meta, metrics -> file(metrics).name }, + workflow.out.stats, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getHeaderMD5() ] }, + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] } + ).match() + } + ) + } + } + + test("align bwamem2, stub") { + + setup { + run("BWAMEM2_INDEX") { + script "modules/nf-core/bwamem2/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + options "-stub" + + when { + params { + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + restrict_to_contigs = "MT192765.1" + } + workflow { + """ + input[0] = [[:],[]] + input[1] = [[:],[]] + input[2] = BWAMEM2_INDEX.out.index + input[3] = [[:],[]] + input[4] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[5] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[6] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[7] = "bwamem2" + input[8] = true + input[9] = "illumina" + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + } + + test("align bwameme, stub") { + + setup { + run("BWAMEME_INDEX") { + script "modules/nf-core/bwameme/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + options "-stub" + + when { + params { + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + restrict_to_contigs = "MT192765.1" + } + workflow { + """ + input[0] = [[:],[]] + input[1] = [[:],[]] + input[2] = [[:],[]] + input[3] = BWAMEME_INDEX.out.index + input[4] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[5] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[6] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group:"\'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test\'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[7] = "bwameme" + input[8] = true + input[9] = "illumina" + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + } + +} diff --git a/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test.snap b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test.snap new file mode 100644 index 000000000..9ea55417c --- /dev/null +++ b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/main.nf.test.snap @@ -0,0 +1,414 @@ +{ + "align bwafastalign": { + "content": [ + [ + "test_sorted_md.metrics.txt" + ], + [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,f0914a56ae73007ebd242cab27861700" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "b88d51cb3010d98935b39ef6a3c58499" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "af8628d9df18b2d3d4f6fd47ef2bb872" + ] + ] + ], + "timestamp": "2026-06-25T13:30:01.076823606", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "align bwamem2": { + "content": [ + [ + "test_sorted_md.metrics.txt" + ], + [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,f0914a56ae73007ebd242cab27861700" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "72b312c47e502b8272741a40e435b96" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "af8628d9df18b2d3d4f6fd47ef2bb872" + ] + ] + ], + "timestamp": "2026-04-08T14:47:44.537374", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwamem2, stub": { + "content": [ + { + "0": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "markdup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bam": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-11T16:06:18.512372", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwameme, stub": { + "content": [ + { + "0": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "markdup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "marked_bam": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-11T16:06:37.969441", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "align bwameme": { + "content": [ + [ + "test_sorted_md.metrics.txt" + ], + [ + [ + { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + }, + "test.stats:md5,f0914a56ae73007ebd242cab27861700" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "11413e81e47d32ac386d29b693693a2e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "af8628d9df18b2d3d4f6fd47ef2bb872" + ] + ] + ], + "timestamp": "2026-04-08T14:48:21.046802", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/align_bwa_bwamem2_bwameme/tests/nextflow.config b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/nextflow.config new file mode 100644 index 000000000..99347febb --- /dev/null +++ b/subworkflows/local/align_bwa_bwamem2_bwameme/tests/nextflow.config @@ -0,0 +1,49 @@ +process { + + withName: 'BWAFASTALIGN_INDEX' { + memory = 15.GB + } + + withName: 'BWAFASTALIGN_MEM' { + memory = 15.GB + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args3 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWAMEME_INDEX' { + ext.args = '-a meme' + } + + withName: 'BWAMEME_MEM' { + memory = 15.GB + ext.args = { "-7 -M -K 100000000 -R ${meta.read_group}" } + ext.args3 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'BWAMEM2_MEM' { + ext.args = { "-M -K 100000000 -R ${meta.read_group}" } + ext.args2 = { "-T ./samtools_sort_tmp" } + ext.prefix = { "${meta.id}_sorted" } + } + + withName: 'SAMTOOLS_STATS' { + ext.args = '-s --remove-overlaps' + } + + withName: 'SAMTOOLS_MERGE' { + ext.prefix = { "${meta.id}_sorted_merged" } + } + + withName: 'EXTRACT_ALIGNMENTS' { + ext.prefix = { "${meta.id}_sorted_merged_extracted" } + ext.args2 = { params.restrict_to_contigs } + } + + withName: 'MARKDUPLICATES' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_sorted_md" } + } + +} diff --git a/subworkflows/local/align_sentieon/main.nf b/subworkflows/local/align_sentieon/main.nf index 15e03b6d9..5d7ee89d7 100644 --- a/subworkflows/local/align_sentieon/main.nf +++ b/subworkflows/local/align_sentieon/main.nf @@ -2,25 +2,24 @@ // A subworkflow to annotate structural variants. // -include { SENTIEON_BWAMEM } from '../../../modules/nf-core/sentieon/bwamem/main' -include { SENTIEON_DATAMETRICS } from '../../../modules/nf-core/sentieon/datametrics/main' -include { SENTIEON_DEDUP } from '../../../modules/nf-core/sentieon/dedup/main' -include { SENTIEON_READWRITER } from '../../../modules/nf-core/sentieon/readwriter/main' -include { SAMTOOLS_VIEW as EXTRACT_ALIGNMENTS } from '../../../modules/nf-core/samtools/view/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_EXTRACT } from '../../../modules/nf-core/samtools/index/main' +include { SAMTOOLS_VIEW as EXTRACT_ALIGNMENTS } from '../../../modules/nf-core/samtools/view/main' +include { SENTIEON_BWAMEM } from '../../../modules/nf-core/sentieon/bwamem/main' +include { SENTIEON_DATAMETRICS } from '../../../modules/nf-core/sentieon/datametrics/main' +include { SENTIEON_DEDUP } from '../../../modules/nf-core/sentieon/dedup/main' +include { SENTIEON_READWRITER } from '../../../modules/nf-core/sentieon/readwriter/main' workflow ALIGN_SENTIEON { take: - ch_reads_input // channel: [mandatory] [ val(meta), path(reads_input) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_bwa_index // channel: [mandatory] [ val(meta), path(bwa_index) ] - val_platform // string: [mandatory] default: illumina + ch_bwa_index // channel: [mandatory] [ val(meta), path(bwa_index) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_input_reads // channel: [mandatory] [ val(meta), path(reads_input) ] + val_extract_alignments // string: boolean + val_platform // string: [mandatory] default: illumina main: - ch_versions = Channel.empty() - SENTIEON_BWAMEM ( ch_reads_input, ch_bwa_index, ch_genome_fasta, ch_genome_fai ) + SENTIEON_BWAMEM ( ch_input_reads, ch_bwa_index, ch_genome_fasta, ch_genome_fai ) SENTIEON_BWAMEM.out .bam_and_bai @@ -30,9 +29,9 @@ workflow ALIGN_SENTIEON { [groupKey(new_meta, new_meta.num_lanes), bam, bai] } .groupTuple() - .branch{ - single: it[1].size() == 1 - multiple: it[1].size() > 1 + .branch{ _meta, bam, _bai -> + single: bam.size() == 1 + multiple: bam.size() > 1 } .set{ merge_bams_in } @@ -40,33 +39,25 @@ workflow ALIGN_SENTIEON { ch_bam_bai = merge_bams_in.single.mix(SENTIEON_READWRITER.out.output_index) // GET ALIGNMENT FROM SELECTED CONTIGS - if (params.extract_alignments) { - EXTRACT_ALIGNMENTS( ch_bam_bai, ch_genome_fasta, []) - ch_bam_bai = EXTRACT_ALIGNMENTS.out.bam - SAMTOOLS_INDEX_EXTRACT ( EXTRACT_ALIGNMENTS.out.bam ) - ch_bam_bai = EXTRACT_ALIGNMENTS.out.bam.join(SAMTOOLS_INDEX_EXTRACT.out.bai, failOnMismatch:true, failOnDuplicate:true) - ch_versions = ch_versions.mix(EXTRACT_ALIGNMENTS.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_EXTRACT.out.versions.first()) - + if (val_extract_alignments) { + EXTRACT_ALIGNMENTS( ch_bam_bai, ch_genome_fasta.join(ch_genome_fai).collect(), [], 'bai') + ch_bam_bai = EXTRACT_ALIGNMENTS.out.bam.join(EXTRACT_ALIGNMENTS.out.bai, failOnMismatch:true, failOnDuplicate:true) } SENTIEON_DATAMETRICS ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, false ) SENTIEON_DEDUP ( ch_bam_bai, ch_genome_fasta, ch_genome_fai ) - ch_versions = ch_versions.mix(SENTIEON_BWAMEM.out.versions.first()) - ch_versions = ch_versions.mix(SENTIEON_DATAMETRICS.out.versions.first()) - ch_versions = ch_versions.mix(SENTIEON_READWRITER.out.versions.first()) - ch_versions = ch_versions.mix(SENTIEON_DEDUP.out.versions.first()) - emit: - marked_bam = SENTIEON_DEDUP.out.bam // channel: [ val(meta), path(bam) ] - marked_bai = SENTIEON_DEDUP.out.bai // channel: [ val(meta), path(bai) ] - mq_metrics = SENTIEON_DATAMETRICS.out.mq_metrics.ifEmpty(null) // channel: [ val(meta), path(mq_metrics) ] - qd_metrics = SENTIEON_DATAMETRICS.out.qd_metrics.ifEmpty(null) // channel: [ val(meta), path(qd_metrics) ] - gc_metrics = SENTIEON_DATAMETRICS.out.gc_metrics.ifEmpty(null) // channel: [ val(meta), path(gc_metrics) ] - gc_summary = SENTIEON_DATAMETRICS.out.gc_summary.ifEmpty(null) // channel: [ val(meta), path(gc_summary) ] - aln_metrics = SENTIEON_DATAMETRICS.out.aln_metrics.ifEmpty(null) // channel: [ val(meta), path(aln_metrics) ] - is_metrics = SENTIEON_DATAMETRICS.out.is_metrics.ifEmpty(null) // channel: [ val(meta), path(is_metrics) ] - versions = ch_versions // channel: [ path(versions.yml) ] + marked_bam = SENTIEON_DEDUP.out.bam // channel: [ val(meta), path(bam) ] + marked_bai = SENTIEON_DEDUP.out.bai // channel: [ val(meta), path(bai) ] + score = SENTIEON_DEDUP.out.score // channel: [ val(meta), path(score) ] + dedup_metrics = SENTIEON_DEDUP.out.metrics // channel: [ val(meta), path(metrics) ] + dedup_metrics_multiqc = SENTIEON_DEDUP.out.metrics_multiqc_tsv // channel: [ val(meta), path(tsv) ] + mq_metrics = SENTIEON_DATAMETRICS.out.mq_metrics.ifEmpty(null) // channel: [ val(meta), path(mq_metrics) ] + qd_metrics = SENTIEON_DATAMETRICS.out.qd_metrics.ifEmpty(null) // channel: [ val(meta), path(qd_metrics) ] + gc_metrics = SENTIEON_DATAMETRICS.out.gc_metrics.ifEmpty(null) // channel: [ val(meta), path(gc_metrics) ] + gc_summary = SENTIEON_DATAMETRICS.out.gc_summary.ifEmpty(null) // channel: [ val(meta), path(gc_summary) ] + aln_metrics = SENTIEON_DATAMETRICS.out.aln_metrics.ifEmpty(null) // channel: [ val(meta), path(aln_metrics) ] + is_metrics = SENTIEON_DATAMETRICS.out.is_metrics.ifEmpty(null) // channel: [ val(meta), path(is_metrics) ] } diff --git a/subworkflows/local/align_sentieon/tests/main.nf.test b/subworkflows/local/align_sentieon/tests/main.nf.test new file mode 100644 index 000000000..e0500aa00 --- /dev/null +++ b/subworkflows/local/align_sentieon/tests/main.nf.test @@ -0,0 +1,143 @@ +nextflow_workflow { + + name "Test Workflow ALIGN_SENTIEON" + script "subworkflows/local/align_sentieon/main.nf" + workflow "ALIGN_SENTIEON" + + tag "subworkflows" + tag "align_sentieon" + + tag "sentieon/bwamem" + tag "sentieon/datametrics" + tag "sentieon/dedup" + tag "sentieon/readwriter" + tag "samtools/view" + + config "./nextflow.config" + + test("align sentieon") { + + setup { + run("SENTIEON_BWAINDEX") { + script "modules/nf-core/sentieon/bwaindex/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + params { + aligner = "sentieon" + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + save_noalt_mapped_as_cram = false + save_all_mapped_as_cram = true + } + workflow { + """ + input[0] = SENTIEON_BWAINDEX.out.index + input[1] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[2] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[4] = false + input[5] = "illumina" + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] }, + workflow.out.marked_bai.collect { meta, baifile -> [ meta, file(baifile).name ] }, + workflow.out.aln_metrics, + workflow.out.gc_metrics, + workflow.out.gc_summary, + workflow.out.is_metrics, + workflow.out.mq_metrics, + workflow.out.qd_metrics, + workflow.out.dedup_metrics, + workflow.out.dedup_metrics_multiqc, + workflow.out.score, + ).match() + } + ) + } + + } + + test("align sentieon, stub") { + + setup { + run("SENTIEON_BWAINDEX") { + script "modules/nf-core/sentieon/bwaindex/main.nf" + process { + """ + input[0] = channel.of([ + [id:'sarscov2'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + } + + options "-stub" + + when { + params { + aligner = "sentieon" + sarscov_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + save_mapped_as_cram = true + } + workflow { + """ + input[0] = SENTIEON_BWAINDEX.out.index + input[1] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]]) + input[2] = channel.of([[id:'sarscov2'], [file(params.sarscov_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]]) + input[3] = channel.of([ + [ id:'test', sample:'test', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:test\\\\tPL:illumina\\\\tSM:test'" ], // meta map + [ + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.sarscov_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[4] = false + input[5] = "illumina" + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.marked_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] }, + workflow.out.marked_bai.collect { meta, baifile -> [ meta, file(baifile).name ] }, + workflow.out.aln_metrics, + workflow.out.gc_metrics, + workflow.out.gc_summary, + workflow.out.is_metrics, + workflow.out.mq_metrics, + workflow.out.qd_metrics, + workflow.out.dedup_metrics, + workflow.out.dedup_metrics_multiqc, + workflow.out.score, + ).match() + } + ) + } + } +} diff --git a/subworkflows/local/align_sentieon/tests/main.nf.test.snap b/subworkflows/local/align_sentieon/tests/main.nf.test.snap new file mode 100644 index 000000000..261a909f4 --- /dev/null +++ b/subworkflows/local/align_sentieon/tests/main.nf.test.snap @@ -0,0 +1,350 @@ +{ + "align sentieon, stub": { + "content": [ + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_aln_metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_gc_metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_gc_summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_is_metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_mq_metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_qd_metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.metrics.multiqc.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.score:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "timestamp": "2026-06-15T14:36:45.068348415", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "align sentieon": { + "content": [ + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "2d64e4363d9f3c0e2167fce49d5087cf" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.bai" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_aln_metrics.txt:md5,e016dd74f156d0b31a787903b8fef29c" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_gc_metrics.txt:md5,003ed2dae28d295e5005fc2be942fd24" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_gc_summary.txt:md5,c238cb8240e7145ea62fd7bc26787cf5" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_is_metrics.txt:md5,47dec263ece77d2f5816012a345e8531" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_mq_metrics.txt:md5,a0ee4d2b9970df49fed3f262c10b5e16" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_datametrics_qd_metrics.txt:md5,8192ba26ccf5cea0778e9ed2cf187430" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.metrics:md5,67c42dfe156b0613d30966768d01b55c" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.bam.metrics.multiqc.tsv:md5,67c42dfe156b0613d30966768d01b55c" + ] + ], + [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "sample": "test", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:test\\tPL:illumina\\tSM:test'" + } + }, + "test_dedup.score:md5,107725946bfe75d63c82d4f330872833" + ] + ] + ], + "timestamp": "2026-06-15T14:42:21.699949612", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/align_sentieon/tests/nextflow.config b/subworkflows/local/align_sentieon/tests/nextflow.config new file mode 100644 index 000000000..a5eb17b20 --- /dev/null +++ b/subworkflows/local/align_sentieon/tests/nextflow.config @@ -0,0 +1,24 @@ +process { + + withName: 'SENTIEON_BWAMEM' { + ext.args = { "-M -K 10000000 -R ${meta.read_group} " } + ext.prefix = { "${meta.id}_sorted.bam" } + } + + withName: 'SENTIEON_DATAMETRICS' { + ext.prefix = { "${meta.id}_datametrics" } + } + + withName: 'SENTIEON_READWRITER' { + ext.prefix = { "${meta.id}_merged.bam" } + } + + withName: 'EXTRACT_ALIGNMENTS' { + ext.prefix = { "${meta.id}_merged_extracted" } + } + + withName: 'SENTIEON_DEDUP' { + ext.args4 = { params.rmdup ? "--rmdup" : '' } + ext.prefix = { "${meta.id}_dedup.bam" } + } +} diff --git a/subworkflows/local/annotate_cadd/main.nf b/subworkflows/local/annotate_cadd/main.nf index 1b5821228..92f0b6d5d 100644 --- a/subworkflows/local/annotate_cadd/main.nf +++ b/subworkflows/local/annotate_cadd/main.nf @@ -2,49 +2,65 @@ // A subworkflow to annotate snvs // -include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' -include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' -include { CADD } from '../../../modules/nf-core/cadd/main' -include { TABIX_TABIX as TABIX_ANNOTATE } from '../../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_CADD } from '../../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_VIEW } from '../../../modules/nf-core/tabix/tabix/main' +include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' +include { BCFTOOLS_ANNOTATE as RENAME_CHRNAMES } from '../../../modules/nf-core/bcftools/annotate/main' +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' +include { CADD } from '../../../modules/nf-core/cadd/main' +include { GAWK as CADD_TO_REFERENCE_CHRNAMES } from '../../../modules/nf-core/gawk/main' +include { GAWK as REFERENCE_TO_CADD_CHRNAMES } from '../../../modules/nf-core/gawk/main' +include { TABIX_TABIX as TABIX_CADD } from '../../../modules/nf-core/tabix/tabix/main' workflow ANNOTATE_CADD { take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcfs), path(idx) ] - ch_header // channel: [mandatory] [ path(txt) ] - ch_cadd_resources // channel: [mandatory] [ path(dir) ] + ch_cadd_resources // channel: [mandatory] [ val(meta), path(dir) ] + ch_cadd_prescored // channel: [optional] [ val(meta), path(prescored) ] + ch_fai // channel: [optional] [ val(meta), path(fai) ] + ch_header // channel: [mandatory] [ path(txt) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcfs), path(idx) ] + val_genome // string: GRCh37 or GRCh38 main: - ch_versions = Channel.empty() + ch_rename_chrs = channel.value([[]]) - BCFTOOLS_VIEW(ch_vcf, [], [], []) + if (val_genome.equals('GRCh38')) { + + REFERENCE_TO_CADD_CHRNAMES ( ch_fai , [], false ) + + CADD_TO_REFERENCE_CHRNAMES ( ch_fai , [], false ) + + CADD_TO_REFERENCE_CHRNAMES.out.output.map { _meta, txt -> txt } + .set { ch_rename_chrs } + + ch_vcf + .map { meta, vcf, tbi -> [ meta, vcf, tbi, [], [], [], [] ] } + .combine(REFERENCE_TO_CADD_CHRNAMES.out.output.map { _meta, txt -> txt }) + .set { ch_rename_chrnames_in } - TABIX_VIEW(BCFTOOLS_VIEW.out.vcf) + RENAME_CHRNAMES ( ch_rename_chrnames_in ) - CADD(BCFTOOLS_VIEW.out.vcf, ch_cadd_resources) + RENAME_CHRNAMES.out.vcf + .map { meta, vcf -> [ meta, vcf, [] ] } + .set { ch_vcf } + } + + BCFTOOLS_VIEW(ch_vcf, [], [], []) + + CADD(BCFTOOLS_VIEW.out.vcf, ch_cadd_resources, ch_cadd_prescored) TABIX_CADD(CADD.out.tsv) ch_vcf .join(CADD.out.tsv) - .join(TABIX_CADD.out.tbi) + .join(TABIX_CADD.out.index) + .map { meta, vcf, tbi, ann, ann_tbi -> [ meta, vcf, tbi, ann, ann_tbi, [] ] } + .combine(ch_header) + .combine(ch_rename_chrs) .set { ch_annotate_in } - BCFTOOLS_ANNOTATE(ch_annotate_in, ch_header) - - TABIX_ANNOTATE (BCFTOOLS_ANNOTATE.out.vcf) - - ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_VIEW.out.versions.first()) - ch_versions = ch_versions.mix(CADD.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_CADD.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_ANNOTATE.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_ANNOTATE.out.versions.first()) + BCFTOOLS_ANNOTATE(ch_annotate_in) emit: + tbi = BCFTOOLS_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = TABIX_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/annotate_cadd/tests/main.nf.test b/subworkflows/local/annotate_cadd/tests/main.nf.test new file mode 100644 index 000000000..d5afb3bb3 --- /dev/null +++ b/subworkflows/local/annotate_cadd/tests/main.nf.test @@ -0,0 +1,83 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_CADD" + script "subworkflows/local/annotate_cadd/main.nf" + workflow "ANNOTATE_CADD" + + tag "subworkflows" + tag "annotate_cadd" + + tag "bcftools/annotate" + tag "bcftools/view" + tag "cadd" + tag "gawk" + tag "tabix/tabix" + + config "./nextflow.config" + + test("ANNOTATE_CADD - GRCh37, stub") { + + options "-stub" + + when { + params { + genome = "GRCh37" + } + workflow { + """ + input[0] = Channel.from("\$PWD").map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[1] = channel.value([[:], []]) + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)).collect() + input[4] = channel.of([ + [id:'test', single_end: false], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[5] = 'GRCh37' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("ANNOTATE_CADD - GRCh38, stub") { + + options "-stub" + + when { + params { + genome = "GRCh38" + } + workflow { + """ + input[0] = Channel.from("\$PWD").map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[1] = channel.value([[:], []]) + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)).collect() + input[4] = channel.of([ + [id:'test', single_end: false], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[5] = 'GRCh38' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out).match() } + ) + } + } + +} diff --git a/subworkflows/local/annotate_cadd/tests/main.nf.test.snap b/subworkflows/local/annotate_cadd/tests/main.nf.test.snap new file mode 100644 index 000000000..7e4551e80 --- /dev/null +++ b/subworkflows/local/annotate_cadd/tests/main.nf.test.snap @@ -0,0 +1,96 @@ +{ + "ANNOTATE_CADD - GRCh37, stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-06T09:35:25.19740914", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_CADD - GRCh38, stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann_ann.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann_ann.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann_ann.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test_ann_ann.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-27T13:31:28.294196962", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_cadd/tests/nextflow.config b/subworkflows/local/annotate_cadd/tests/nextflow.config new file mode 100644 index 000000000..6b649a5a7 --- /dev/null +++ b/subworkflows/local/annotate_cadd/tests/nextflow.config @@ -0,0 +1,34 @@ +process { + + withName: 'BCFTOOLS_VIEW' { + ext.args = { "--output-type z --types indels,other" } + ext.prefix = { "${vcf.simpleName}_indels" } + } + + withName: 'CADD' { + container = "nf-core/ubuntu:22.04" //Using an basic container because v1.7.3 is too big for CI. + ext.args = { "-g ${params.genome}" } + ext.prefix = { "${vcf.simpleName}_cadd" } + } + + withName: 'TABIX_CADD' { + ext.args = { "--force --sequence 1 --begin 2 --end 2" } + } + + withName: 'BCFTOOLS_ANNOTATE' { + ext.args = { "--columns Chrom,Pos,Ref,Alt,-,CADD --output-type z --write-index=tbi" } + ext.prefix = { "${input.simpleName}_ann" } + } + + withName: 'CADD_TO_REFERENCE_CHRNAMES' { + ext.args2 = '\'{original=$1; sub("chr","",$1); print $1, original}\'' + ext.prefix = "cadd_to_reference" + ext.suffix = "txt" + } + + withName: 'REFERENCE_TO_CADD_CHRNAMES' { + ext.args2 = '\'{original=$1; sub("chr","",$1); print original, $1}\'' + ext.prefix = "reference_to_cadd" + ext.suffix = "txt" + } +} diff --git a/subworkflows/local/annotate_consequence_pli.nf b/subworkflows/local/annotate_consequence_pli.nf deleted file mode 100644 index 5b625a7b2..000000000 --- a/subworkflows/local/annotate_consequence_pli.nf +++ /dev/null @@ -1,31 +0,0 @@ -// -// A subworkflow to add most severe consequence and pli to a vep annotated vcf -// - -include { ADD_MOST_SEVERE_CSQ } from '../../modules/local/add_most_severe_consequence' -include { ADD_MOST_SEVERE_PLI } from '../../modules/local/add_most_severe_pli' -include { TABIX_BGZIPTABIX } from '../../modules/nf-core/tabix/bgziptabix/main' - -workflow ANNOTATE_CSQ_PLI { - take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_variant_consequences // channel: [mandatory] [ path(consequences) ] - - main: - ch_versions = Channel.empty() - - ADD_MOST_SEVERE_CSQ (ch_vcf, ch_variant_consequences) - - ADD_MOST_SEVERE_PLI (ADD_MOST_SEVERE_CSQ.out.vcf) - - TABIX_BGZIPTABIX (ADD_MOST_SEVERE_PLI.out.vcf) - - ch_versions = ch_versions.mix(ADD_MOST_SEVERE_CSQ.out.versions) - ch_versions = ch_versions.mix(ADD_MOST_SEVERE_PLI.out.versions) - ch_versions = ch_versions.mix(TABIX_BGZIPTABIX.out.versions) - - emit: - vcf_ann = TABIX_BGZIPTABIX.out.gz_tbi.map { meta, vcf, tbi -> return [ meta, vcf ] } // channel: [ val(meta), path(vcf) ] - tbi_ann = TABIX_BGZIPTABIX.out.gz_tbi.map { meta, vcf, tbi -> return [ meta, tbi ] } // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/annotate_consequence_pli/main.nf b/subworkflows/local/annotate_consequence_pli/main.nf new file mode 100644 index 000000000..7629731ad --- /dev/null +++ b/subworkflows/local/annotate_consequence_pli/main.nf @@ -0,0 +1,29 @@ +// +// A subworkflow to add most severe consequence and pli to a vep annotated vcf +// + +include { CUSTOM_ADDMOSTSEVERECONSEQUENCE } from '../../../modules/local/custom/addmostsevereconsequence' +include { CUSTOM_ADDMOSTSEVEREPLI } from '../../../modules/local/custom/addmostseverepli' +include { TABIX_TABIX } from '../../../modules/nf-core/tabix/tabix/main' + +workflow ANNOTATE_CSQ_PLI { + take: + ch_variant_consequences // channel: [mandatory] [ path(consequences) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + val_index // bool + + main: + CUSTOM_ADDMOSTSEVERECONSEQUENCE (ch_vcf, ch_variant_consequences) + + CUSTOM_ADDMOSTSEVEREPLI (CUSTOM_ADDMOSTSEVERECONSEQUENCE.out.vcf) + + ch_tbi = channel.empty() + if (val_index) { + TABIX_TABIX(CUSTOM_ADDMOSTSEVEREPLI.out.vcf) + ch_tbi = TABIX_TABIX.out.index + } + + emit: + tbi = ch_tbi // channel: [ val(meta), path(tbi) ] + vcf_ann = CUSTOM_ADDMOSTSEVEREPLI.out.vcf // channel: [ val(meta), path(vcf) ] +} diff --git a/subworkflows/local/annotate_consequence_pli/tests/main.nf.test b/subworkflows/local/annotate_consequence_pli/tests/main.nf.test new file mode 100644 index 000000000..35035998c --- /dev/null +++ b/subworkflows/local/annotate_consequence_pli/tests/main.nf.test @@ -0,0 +1,102 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_CSQ_PLI" + script "subworkflows/local/annotate_consequence_pli/main.nf" + workflow "ANNOTATE_CSQ_PLI" + + tag "custom/addmostsevereconsequence" + tag "custom/addmostseverepli" + tag "tabix/tabix" + + tag "subworkflows" + tag "annotate_consequence_pli" + + config './nextflow.config' + + test("ANNOTATE_CSQ_PLI - no index") { + + when { + workflow { + """ + input[0] = channel.of([ + [id:'var_csq'], + file(params.pipelines_testdata_base_path + 'reference/variant_consequences_v2.txt', checkIfExists: true) + ]).collect() + input[1] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ]) + input[2] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.vcf_ann[0][1]).vcf.variantsMD5, + path(workflow.out.vcf_ann[0][1]).vcf.summary + ).match() } + ) + } + } + + test("ANNOTATE_CSQ_PLI - with index") { + + when { + workflow { + """ + input[0] = channel.of([ + [id:'var_csq'], + file(params.pipelines_testdata_base_path + 'reference/variant_consequences_v2.txt', checkIfExists: true) + ]).collect() + input[1] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ]) + input[2] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_ann.collect { meta, f -> file(f).name }, + workflow.out.tbi.collect { meta, f -> file(f).name }, + path(workflow.out.vcf_ann[0][1]).vcf.variantsMD5, + path(workflow.out.vcf_ann[0][1]).vcf.summary + ).match() } + ) + } + } + test("ANNOTATE_CSQ_PLI - with index, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'var_csq'], + file(params.pipelines_testdata_base_path + 'reference/variant_consequences_v2.txt', checkIfExists: true) + ]).collect() + input[1] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/genmod_compound.vcf', checkIfExists: true) + ]) + input[2] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_consequence_pli/tests/main.nf.test.snap b/subworkflows/local/annotate_consequence_pli/tests/main.nf.test.snap new file mode 100644 index 000000000..c50352284 --- /dev/null +++ b/subworkflows/local/annotate_consequence_pli/tests/main.nf.test.snap @@ -0,0 +1,73 @@ +{ + "ANNOTATE_CSQ_PLI - with index": { + "content": [ + [ + "severepli.vcf.gz" + ], + [ + "severepli.vcf.gz.tbi" + ], + "58d9c7a329ee86094acc0826b671652c", + "VcfFile [chromosomes=[MT], sampleCount=3, variantCount=22, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-06-26T16:05:57.762515171", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_CSQ_PLI - no index": { + "content": [ + "58d9c7a329ee86094acc0826b671652c", + "VcfFile [chromosomes=[MT], sampleCount=3, variantCount=22, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-03-01T17:08:08.450262918", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_CSQ_PLI - with index, stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "severepli.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "severepli.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "justhusky" + }, + "severepli.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf_ann": [ + [ + { + "id": "justhusky" + }, + "severepli.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-26T15:58:14.350740472", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_consequence_pli/tests/nextflow.config b/subworkflows/local/annotate_consequence_pli/tests/nextflow.config new file mode 100644 index 000000000..5fcc87840 --- /dev/null +++ b/subworkflows/local/annotate_consequence_pli/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + withName: "CUSTOM_ADDMOSTSEVEREPLI" { + ext.prefix = 'severepli' + } + withName: "CUSTOM_ADDMOSTSEVERECONSEQUENCE" { + ext.prefix = 'severecsq' + } +} diff --git a/subworkflows/local/annotate_genome_snvs.nf b/subworkflows/local/annotate_genome_snvs.nf deleted file mode 100644 index 62d3808ee..000000000 --- a/subworkflows/local/annotate_genome_snvs.nf +++ /dev/null @@ -1,192 +0,0 @@ -// -// A subworkflow to annotate snvs in the genome -// - -include { VCFANNO } from '../../modules/nf-core/vcfanno/main' -include { BCFTOOLS_CONCAT } from '../../modules/nf-core/bcftools/concat/main' -include { BCFTOOLS_ROH } from '../../modules/nf-core/bcftools/roh/main' -include { BCFTOOLS_VIEW } from '../../modules/nf-core/bcftools/view/main' -include { RHOCALL_ANNOTATE } from '../../modules/nf-core/rhocall/annotate/main' -include { UPD as UPD_SITES } from '../../modules/nf-core/upd/main' -include { UPD as UPD_REGIONS } from '../../modules/nf-core/upd/main' -include { CHROMOGRAPH as CHROMOGRAPH_SITES } from '../../modules/nf-core/chromograph/main' -include { CHROMOGRAPH as CHROMOGRAPH_REGIONS } from '../../modules/nf-core/chromograph/main' -include { ENSEMBLVEP_VEP as ENSEMBLVEP_SNV } from '../../modules/nf-core/ensemblvep/vep/main' -include { TABIX_BGZIPTABIX as ZIP_TABIX_ROHCALL } from '../../modules/nf-core/tabix/bgziptabix/main' -include { TABIX_BGZIPTABIX as ZIP_TABIX_VCFANNO } from '../../modules/nf-core/tabix/bgziptabix/main' -include { TABIX_TABIX as TABIX_VEP } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_BCFTOOLS_CONCAT } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_BCFTOOLS_VIEW } from '../../modules/nf-core/tabix/tabix/main' -include { GATK4_SELECTVARIANTS } from '../../modules/nf-core/gatk4/selectvariants/main' -include { ANNOTATE_CADD } from './annotate_cadd' -include { ANNOTATE_RHOCALLVIZ } from './annotate_rhocallviz' - -workflow ANNOTATE_GENOME_SNVS { - - take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] - analysis_type // string: [mandatory] 'wgs' or 'wes' - ch_cadd_header // channel: [mandatory] [ path(txt) ] - ch_cadd_resources // channel: [mandatory] [ path(annotation) ] - ch_vcfanno_extra // channel: [mandatory] [ [path(vcf),path(index)] ] - ch_vcfanno_resources // channel: [mandatory] [ [path(vcf1),path(index1),...,path(vcfn),path(indexn)] ] - ch_vcfanno_lua // channel: [mandatory] [ path(lua) ] - ch_vcfanno_toml // channel: [mandatory] [ path(toml) ] - val_vep_genome // string: [mandatory] GRCh37 or GRCh38 - val_vep_cache_version // string: [mandatory] default: 107 - ch_vep_cache // channel: [mandatory] [ path(cache) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_gnomad_af // channel: [optional] [ path(tab), path(tbi) ] - ch_samples // channel: [mandatory] [ val(sample_meta) ] - ch_split_intervals // channel: [mandatory] [ path(intervals) ] - ch_vep_extra_files // channel: [mandatory] [ path(files) ] - ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] - - main: - ch_cadd_vcf = Channel.empty() - ch_versions = Channel.empty() - ch_vcf_scatter_in = Channel.empty() - ch_vep_in = Channel.empty() - - BCFTOOLS_ROH (ch_vcf, ch_gnomad_af, [], [], [], []) - - RHOCALL_ANNOTATE (ch_vcf, BCFTOOLS_ROH.out.roh, []) - - ZIP_TABIX_ROHCALL (RHOCALL_ANNOTATE.out.vcf) - - ch_vcf - .join(ZIP_TABIX_ROHCALL.out.gz_tbi, remainder: true) - .combine(ch_split_intervals) - .map { it -> - if (it[3].equals(null)) { - return [it[0] + [prefix: it[0].id, scatterid:it[4].baseName], it[1], it[2], it[4]] - } else { - return [it[0] + [prefix: it[0].id + "_rhocall", scatterid:it[5].baseName], it[3], it[4], it[5]] - } - } - .set { ch_vcf_scatter_in } - - GATK4_SELECTVARIANTS (ch_vcf_scatter_in) - - GATK4_SELECTVARIANTS.out.vcf - .join(GATK4_SELECTVARIANTS.out.tbi) - .combine(ch_vcfanno_extra) - .set { ch_vcfanno_in } - - VCFANNO (ch_vcfanno_in, ch_vcfanno_toml, ch_vcfanno_lua, ch_vcfanno_resources) - - ZIP_TABIX_VCFANNO (VCFANNO.out.vcf) - - BCFTOOLS_VIEW(ZIP_TABIX_VCFANNO.out.gz_tbi, [], [], []) // filter on frequencies - - // Annotating with CADD - if (params.cadd_resources != null) { - TABIX_BCFTOOLS_VIEW (BCFTOOLS_VIEW.out.vcf) - - BCFTOOLS_VIEW.out.vcf - .join(TABIX_BCFTOOLS_VIEW.out.tbi, failOnMismatch:true, failOnDuplicate:true) - .set { ch_cadd_in } - - ANNOTATE_CADD ( - ch_cadd_in, - ch_cadd_header, - ch_cadd_resources - ) - ch_cadd_vcf = ANNOTATE_CADD.out.vcf - ch_versions = ch_versions.mix(ANNOTATE_CADD.out.versions) - ch_versions = ch_versions.mix(TABIX_BCFTOOLS_VIEW.out.versions) - } - - // If CADD is run, pick CADD output as input for VEP else pass selectvariants output to VEP. - BCFTOOLS_VIEW.out.vcf - .join(ch_cadd_vcf, remainder: true) // If CADD is not run then the third element in this channel will be `null` - .branch { it -> // If CADD is run, then "it" will be [[meta],selvar.vcf,cadd.vcf], else [[meta],selvar.vcf,null] - selvar: it[2].equals(null) - return [it[0] + [prefix: it[0].prefix + "_filter"], it[1]] - cadd: !(it[2].equals(null)) - return [it[0] + [prefix: it[0].prefix + "_filter_cadd"], it[2]] - } - .set { ch_for_mix } - - ch_for_mix.selvar.mix(ch_for_mix.cadd) - .map { meta, vcf -> return [meta, vcf, []] } - .set { ch_vep_in } - - // Annotating with ensembl Vep - ENSEMBLVEP_SNV( - ch_vep_in, - val_vep_genome, - "homo_sapiens", - val_vep_cache_version, - ch_vep_cache, - ch_genome_fasta, - ch_vep_extra_files - ) - - ENSEMBLVEP_SNV.out.vcf - .map { meta, vcf -> [meta - meta.subMap('scatterid'), vcf] } - .set { ch_vep_out } - - TABIX_VEP (ch_vep_out) - - ch_vep_out - .join(TABIX_VEP.out.tbi, failOnMismatch:true) - .groupTuple() - .map { meta, vcfs, tbis -> - def sortedvcfs = vcfs.sort { it.baseName } - def sortedtbis = tbis.sort { it.baseName } - return [ meta, sortedvcfs, sortedtbis ] - } - .set { ch_concat_in } - - BCFTOOLS_CONCAT (ch_concat_in) - - BCFTOOLS_CONCAT.out.vcf - .flatMap { meta, vcf -> - meta.upd_children.collect { upd_sample -> - def new_meta = meta + [upd_child: upd_sample, prefix: meta.prefix + "_vcfanno"] - [new_meta, vcf] - } - } - .set { ch_upd_in } - - UPD_SITES(ch_upd_in) - UPD_REGIONS(ch_upd_in) - CHROMOGRAPH_SITES([[],[]], [[],[]], [[],[]], [[],[]], [[],[]], [[],[]], UPD_SITES.out.bed) - CHROMOGRAPH_REGIONS([[],[]], [[],[]], [[],[]], [[],[]], [[],[]], UPD_REGIONS.out.bed, [[],[]]) - - - BCFTOOLS_CONCAT.out.vcf - .map { meta, vcf -> [meta - meta.subMap('prefix'), vcf] } - .set { ch_concat_out } - - TABIX_BCFTOOLS_CONCAT (ch_concat_out) - - ch_vep_ann = ch_concat_out - ch_vep_index = TABIX_BCFTOOLS_CONCAT.out.tbi - ch_vep_ann_index = ch_concat_out.join(TABIX_BCFTOOLS_CONCAT.out.tbi) - //rhocall_viz - ANNOTATE_RHOCALLVIZ(ch_vep_ann_index, ch_samples, ch_genome_chrsizes) - - ch_versions = ch_versions.mix(BCFTOOLS_ROH.out.versions) - ch_versions = ch_versions.mix(RHOCALL_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(ZIP_TABIX_ROHCALL.out.versions) - ch_versions = ch_versions.mix(VCFANNO.out.versions) - ch_versions = ch_versions.mix(UPD_SITES.out.versions) - ch_versions = ch_versions.mix(UPD_REGIONS.out.versions) - ch_versions = ch_versions.mix(CHROMOGRAPH_SITES.out.versions) - ch_versions = ch_versions.mix(CHROMOGRAPH_REGIONS.out.versions) - ch_versions = ch_versions.mix(ZIP_TABIX_VCFANNO.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions) - ch_versions = ch_versions.mix(GATK4_SELECTVARIANTS.out.versions.first()) - ch_versions = ch_versions.mix(ENSEMBLVEP_SNV.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_VEP.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_CONCAT.out.versions) - ch_versions = ch_versions.mix(TABIX_BCFTOOLS_CONCAT.out.versions) - ch_versions = ch_versions.mix(ANNOTATE_RHOCALLVIZ.out.versions) - - emit: - vcf_ann = ch_vep_ann // channel: [ val(meta), path(vcf) ] - tbi = ch_vep_index // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/annotate_genome_snvs/main.nf b/subworkflows/local/annotate_genome_snvs/main.nf new file mode 100644 index 000000000..992e86646 --- /dev/null +++ b/subworkflows/local/annotate_genome_snvs/main.nf @@ -0,0 +1,217 @@ +// +// A subworkflow to annotate snvs in the genome +// + +include { ANNOTATE_CADD } from '../annotate_cadd' +include { ANNOTATE_RHOCALLVIZ } from '../annotate_rhocallviz' +include { BCFTOOLS_CONCAT } from '../../../modules/nf-core/bcftools/concat/main' +include { BCFTOOLS_ROH } from '../../../modules/nf-core/bcftools/roh/main' +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' +include { CHROMOGRAPH as CHROMOGRAPH_REGIONS } from '../../../modules/nf-core/chromograph/main' +include { CHROMOGRAPH as CHROMOGRAPH_SITES } from '../../../modules/nf-core/chromograph/main' +include { ENSEMBLVEP_VEP as ENSEMBLVEP_SNV } from '../../../modules/nf-core/ensemblvep/vep/main' +include { GATK4_SELECTVARIANTS } from '../../../modules/nf-core/gatk4/selectvariants/main' +include { RHOCALL_ANNOTATE } from '../../../modules/nf-core/rhocall/annotate/main' +include { TABIX_BGZIPTABIX as ZIP_TABIX_ROHCALL } from '../../../modules/nf-core/tabix/bgziptabix/main' +include { UPD as UPD_REGIONS } from '../../../modules/nf-core/upd/main' +include { UPD as UPD_SITES } from '../../../modules/nf-core/upd/main' +include { VCFANNO } from '../../../modules/nf-core/vcfanno/main' + +workflow ANNOTATE_GENOME_SNVS { + + take: + ch_cadd_header // channel: [mandatory] [ path(txt) ] + ch_cadd_prescored // channel: [optional] [ val(meta), path(prescored) ] + ch_cadd_resources // channel: [mandatory] [ val(meta), path(annotation) ] + ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] + ch_genome_fai // channel: [mandatory] [ path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_gnomad_af // channel: [optional] [ path(tab), path(tbi) ] + ch_samples // channel: [mandatory] [ val(sample_meta) ] + ch_split_intervals // channel: [mandatory] [ val(meta), path(interval_list) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] + ch_vcfanno_extra // channel: [mandatory] [ [path(vcf),path(index)] ] + ch_vcfanno_lua // channel: [mandatory] [ path(lua) ] + ch_vcfanno_resources // channel: [mandatory] [ [path(vcf1),path(index1),...,path(vcfn),path(indexn)] ] + ch_vcfanno_toml // channel: [mandatory] [ path(toml) ] + ch_vep_cache // channel: [mandatory] [ path(cache) ] + ch_vep_extra_files // channel: [mandatory] [ path(files) ] + val_analysis_type // string: wgs, wes, or mito + val_cadd_resources // string: path to cadd resources file + val_genome // string: GRCh37 or GRCh38 + val_vep_cache_version // string: vep version ex: 107 + + main: + ch_cadd_vcf = channel.empty() + ch_chromograph_regions_plots = channel.empty() + ch_chromograph_sites_plots = channel.empty() + ch_vcf_scatter_in = channel.empty() + ch_vep_in = channel.empty() + + ch_vcf + .filter { meta, _vcf, _tbi -> + meta.probands.size() > 0 + } + .set { ch_roh_in } + + BCFTOOLS_ROH (ch_roh_in, ch_gnomad_af, [], [], [], []) + + RHOCALL_ANNOTATE (ch_vcf, BCFTOOLS_ROH.out.roh, []) + + ZIP_TABIX_ROHCALL (RHOCALL_ANNOTATE.out.vcf) + + // BCFTOOLS_ROH and RHOCALL_ANNOTATE only run when probands are present (filtered above). + // The remainder:true join pads cases without rohcall output with a single null, giving + // tuples of length 4 (no rohcall) vs 5 (rohcall). After combining with an interval both + // grow by one, so size==6 means this case has probands and a rohcall-annotated VCF. + ch_split_intervals + .flatMap { _meta, intervals -> intervals.collect{ interval -> [interval] } } + .set { ch_split_intervals_flat } + + ch_vcf + .join(ZIP_TABIX_ROHCALL.out.gz_index, remainder: true) + .combine(ch_split_intervals_flat) + .map { it -> + def meta = it[0] + def vcf = it[1] + def tbi = it[2] + + def hasRohCall = (it.size() == 6) + + if (hasRohCall) { + def rohcall = it[3] + def rohcallindex = it[4] + def interval = it[5] + return [ + meta + [prefix: meta.id + "_rhocall", scatterid: interval.baseName], + rohcall, + rohcallindex, + interval + ] + } else { + def interval = it[4] + return [ + meta + [prefix: meta.id, scatterid: interval.baseName], + vcf, + tbi, + interval + ] + } + } + .set { ch_vcf_scatter_in } + + GATK4_SELECTVARIANTS (ch_vcf_scatter_in) + + GATK4_SELECTVARIANTS.out.vcf + .join(GATK4_SELECTVARIANTS.out.tbi) + .combine(ch_vcfanno_extra) + .set { ch_vcfanno_in } + + VCFANNO (ch_vcfanno_in, ch_vcfanno_toml, ch_vcfanno_lua, ch_vcfanno_resources) + + VCFANNO.out.vcf + .join(VCFANNO.out.tbi, failOnMismatch:true, failOnDuplicate:true) + .set { ch_bcftools_view_in } + + // filter on frequencies + BCFTOOLS_VIEW( + ch_bcftools_view_in, + [], [], []) + + // Annotating with CADD + if (!val_cadd_resources.equals(null)) { + + BCFTOOLS_VIEW.out.vcf + .join(BCFTOOLS_VIEW.out.tbi, failOnMismatch:true, failOnDuplicate:true) + .set { ch_cadd_in } + + ANNOTATE_CADD ( + ch_cadd_resources, + ch_cadd_prescored, + ch_genome_fai, + ch_cadd_header, + ch_cadd_in, + val_genome + ) + ch_cadd_vcf = ANNOTATE_CADD.out.vcf + } + + BCFTOOLS_VIEW.out.vcf + .join(ch_cadd_vcf, remainder: true) + .branch { meta, selectvariants, cadd -> + selvar: cadd.equals(null) + return [meta + [prefix: meta.prefix + "_filter"], selectvariants] + cadd: !(cadd.equals(null)) + return [meta + [prefix: meta.prefix + "_filter_cadd"], cadd] + } + .set { ch_annotated_vcfs } + + ch_annotated_vcfs.selvar.mix(ch_annotated_vcfs.cadd) + .map { meta, vcf -> return [meta, vcf, []] } + .set { ch_vep_in } + + // Annotating with ensembl Vep + ENSEMBLVEP_SNV( + ch_vep_in, + val_genome, + "homo_sapiens", + val_vep_cache_version, + ch_vep_cache, + ch_genome_fasta, + ch_vep_extra_files + ) + + ENSEMBLVEP_SNV.out.vcf + .map { meta, vcf -> [meta - meta.subMap('scatterid'), vcf] } + .set { ch_vep_vcf_out } + ENSEMBLVEP_SNV.out.tbi + .map { meta, tbi -> [meta - meta.subMap('scatterid'), tbi] } + .set { ch_vep_tbi_out } + + ch_vep_vcf_out + .join(ch_vep_tbi_out, failOnMismatch:true) + .groupTuple() + .set { ch_concat_in } + + BCFTOOLS_CONCAT (ch_concat_in) + + BCFTOOLS_CONCAT.out.vcf + .flatMap { meta, vcf -> + meta.upd_children.collect { upd_sample -> + def new_meta = meta + [upd_child: upd_sample, prefix: meta.prefix + "_vcfanno"] + [new_meta, vcf] + } + } + .set { ch_upd_in } + + if (val_analysis_type.equals("wgs")) { + UPD_SITES(ch_upd_in) + UPD_REGIONS(ch_upd_in) + CHROMOGRAPH_SITES([[],[]], [[],[]], [[],[]], [[],[]], [[],[]], [[],[]], UPD_SITES.out.bed) + CHROMOGRAPH_REGIONS([[],[]], [[],[]], [[],[]], [[],[]], [[],[]], UPD_REGIONS.out.bed, [[],[]]) + ch_chromograph_sites_plots = CHROMOGRAPH_SITES.out.plots + ch_chromograph_regions_plots = CHROMOGRAPH_REGIONS.out.plots + } + + BCFTOOLS_CONCAT.out.vcf + .map { meta, vcf -> [meta - meta.subMap('prefix'), vcf] } + .set { ch_concat_vcf_out } + + BCFTOOLS_CONCAT.out.tbi + .map { meta, tbi -> [meta - meta.subMap('prefix'), tbi] } + .set { ch_concat_tbi_out } + + ch_vep_ann_index = ch_concat_vcf_out.join(ch_concat_tbi_out, failOnMismatch:true, failOnDuplicate:true) + //rhocall_viz + ANNOTATE_RHOCALLVIZ(ch_genome_chrsizes, ch_samples, ch_vep_ann_index ) + + emit: + bcftools_concat_tbi = ch_concat_tbi_out // channel: [ val(meta), path(tbi) ] + bcftools_concat_vcf = ch_concat_vcf_out // channel: [ val(meta), path(vcf) ] + chromograph_autozyg_plots = ANNOTATE_RHOCALLVIZ.out.chromograph_autozyg_plots // channel: [ val(meta), path(png) ] + chromograph_regions_plots = ch_chromograph_regions_plots // channel: [ val(meta), path(png) ] + chromograph_sites_plots = ch_chromograph_sites_plots // channel: [ val(meta), path(png) ] + rhocall_viz_bed = ANNOTATE_RHOCALLVIZ.out.rhocall_viz_bed // channel: [ val(meta), path(bed) ] + rhocall_viz_wig = ANNOTATE_RHOCALLVIZ.out.rhocall_viz_wig // channel: [ val(meta), path(wig) ] + ucsc_wigtobigwig_bw = ANNOTATE_RHOCALLVIZ.out.ucsc_wigtobigwig_bw // channel: [ val(meta), path(bw) ] +} diff --git a/subworkflows/local/annotate_genome_snvs/tests/main.nf.test b/subworkflows/local/annotate_genome_snvs/tests/main.nf.test new file mode 100644 index 000000000..fe8164eff --- /dev/null +++ b/subworkflows/local/annotate_genome_snvs/tests/main.nf.test @@ -0,0 +1,135 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_GENOME_SNVS" + script "subworkflows/local/annotate_genome_snvs/main.nf" + workflow "ANNOTATE_GENOME_SNVS" + + tag "subworkflows" + tag "annotate_genome_snvs" + tag "annotate_cadd" + tag "annotate_rhocallviz" + + tag "vcfanno" + tag "bcftools/concat" + tag "bcftools/roh" + tag "bcftools/view" + tag "rhocall/annotate" + tag "upd" + tag "chromograph" + tag "ensemblvep/vep" + tag "tabix/bgziptabix" + tag "gatk4/selectvariants" + + config "./nextflow.config" + + test("ANNOTATE_GENOME_SNVS - GRCh37, wgs, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([[id:'resources'], file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)]).collect() + input[1] = channel.value([[:], []]) + input[2] = Channel.from(env('PWD')).map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[3] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[5] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[6] = channel.value([[],[]]) + input[7] = channel.of([id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:2, paternal:0, maternal:0, case_id:'justhusky']) + input[8] = channel.of([[id:'genome'], [file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)]]) + input[9] = channel.of([ + [id:'justhusky', probands:['earlycasualcaiman'], upd_children:['earlycasualcaiman'], mother:'', father:''], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[10] = channel.value([[]]) + input[11] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_functions.lua', checkIfExists: true)).collect() + input[12] = channel.value(file(params.pipelines_testdata_base_path + 'reference/grch38_gnomad_reformated_-r3.1.1-.vcf.gz', checkIfExists: true)) + input[13] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_config.toml', checkIfExists: true)).collect() + input[14] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[15] = channel.value([]) + input[16] = 'wgs' + input[17] = null + input[18] = 'GRCh37' + input[19] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + // Unwrap nested lists to get the filename + def sortKey = item + while (sortKey instanceof List) { + sortKey = sortKey[-1] + } + // Extract filename: strip :md5, suffix then take basename only + // (sortKey may be a raw Path with an absolute work-dir prefix) + sortKey.toString().split(':md5,')[0].tokenize('/')[-1] + } + [name, sorted_channel] + }.sort { it[0] } + ).match() } + ) + } + } + + test("ANNOTATE_GENOME_SNVS - GRCh37, wes, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([[id:'resources'], file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)]).collect() + input[1] = channel.value([[:], []]) + input[2] = Channel.from(env('PWD')).map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[3] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[5] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[6] = channel.value([[],[]]) + input[7] = channel.of([id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:2, paternal:0, maternal:0, case_id:'justhusky']) + input[8] = channel.of([[id:'genome'], [file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)]]) + input[9] = channel.of([ + [id:'justhusky', probands:['earlycasualcaiman'], upd_children:['earlycasualcaiman'], mother:'', father:''], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[10] = channel.value([[]]) + input[11] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_functions.lua', checkIfExists: true)).collect() + input[12] = channel.value(file(params.pipelines_testdata_base_path + 'reference/grch38_gnomad_reformated_-r3.1.1-.vcf.gz', checkIfExists: true)) + input[13] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_config.toml', checkIfExists: true)).collect() + input[14] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[15] = channel.value([]) + input[16] = 'wes' + input[17] = null + input[18] = 'GRCh37' + input[19] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List) { + sortKey = sortKey[-1] + } + sortKey.toString().split(':md5,')[0].tokenize('/')[-1] + } + [name, sorted_channel] + }.sort { it[0] } + ).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_genome_snvs/tests/main.nf.test.snap b/subworkflows/local/annotate_genome_snvs/tests/main.nf.test.snap new file mode 100644 index 000000000..98d758912 --- /dev/null +++ b/subworkflows/local/annotate_genome_snvs/tests/main.nf.test.snap @@ -0,0 +1,724 @@ +{ + "ANNOTATE_GENOME_SNVS - GRCh37, wes, stub": { + "content": [ + [ + [ + "0", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "1", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "2", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "3", + [ + + ] + ], + [ + "4", + [ + + ] + ], + [ + "5", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "6", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "7", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "bcftools_concat_tbi", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "bcftools_concat_vcf", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "chromograph_autozyg_plots", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "chromograph_regions_plots", + [ + + ] + ], + [ + "chromograph_sites_plots", + [ + + ] + ], + [ + "rhocall_viz_bed", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "rhocall_viz_wig", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "ucsc_wigtobigwig_bw", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ] + ], + "timestamp": "2026-06-25T15:16:55.298746259", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_GENOME_SNVS - GRCh37, wgs, stub": { + "content": [ + [ + [ + "0", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "1", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "2", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "3", + [ + [ + [ + + ], + [ + "earlycasualcaiman_upd_regions.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "4", + [ + [ + [ + + ], + [ + "earlycasualcaiman_upd_sites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "5", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "6", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "7", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "bcftools_concat_tbi", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "bcftools_concat_vcf", + [ + [ + { + "id": "justhusky", + "probands": [ + "earlycasualcaiman" + ], + "upd_children": [ + "earlycasualcaiman" + ], + "mother": "", + "father": "" + }, + "justhusky_rhocall_filter_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "chromograph_autozyg_plots", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "chromograph_regions_plots", + [ + [ + [ + + ], + [ + "earlycasualcaiman_upd_regions.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_regions.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "chromograph_sites_plots", + [ + [ + [ + + ], + [ + "earlycasualcaiman_upd_sites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_upd_sites.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "rhocall_viz_bed", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "rhocall_viz_wig", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "ucsc_wigtobigwig_bw", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 2, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ] + ], + "timestamp": "2026-06-25T15:14:21.312733081", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_genome_snvs/tests/nextflow.config b/subworkflows/local/annotate_genome_snvs/tests/nextflow.config new file mode 100644 index 000000000..9f051f6a3 --- /dev/null +++ b/subworkflows/local/annotate_genome_snvs/tests/nextflow.config @@ -0,0 +1,73 @@ +process { + + withName: 'BCFTOOLS_ROH' { + ext.args = { "--samples ${meta.probands.unique().first()} --skip-indels " } + ext.prefix = { "${meta.id}_roh" } + } + + withName: 'RHOCALL_ANNOTATE' { + ext.args = { "--v14 " } + } + + withName: 'ZIP_TABIX_ROHCALL' { + ext.prefix = { "${input.simpleName}" } + } + + withName: 'GATK4_SELECTVARIANTS' { + ext.prefix = { "${vcf.simpleName}_${intervals.simpleName}" } + } + + withName: 'VCFANNO' { + ext.prefix = { "${meta.prefix}_vcfanno_${meta.scatterid}" } + } + + withName: 'UPD_SITES' { + ext.prefix = { "${meta.upd_child}_upd_sites" } + ext.args = {"--af-tag GNOMADAF --proband ${meta.upd_child} --mother ${meta.mother} --father ${meta.father} sites"} + } + + withName: 'UPD_REGIONS' { + ext.prefix = { "${meta.upd_child}_upd_regions" } + ext.args = {"--af-tag GNOMADAF --proband ${meta.upd_child} --mother ${meta.mother} --father ${meta.father} regions --min-size 5 --min-sites 1"} + } + + withName: 'CHROMOGRAPH_SITES' { + ext.prefix = { "${meta7.upd_child}_chromograph_sites" } + ext.args = { "--euploid" } + } + + withName: 'CHROMOGRAPH_REGIONS' { + ext.prefix = { "${meta6.upd_child}_chromograph_regions" } + ext.args = { '--euploid' } + } + + withName: 'ZIP_TABIX_VCFANNO' { + ext.prefix = { "${input.simpleName}" } + } + + withName: 'BCFTOOLS_VIEW' { + ext.prefix = { "${meta.prefix}_filter_${meta.scatterid}" } + } + + withName: 'ENSEMBLVEP_SNV' { + ext.prefix = { "${meta.prefix}_vep_${meta.scatterid}" } + ext.args = { [ + '--dir_plugins vep_cache/Plugins', + '--plugin LoFtool,LoFtool_scores.txt', + '--plugin pLI,pLI_values.txt', + '--plugin SpliceAI,snv=spliceai_21_scores_raw_snv_-v1.3-.vcf.gz,indel=spliceai_21_scores_raw_snv_-v1.3-.vcf.gz', + '--distance 5000', + '--buffer_size 20000', + '--format vcf --max_sv_size 248956422', + '--appris --biotype --cache --canonical --ccds --compress_output bgzip', + '--domains --exclude_predicted --force_overwrite', + '--hgvs --humdiv --no_progress --numbers', + '--merged --polyphen p --protein --offline --regulatory --sift p --symbol --tsl', + '--uniprot --vcf' + ].join(' ') } + } + + withName: 'BCFTOOLS_CONCAT' { + ext.args = { "--output-type z" } + } +} diff --git a/subworkflows/local/annotate_mobile_elements.nf b/subworkflows/local/annotate_mobile_elements/main.nf similarity index 58% rename from subworkflows/local/annotate_mobile_elements.nf rename to subworkflows/local/annotate_mobile_elements/main.nf index 2d08ca072..f237a07bb 100644 --- a/subworkflows/local/annotate_mobile_elements.nf +++ b/subworkflows/local/annotate_mobile_elements/main.nf @@ -2,36 +2,34 @@ // A subworkflow to annotate structural variants. // -include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_FILTER } from '../../modules/nf-core/bcftools/view/main' -include { ENSEMBLVEP_VEP as ENSEMBLVEP_ME } from '../../modules/nf-core/ensemblvep/vep/main' -include { PICARD_SORTVCF } from '../../modules/nf-core/picard/sortvcf/main' -include { SVDB_QUERY as SVDB_QUERY_DB } from '../../modules/nf-core/svdb/query/main' +include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_FILTER } from '../../../modules/nf-core/bcftools/view/main' +include { ENSEMBLVEP_VEP as ENSEMBLVEP_ME } from '../../../modules/nf-core/ensemblvep/vep/main' +include { PICARD_SORTVCF } from '../../../modules/nf-core/picard/sortvcf/main' +include { SVDB_QUERY as SVDB_QUERY_DB } from '../../../modules/nf-core/svdb/query/main' workflow ANNOTATE_MOBILE_ELEMENTS { take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_me_svdb_resources // channel: [mandatory] [ path(csv) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_me_svdb_resources // channel: [mandatory] [ path(csv) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] ch_vep_cache // channel: [mandatory] [ path(cache) ] - val_vep_genome // string: [mandatory] GRCh37 or GRCh38 + val_genome // string: [mandatory] GRCh37 or GRCh38 val_vep_cache_version // string: [mandatory] default: 107 ch_vep_extra_files // channel: [mandatory] [ path(files) ] main: - ch_versions = Channel.empty() - ch_svdb_dbs = Channel.empty() + ch_svdb_dbs = channel.empty() ch_me_svdb_resources - .splitCsv ( header:true ) - .multiMap { row -> - vcf_dbs: row.filename - in_frqs: row.in_freq_info_key - in_occs: row.in_allele_count_info_key - out_frqs: row.out_freq_info_key - out_occs: row.out_allele_count_info_key + .multiMap { file, in_freq_info_key, in_allele_count_info_key, out_freq_info_key, out_allele_count_info_key -> + vcf_dbs: file + in_frqs: in_freq_info_key + in_occs: in_allele_count_info_key + out_frqs: out_freq_info_key + out_occs: out_allele_count_info_key } .set { ch_svdb_dbs } @@ -56,7 +54,7 @@ workflow ANNOTATE_MOBILE_ELEMENTS { ENSEMBLVEP_ME( ch_vep_in, - val_vep_genome, + val_genome, "homo_sapiens", val_vep_cache_version, ch_vep_cache, @@ -72,12 +70,6 @@ workflow ANNOTATE_MOBILE_ELEMENTS { BCFTOOLS_VIEW_FILTER( ch_bcftools_filter_input, [], [], [] ) - ch_versions = ch_versions.mix( SVDB_QUERY_DB.out.versions ) - ch_versions = ch_versions.mix( PICARD_SORTVCF.out.versions ) - ch_versions = ch_versions.mix( ENSEMBLVEP_ME.out.versions ) - ch_versions = ch_versions.mix( BCFTOOLS_VIEW_FILTER.out.versions ) - emit: vcf_ann = BCFTOOLS_VIEW_FILTER.out.vcf // channel: [ val(meta), path(vcf) ] - versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/annotate_mobile_elements/tests/main.nf.test b/subworkflows/local/annotate_mobile_elements/tests/main.nf.test new file mode 100644 index 000000000..5aa86d4e3 --- /dev/null +++ b/subworkflows/local/annotate_mobile_elements/tests/main.nf.test @@ -0,0 +1,55 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_MOBILE_ELEMENTS" + script "subworkflows/local/annotate_mobile_elements/main.nf" + workflow "ANNOTATE_MOBILE_ELEMENTS" + + tag "subworkflows" + tag "annotate_mobile_elements" + + tag "bcftools/view" + tag "ensemblvep/vep" + tag "picard/sortvcf" + tag "svdb/query" + + config "./nextflow.config" + + test("ANNOTATE_MOBILE_ELEMENTS - GRCh37, stub") { + + options "-stub" + + when { + params { + bcftools_args = "--output-type z" + } + workflow { + """ + input[0] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[2] = channel.of([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + 'FRQ', + 'OCC', + 'swegen_FRQ', + 'swegen_OCC' + ]) + input[3] = channel.of([ + [id:'justhusky', single_end:false], + file(params.pipelines_testdata_base_path + 'reference/grch38_gnomad_reformated_-r3.1.1-.vcf.gz', checkIfExists: true) + ]) + input[4] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[5] = 'GRCh37' + input[6] = 107 + input[7] = channel.value([]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_mobile_elements/tests/main.nf.test.snap b/subworkflows/local/annotate_mobile_elements/tests/main.nf.test.snap new file mode 100644 index 000000000..febc7e5db --- /dev/null +++ b/subworkflows/local/annotate_mobile_elements/tests/main.nf.test.snap @@ -0,0 +1,31 @@ +{ + "ANNOTATE_MOBILE_ELEMENTS - GRCh37, stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky_filter.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "vcf_ann": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky_filter.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-05T00:16:05.837537418", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_mobile_elements/tests/nextflow.config b/subworkflows/local/annotate_mobile_elements/tests/nextflow.config new file mode 100644 index 000000000..13ccf42dc --- /dev/null +++ b/subworkflows/local/annotate_mobile_elements/tests/nextflow.config @@ -0,0 +1,20 @@ +process { + + withName: 'SVDB_QUERY_DB' { + ext.prefix = { "${meta.id}_me_svdb" } + } + + withName: 'PICARD_SORTVCF' { + ext.prefix = { "${meta.id}_sortvcf" } + } + + withName: 'ENSEMBLVEP_ME' { + ext.prefix = { "${meta.id}_svdbquery_vep" } + } + + withName: 'BCFTOOLS_VIEW_FILTER' { + ext.args = { params.bcftools_args } + ext.prefix = { "${meta.id}_filter" } + } + +} diff --git a/subworkflows/local/annotate_mt_snvs.nf b/subworkflows/local/annotate_mt_snvs.nf deleted file mode 100644 index b1fba8b09..000000000 --- a/subworkflows/local/annotate_mt_snvs.nf +++ /dev/null @@ -1,122 +0,0 @@ -// -// Annotate MT -// - -include { REPLACE_SPACES_IN_VCFINFO } from '../../modules/local/replace_spaces_in_vcfinfo' -include { TABIX_TABIX as TABIX_TABIX_VEP_MT } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_BGZIPTABIX as ZIP_TABIX_HMTNOTE_MT } from '../../modules/nf-core/tabix/bgziptabix/main' -include { ENSEMBLVEP_VEP as ENSEMBLVEP_MT } from '../../modules/nf-core/ensemblvep/vep/main' -include { HAPLOGREP3_CLASSIFY as HAPLOGREP3_CLASSIFY_MT } from '../../modules/nf-core/haplogrep3/classify/main' -include { VCFANNO as VCFANNO_MT } from '../../modules/nf-core/vcfanno/main' -include { ANNOTATE_CADD } from './annotate_cadd' -include { TABIX_BGZIPTABIX as ZIP_TABIX_VCFANNO_MT } from '../../modules/nf-core/tabix/bgziptabix/main' -include { HMTNOTE_ANNOTATE } from '../../modules/nf-core/hmtnote/annotate/main' - -workflow ANNOTATE_MT_SNVS { - take: - ch_mt_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_mt_tbi // channel: [mandatory] [ val(meta), path(tbi) ] - ch_cadd_header // channel: [mandatory] [ path(txt) ] - ch_cadd_resources // channel: [mandatory] [ path(annotation) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_vcfanno_extra // channel: [mandatory] [ [path(vcf),path(index)] ] - ch_vcfanno_lua // channel: [mandatory] [ path(lua) ] - ch_vcfanno_resources // channel: [mandatory] [ [path(vcf1),path(index1),...,path(vcfn),path(indexn)] ] - ch_vcfanno_toml // channel: [mandatory] [ path(toml) ] - val_vep_genome // string: [mandatory] GRCh37 or GRCh38 - val_vep_cache_version // string: [mandatory] 107 - ch_vep_cache // channel: [mandatory] [ path(cache) ] - ch_vep_extra_files // channel: [mandatory] [ path(files) ] - - main: - ch_versions = Channel.empty() - ch_haplog = Channel.empty() - - // add prefix to meta - ch_mt_vcf - .map { it -> - return [it[0]+ [prefix: it[1].simpleName + "_hmtnote"], it[1]] - } - .set { ch_hmtnote_in } - - // HMTNOTE ANNOTATE - HMTNOTE_ANNOTATE(ch_hmtnote_in) - REPLACE_SPACES_IN_VCFINFO(HMTNOTE_ANNOTATE.out.vcf) - ZIP_TABIX_HMTNOTE_MT(REPLACE_SPACES_IN_VCFINFO.out.vcf) - - // Vcfanno - ZIP_TABIX_HMTNOTE_MT.out.gz_tbi - .combine(ch_vcfanno_extra) - .map { meta, vcf, tbi, resources -> return [meta + [prefix: meta.prefix + "_vcfanno"], vcf, tbi, resources]} - .set { ch_in_vcfanno } - - VCFANNO_MT(ch_in_vcfanno, ch_vcfanno_toml, ch_vcfanno_lua, ch_vcfanno_resources) - ZIP_TABIX_VCFANNO_MT(VCFANNO_MT.out.vcf) - - ch_vcfanno_vcf = ZIP_TABIX_VCFANNO_MT.out.gz_tbi.map{meta, vcf, tbi -> return [meta, vcf]} - ch_vcfanno_tbi = ZIP_TABIX_VCFANNO_MT.out.gz_tbi.map{meta, vcf, tbi -> return [meta, tbi]} - - // Annotating with CADD - if (params.cadd_resources != null) { - ANNOTATE_CADD ( - ZIP_TABIX_VCFANNO_MT.out.gz_tbi, - ch_cadd_header, - ch_cadd_resources - ) - ch_cadd_vcf = ANNOTATE_CADD.out.vcf - ch_versions = ch_versions.mix(ANNOTATE_CADD.out.versions) - } else { - ch_cadd_vcf = Channel.empty() - } - - // Pick input for vep - ch_vcfanno_vcf - .join(ch_cadd_vcf, remainder: true) // If CADD is not run then the third element in this channel will be `null` - .branch { it -> // If CADD is run, then "it" will be [[meta],selvar.vcf,cadd.vcf], else [[meta],selvar.vcf,null] - merged: it[2].equals(null) - return [it[0]+ [prefix: it[0].prefix + "_vep"], it[1]] - cadd: !(it[2].equals(null)) - return [it[0] + [prefix: it[0].prefix + "_cadd_vep"], it[2]] - } - .set { ch_for_mix } - - ch_for_mix.merged.mix(ch_for_mix.cadd) - .tap { ch_haplogrep_in } - .map { meta, vcf -> return [meta, vcf, []] } - .set { ch_vep_in } - - // Annotating with ensembl Vep - ENSEMBLVEP_MT( - ch_vep_in, - val_vep_genome, - "homo_sapiens", - val_vep_cache_version, - ch_vep_cache, - ch_genome_fasta, - ch_vep_extra_files - ) - - TABIX_TABIX_VEP_MT(ENSEMBLVEP_MT.out.vcf) - - // Running haplogrep3 - if (!(params.skip_tools && params.skip_tools.split(',').contains('haplogrep3'))) { - HAPLOGREP3_CLASSIFY_MT(ch_haplogrep_in) - ch_haplog = HAPLOGREP3_CLASSIFY_MT.out.txt - ch_versions = ch_versions.mix(HAPLOGREP3_CLASSIFY_MT.out.versions) - } - - ch_versions = ch_versions.mix(ENSEMBLVEP_MT.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX_VEP_MT.out.versions) - ch_versions = ch_versions.mix(VCFANNO_MT.out.versions) - ch_versions = ch_versions.mix(HMTNOTE_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(ZIP_TABIX_VCFANNO_MT.out.versions) - ch_versions = ch_versions.mix(ZIP_TABIX_HMTNOTE_MT.out.versions) - ch_versions = ch_versions.mix(REPLACE_SPACES_IN_VCFINFO.out.versions) - - emit: - haplog = ch_haplog // channel: [ val(meta), path(txt) ] - vcf_ann = ENSEMBLVEP_MT.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = TABIX_TABIX_VEP_MT.out.tbi // channel: [ val(meta), path(tbi) ] - report = ENSEMBLVEP_MT.out.report // channel: [ path(html) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/annotate_mt_snvs/main.nf b/subworkflows/local/annotate_mt_snvs/main.nf new file mode 100644 index 000000000..54da99c6c --- /dev/null +++ b/subworkflows/local/annotate_mt_snvs/main.nf @@ -0,0 +1,101 @@ +// +// Annotate MT +// + + +include { ANNOTATE_CADD } from '../annotate_cadd' +include { BCFTOOLS_PLUGINSETGT } from '../../../modules/nf-core/bcftools/pluginsetgt' +include { ENSEMBLVEP_VEP as ENSEMBLVEP_MT } from '../../../modules/nf-core/ensemblvep/vep/main' +include { TABIX_TABIX as TABIX_TABIX_VEP_MT } from '../../../modules/nf-core/tabix/tabix/main' +include { VCFANNO as VCFANNO_MT } from '../../../modules/nf-core/vcfanno/main' + +workflow ANNOTATE_MT_SNVS { + take: + ch_cadd_header // channel: [mandatory] [ path(txt) ] + ch_cadd_prescored // channel: [optional] [ val(meta), path(prescored) ] + ch_cadd_resources // channel: [mandatory] [ val(meta), path(annotation) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_mt_vcf_tbi // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] + ch_vcfanno_extra // channel: [mandatory] [ [path(vcf),path(index)] ] + ch_vcfanno_lua // channel: [mandatory] [ path(lua) ] + ch_vcfanno_resources // channel: [mandatory] [ [path(vcf1),path(index1),...,path(vcfn),path(indexn)] ] + ch_vcfanno_toml // channel: [mandatory] [ path(toml) ] + ch_vep_cache // channel: [mandatory] [ path(cache) ] + ch_vep_extra_files // channel: [mandatory] [ path(files) ] + val_cadd_resources // string: path to cadd resources file + val_genome // string: GRCh37 or GRCh38 + val_homoplasmy_af_threshold // float: 0-1 + val_vep_cache_version // string: vep version ex: 107 + + main: + // Vcfanno + ch_mt_vcf_tbi + .combine(ch_vcfanno_extra) + .map { meta, vcf, tbi, resources -> return [meta + [prefix: vcf.simpleName + "_vcfanno"], vcf, tbi, resources]} + .set { ch_in_vcfanno } + + VCFANNO_MT(ch_in_vcfanno, ch_vcfanno_toml, ch_vcfanno_lua, ch_vcfanno_resources) + + // Annotating with CADD + if (!val_cadd_resources.equals(null)) { + ANNOTATE_CADD ( + ch_cadd_resources, + ch_cadd_prescored, + ch_fai, + ch_cadd_header, + VCFANNO_MT.out.vcf.join(VCFANNO_MT.out.tbi, failOnMismatch:true, failOnDuplicate:true), + val_genome + ) + ch_cadd_vcf = ANNOTATE_CADD.out.vcf + } else { + ch_cadd_vcf = channel.empty() + } + + VCFANNO_MT.out.vcf + .join(ch_cadd_vcf, remainder: true) + .branch { meta, vcfanno, cadd -> + vcfanno: cadd.equals(null) + return [meta+ [prefix: meta.prefix + "_vep"], vcfanno] + cadd: !(cadd.equals(null)) + return [meta + [prefix: meta.prefix + "_cadd_vep"], cadd] + } + .set { ch_annotated_vcfs } + + ch_annotated_vcfs.vcfanno.mix(ch_annotated_vcfs.cadd) + .map { meta, vcf -> return [meta, vcf, []] } + .set { ch_vep_in } + + // Annotating with ensembl Vep + ENSEMBLVEP_MT( + ch_vep_in, + val_genome, + "homo_sapiens", + val_vep_cache_version, + ch_vep_cache, + ch_genome_fasta, + ch_vep_extra_files + ) + + ch_vcf = ENSEMBLVEP_MT.out.vcf + ch_tbi = ENSEMBLVEP_MT.out.tbi + + if (val_homoplasmy_af_threshold<1) { + BCFTOOLS_PLUGINSETGT ( + ENSEMBLVEP_MT.out.vcf.map { meta, vcf -> return [meta, vcf, []] }, + channel.value('q'), + channel.value("c:'1/1'"), + [], + [] + ) + ch_vcf = BCFTOOLS_PLUGINSETGT.out.vcf + ch_tbi = BCFTOOLS_PLUGINSETGT.out.tbi + } + + emit: + ensemblvep_mt_tbi = ENSEMBLVEP_MT.out.tbi // channel: [ val(meta), path(tbi) ] + ensemblvep_mt_vcf = ENSEMBLVEP_MT.out.vcf // channel: [ val(meta), path(vcf) ] + report = ENSEMBLVEP_MT.out.report // channel: [ val(meta), val(tool), val(toolver), path(html) ] + tbi = ch_tbi // channel: [ val(meta), path(tbi) ] + vcf_ann = ch_vcf // channel: [ val(meta), path(vcf) ] +} diff --git a/subworkflows/local/annotate_mt_snvs/tests/main.nf.test b/subworkflows/local/annotate_mt_snvs/tests/main.nf.test new file mode 100644 index 000000000..8ce795e77 --- /dev/null +++ b/subworkflows/local/annotate_mt_snvs/tests/main.nf.test @@ -0,0 +1,132 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_MT_SNVS" + script "subworkflows/local/annotate_mt_snvs/main.nf" + workflow "ANNOTATE_MT_SNVS" + + tag "subworkflows" + tag "annotate_mt_snvs" + tag "annotate_cadd" + + tag "bcftools/pluginsetgt" + tag "tabix/tabix" + tag "ensemblvep/vep" + tag "haplogrep3/classify" + tag "vcfanno" + tag "tabix/bgziptabix" + + config "./nextflow.config" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = channel.of([ + [id:'vep_cache'], + file('https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/vep_cache_and_plugins.tar.gz', checkIfExists: true) + ]) + """ + } + } + } + + test("ANNOTATE_MT_SNVS - GRCh37") { + when { + params { + homoplasmy_af_threshold = 0.95 + } + workflow { + """ + input[0] = channel.of([[id:'resources'], file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)]).collect() + input[1] = channel.value([[:], []]) + input[2] = Channel.from(env("PWD")).map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[3] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[5] = channel.of([ + [id:'justhusky', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'reference/vcfanno_gnomad_mt.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/vcfanno_gnomad_mt.vcf.gz.tbi', checkIfExists: true), + ]) + input[6] = channel.value([[]]) + input[7] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_functions.lua', checkIfExists: true)).collect() + input[8] = [ + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz.tbi', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/vcfanno_cadd.tsv.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/vcfanno_cadd.tsv.gz.tbi', checkIfExists: true) + ] + input[9] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_config.toml', checkIfExists: true)).collect() + input[10] = UNTAR.out.untar.map { _meta, untar -> untar }.collect() + input[11] = [ + file(params.pipelines_testdata_base_path + 'reference/pLI_values.txt', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/LoFtool_scores.txt', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/spliceai_21_scores_raw_snv_-v1.3-.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/spliceai_21_scores_raw_snv_-v1.3-.vcf.gz.tbi', checkIfExists: true) + ] + input[12] = null + input[13] = 'GRCh37' + input[14] = 1.0 + input[15] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.vcf_ann }, + { assert workflow.out.tbi }, + { assert workflow.out.report }, + { assert workflow.out.ensemblvep_mt_vcf }, + { assert workflow.out.ensemblvep_mt_tbi }, + { assert snapshot( + "${file(workflow.out.vcf_ann[0][1]).name}:md5,${path(workflow.out.vcf_ann[0][1]).vcf.variantsMD5}", + path(workflow.out.vcf_ann[0][1]).vcf.summary + ).match() } + ) + } + } + + test("ANNOTATE_MT_SNVS - GRCh37, stub") { + + options "-stub" + + when { + params { + homoplasmy_af_threshold = 0.95 + } + workflow { + """ + input[0] = channel.of([[id:'resources'], file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/cadd_to_vcf_header_-1.0-.txt', checkIfExists: true)]).collect() + input[1] = channel.value([[:], []]) + input[2] = Channel.from(env("PWD")).map { dir -> [ [ id: 'cadd_resources' ], dir ] } + input[3] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[5] = channel.of([ + [id:'justhusky', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'reference/vcfanno_gnomad_mt.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/vcfanno_gnomad_mt.vcf.gz.tbi', checkIfExists: true), + ]) + input[6] = channel.value([[]]) + input[7] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_functions.lua', checkIfExists: true)).collect() + input[8] = channel.value(file(params.pipelines_testdata_base_path + 'reference/grch38_gnomad_reformated_-r3.1.1-.vcf.gz', checkIfExists: true)) + input[9] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vcfanno_config.toml', checkIfExists: true)).collect() + input[10] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[11] = channel.value([]) + input[12] = null + input[13] = 'GRCh37' + input[14] = 1.0 + input[15] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_mt_snvs/tests/main.nf.test.snap b/subworkflows/local/annotate_mt_snvs/tests/main.nf.test.snap new file mode 100644 index 000000000..77adf4738 --- /dev/null +++ b/subworkflows/local/annotate_mt_snvs/tests/main.nf.test.snap @@ -0,0 +1,128 @@ +{ + "ANNOTATE_MT_SNVS - GRCh37": { + "content": [ + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz:md5,35b30b356d34416a56b262834cbeaf32", + "VcfFile [chromosomes=[MT], sampleCount=0, variantCount=18164, phased=true, phasedAutodetect=true]" + ], + "timestamp": "2026-06-26T16:50:08.067805575", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_MT_SNVS - GRCh37, stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "2": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "ANNOTATE_MT_SNVS:ENSEMBLVEP_MT", + "ensemblvep", + "vcfanno_gnomad_mt_vcfanno_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "ensemblvep_mt_tbi": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ensemblvep_mt_vcf": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "report": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "ANNOTATE_MT_SNVS:ENSEMBLVEP_MT", + "ensemblvep", + "vcfanno_gnomad_mt_vcfanno_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf_ann": [ + [ + { + "id": "justhusky", + "case_id": "justhusky", + "prefix": "vcfanno_gnomad_mt_vcfanno_vep" + }, + "vcfanno_gnomad_mt_vcfanno_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-26T16:48:12.895866197", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_mt_snvs/tests/nextflow.config b/subworkflows/local/annotate_mt_snvs/tests/nextflow.config new file mode 100644 index 000000000..a31fa13b0 --- /dev/null +++ b/subworkflows/local/annotate_mt_snvs/tests/nextflow.config @@ -0,0 +1,34 @@ +process { + + withName: 'VCFANNO_MT' { + ext.prefix = { "${meta.prefix}" } + } + + withName: 'ZIP_TABIX_VCFANNO_MT' { + ext.prefix = { "${meta.prefix}" } + } + + withName: 'ENSEMBLVEP_MT' { + ext.args = { [ + '--dir_plugins vep_cache/Plugins', + '--plugin LoFtool,LoFtool_scores.txt', + '--plugin pLI,pLI_values.txt', + '--plugin SpliceAI,snv=spliceai_21_scores_raw_snv_-v1.3-.vcf.gz,indel=spliceai_21_scores_raw_snv_-v1.3-.vcf.gz', + '--distance 0', + '--buffer_size 20000', + '--format vcf --max_sv_size 248956422', + '--appris --biotype --cache --canonical --ccds --compress_output bgzip', + '--domains --exclude_predicted --force_overwrite', + '--hgvs --humdiv --no_progress --numbers', + '--merged --polyphen p --protein --offline --regulatory --sift p --symbol --tsl --vcf', + '--uniprot' + ].join(' ') } + ext.prefix = { "${meta.prefix}" } + } + + withName: 'BCFTOOLS_PLUGINSETGT' { + ext.prefix = { "${meta.prefix}_mt_modifiedgt" } + ext.args = "--output-type z --write-index=tbi" + ext.args2 = { "-i 'FMT/AF>=${params.homoplasmy_af_threshold} && FMT/DP>=100'" } + } +} diff --git a/subworkflows/local/annotate_rhocallviz/main.nf b/subworkflows/local/annotate_rhocallviz/main.nf index 87d3b6bd6..3aafcd11d 100644 --- a/subworkflows/local/annotate_rhocallviz/main.nf +++ b/subworkflows/local/annotate_rhocallviz/main.nf @@ -2,55 +2,56 @@ // A subworkflow to plot binned zygosity and RHO-regions. // -include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_RHOCALL } from '../../../modules/nf-core/bcftools/view/main' -include { TABIX_TABIX } from '../../../modules/nf-core/tabix/tabix/main' include { BCFTOOLS_ROH } from '../../../modules/nf-core/bcftools/roh/main' +include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_RHOCALL } from '../../../modules/nf-core/bcftools/view/main' include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_UNCOMPRESS } from '../../../modules/nf-core/bcftools/view/main' +include { CHROMOGRAPH as CHROMOGRAPH_AUTOZYG } from '../../../modules/nf-core/chromograph/main' include { RHOCALL_VIZ } from '../../../modules/nf-core/rhocall/viz/main' include { UCSC_WIGTOBIGWIG } from '../../../modules/nf-core/ucsc/wigtobigwig/main' -include { CHROMOGRAPH as CHROMOGRAPH_AUTOZYG } from '../../../modules/nf-core/chromograph/main' workflow ANNOTATE_RHOCALLVIZ { take: - ch_vcf_tbi // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] - ch_samples // channel: [mandatory] [ val(sample_meta) ] ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] + ch_samples // channel: [mandatory] [ val(sample_meta) ] + ch_vcf_tbi // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] main: - ch_versions = Channel.empty() - ch_vcf_tbi .combine(ch_samples) - .map {meta, vcf, tbi, meta2 -> return [meta2,vcf,tbi]} + .map {_meta, vcf, tbi, meta2 -> return [meta2,vcf,tbi]} .set { ch_rhocall_viz } BCFTOOLS_VIEW_RHOCALL(ch_rhocall_viz, [],[],[]) - TABIX_TABIX(BCFTOOLS_VIEW_RHOCALL.out.vcf) - BCFTOOLS_VIEW_RHOCALL.out.vcf - .join(TABIX_TABIX.out.tbi) + .join(BCFTOOLS_VIEW_RHOCALL.out.tbi) .set {ch_roh_in } BCFTOOLS_ROH(ch_roh_in, [[],[]], [], [], [], []) BCFTOOLS_VIEW_UNCOMPRESS(ch_roh_in,[],[],[]) - RHOCALL_VIZ(BCFTOOLS_VIEW_UNCOMPRESS.out.vcf, BCFTOOLS_ROH.out.roh) + BCFTOOLS_VIEW_UNCOMPRESS.out.vcf + .join(BCFTOOLS_ROH.out.roh) + .multiMap { meta, vcf, roh -> + vcf: [meta, vcf] + roh: [meta, roh] + } + .set { ch_rhocall_viz_input } + + RHOCALL_VIZ( + ch_rhocall_viz_input.vcf, + ch_rhocall_viz_input.roh, + ) CHROMOGRAPH_AUTOZYG(RHOCALL_VIZ.out.bed, [[],[]], [[],[]], [[],[]], [[],[]], [[],[]], [[],[]]) UCSC_WIGTOBIGWIG(RHOCALL_VIZ.out.wig, ch_genome_chrsizes) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW_RHOCALL.out.versions.first()) - ch_versions = ch_versions.mix(CHROMOGRAPH_AUTOZYG.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_TABIX.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_ROH.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW_UNCOMPRESS.out.versions.first()) - ch_versions = ch_versions.mix(RHOCALL_VIZ.out.versions.first()) - ch_versions = ch_versions.mix(UCSC_WIGTOBIGWIG.out.versions.first()) - emit: - versions = ch_versions // channel: [ path(versions.yml) ] + chromograph_autozyg_plots = CHROMOGRAPH_AUTOZYG.out.plots // channel: [ val(meta), path(png) ] + rhocall_viz_bed = RHOCALL_VIZ.out.bed // channel: [ val(meta), path(bed) ] + rhocall_viz_wig = RHOCALL_VIZ.out.wig // channel: [ val(meta), path(wig) ] + ucsc_wigtobigwig_bw = UCSC_WIGTOBIGWIG.out.bw // channel: [ val(meta), path(bw) ] } diff --git a/subworkflows/local/annotate_rhocallviz/tests/main.nf.test b/subworkflows/local/annotate_rhocallviz/tests/main.nf.test new file mode 100644 index 000000000..7da8f7204 --- /dev/null +++ b/subworkflows/local/annotate_rhocallviz/tests/main.nf.test @@ -0,0 +1,60 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_RHOCALLVIZ" + script "subworkflows/local/annotate_rhocallviz/main.nf" + workflow "ANNOTATE_RHOCALLVIZ" + + tag "subworkflows" + tag "annotate_rhocallviz" + + tag "bcftools/view" + tag "bcftools/roh" + tag "rhocall/viz" + tag "ucsc/wigtobigwig" + tag "chromograph" + + config "./nextflow.config" + + test("ANNOTATE_RHOCALLVIZ - stub") { + + options "-stub" + + when { + params { + bcftools_view_rhocall = "--output-type z --write-index=tbi --min-ac 1 --samples test_sample" + bcftools_roh = "--AF-tag GNOMADAF --skip-indels" + bcftools_view_uncompressed = "--output-type v" + rhocall_viz = "--aftag GNOMADAF --wig" + chromograph_autozyg = "--euploid" + ucsc_wigtobigwig = "-clip" + } + workflow { + """ + input[0] = channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.sizes', checkIfExists: true)).collect() + input[1] = channel.of([id:'test_sample', sample:'test_sample', sex:1, phenotype:2, paternal:0, maternal:0, case_id:'test_case']) + input[2] = channel.of([ + [id:'test_case', sample:'test_sample'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.rhocall_viz_bed + .collect { meta, bedfile -> [file(bedfile)] }, + workflow.out.rhocall_viz_wig + .collect { meta, wigfile -> [file(wigfile)] }, + workflow.out.ucsc_wigtobigwig_bw + .collect { meta, bwfile -> [file(bwfile)] }, + workflow.out.chromograph_autozyg_plots + .collect { meta, plots -> [plots.collect { png -> file(png) }.sort()] } + ).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_rhocallviz/tests/main.nf.test.snap b/subworkflows/local/annotate_rhocallviz/tests/main.nf.test.snap new file mode 100644 index 000000000..e6c4f4c5f --- /dev/null +++ b/subworkflows/local/annotate_rhocallviz/tests/main.nf.test.snap @@ -0,0 +1,57 @@ +{ + "ANNOTATE_RHOCALLVIZ - stub": { + "content": [ + [ + [ + "test_sample_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + "test_sample_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + "test_sample_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + [ + "test_sample_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + "timestamp": "2026-05-26T11:46:37.479912106", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_rhocallviz/tests/nextflow.config b/subworkflows/local/annotate_rhocallviz/tests/nextflow.config new file mode 100644 index 000000000..3ccb91b06 --- /dev/null +++ b/subworkflows/local/annotate_rhocallviz/tests/nextflow.config @@ -0,0 +1,32 @@ +process { + + withName: 'BCFTOOLS_VIEW_RHOCALL' { + ext.prefix = { "${meta.sample}" } + ext.args = { params.bcftools_view_rhocall } + } + + withName: 'BCFTOOLS_ROH' { + ext.prefix = { "${meta.sample}" } + ext.args = { params.bcftools_roh } + } + + withName: 'BCFTOOLS_VIEW_UNCOMPRESS' { + ext.prefix = { "${meta.sample}" } + ext.args = { params.bcftools_view_uncompressed } + } + + withName: 'RHOCALL_VIZ' { + ext.prefix = { "${meta.sample}_rhocallviz" } + ext.args = { params.rhocall_viz } + } + + withName: 'CHROMOGRAPH_AUTOZYG' { + ext.prefix = { "${autozyg.simpleName}_autozyg_chromograph" } + ext.args = { params.chromograph_autozyg } + } + + withName: 'UCSC_WIGTOBIGWIG' { + ext.prefix = { "${meta.sample}_rhocallviz" } + ext.args = { params.ucsc_wigtobigwig } + } +} diff --git a/subworkflows/local/annotate_structural_variants.nf b/subworkflows/local/annotate_structural_variants.nf deleted file mode 100644 index db73f5a19..000000000 --- a/subworkflows/local/annotate_structural_variants.nf +++ /dev/null @@ -1,130 +0,0 @@ -// -// A subworkflow to annotate structural variants. -// - -include { SVDB_QUERY as SVDB_QUERY_DB } from '../../modules/nf-core/svdb/query/main' -include { SVDB_QUERY as SVDB_QUERY_BEDPE } from '../../modules/nf-core/svdb/query/main' -include { PICARD_SORTVCF } from '../../modules/nf-core/picard/sortvcf/main' -include { BCFTOOLS_VIEW } from '../../modules/nf-core/bcftools/view/main' -include { ENSEMBLVEP_VEP as ENSEMBLVEP_SV } from '../../modules/nf-core/ensemblvep/vep/main' -include { TABIX_TABIX as TABIX_VEP } from '../../modules/nf-core/tabix/tabix/main' - -workflow ANNOTATE_STRUCTURAL_VARIANTS { - - take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_sv_dbs // channel: [mandatory] [ val(csv) ] - ch_sv_bedpedbs // channel: [mandatory] [ val(csv) ] - val_vep_genome // string: [mandatory] GRCh37 or GRCh38 - val_vep_cache_version // string: [mandatory] default: 107 - ch_vep_cache // channel: [mandatory] [ path(cache) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_vep_extra_files // channel: [mandatory] [ path(files) ] - - main: - ch_versions = Channel.empty() - ch_svdb_dbs = Channel.empty() - ch_svdb_bedpedbs = Channel.empty() - - ch_sv_dbs - .splitCsv ( header:true ) - .multiMap { row -> - vcf_dbs: row.filename - in_frqs: row.in_freq_info_key - in_occs: row.in_allele_count_info_key - out_frqs: row.out_freq_info_key - out_occs: row.out_allele_count_info_key - } - .set { ch_svdb_dbs } - - ch_sv_bedpedbs - .splitCsv ( header:true ) - .multiMap { row -> - bedpedbs: row.filename - in_frqs: row.in_freq_info_key - in_occs: row.in_allele_count_info_key - out_frqs: row.out_freq_info_key - out_occs: row.out_allele_count_info_key - } - .set { ch_svdb_bedpedbs } - - SVDB_QUERY_DB ( - ch_vcf, - ch_svdb_dbs.in_occs.toList(), - ch_svdb_dbs.in_frqs.toList(), - ch_svdb_dbs.out_occs.toList(), - ch_svdb_dbs.out_frqs.toList(), - ch_svdb_dbs.vcf_dbs.toList(), - [] - ) - - ch_vcf - .join(SVDB_QUERY_DB.out.vcf, remainder: true) - .branch { it -> - original_call: it[2].equals(null) - return [it[0], it[1]] - annotated_with_db: !(it[2].equals(null)) - return [it[0], it[2]] - } - .set { ch_for_mix_querydb } - - ch_querydb_out = ch_for_mix_querydb.original_call.mix(ch_for_mix_querydb.annotated_with_db) - - SVDB_QUERY_BEDPE ( - ch_querydb_out, - ch_svdb_bedpedbs.in_occs.toList(), - ch_svdb_bedpedbs.in_frqs.toList(), - ch_svdb_bedpedbs.out_occs.toList(), - ch_svdb_bedpedbs.out_frqs.toList(), - [], - ch_svdb_bedpedbs.bedpedbs.toList() - ) - - ch_querydb_out - .join(SVDB_QUERY_BEDPE.out.vcf, remainder: true) - .branch { it -> - querydb_out: it[2].equals(null) - return [it[0], it[1]] - annotated_with_bedped: !(it[2].equals(null)) - return [it[0], it[2]] - } - .set { ch_for_mix_querybedpedb } - - ch_querypedbed_out = ch_for_mix_querybedpedb.querydb_out.mix(ch_for_mix_querybedpedb.annotated_with_bedped) - - PICARD_SORTVCF(ch_querypedbed_out, ch_genome_fasta, ch_genome_dictionary) - - PICARD_SORTVCF.out.vcf - .map { meta, vcf -> return [meta,vcf,[]] } - .set { ch_sortvcf } - - BCFTOOLS_VIEW(ch_sortvcf, [], [], []) - .vcf - .map { meta, vcf -> return [meta, vcf, []]} - .set { ch_vep_in } - - ENSEMBLVEP_SV( - ch_vep_in, - val_vep_genome, - "homo_sapiens", - val_vep_cache_version, - ch_vep_cache, - ch_genome_fasta, - ch_vep_extra_files - ) - - TABIX_VEP (ENSEMBLVEP_SV.out.vcf) - - ch_versions = ch_versions.mix(SVDB_QUERY_DB.out.versions) - ch_versions = ch_versions.mix(SVDB_QUERY_BEDPE.out.versions) - ch_versions = ch_versions.mix(PICARD_SORTVCF.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions) - ch_versions = ch_versions.mix(ENSEMBLVEP_SV.out.versions) - ch_versions = ch_versions.mix(TABIX_VEP.out.versions) - - emit: - vcf_ann = ENSEMBLVEP_SV.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = TABIX_VEP.out.tbi // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/annotate_structural_variants/main.nf b/subworkflows/local/annotate_structural_variants/main.nf new file mode 100644 index 000000000..af846901a --- /dev/null +++ b/subworkflows/local/annotate_structural_variants/main.nf @@ -0,0 +1,105 @@ +// +// A subworkflow to annotate structural variants. +// + +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' +include { ENSEMBLVEP_VEP as ENSEMBLVEP_SV } from '../../../modules/nf-core/ensemblvep/vep/main' +include { PICARD_SORTVCF } from '../../../modules/nf-core/picard/sortvcf/main' +include { SVDB_QUERY as SVDB_QUERY_BEDPE } from '../../../modules/nf-core/svdb/query/main' +include { SVDB_QUERY as SVDB_QUERY_DB } from '../../../modules/nf-core/svdb/query/main' + +workflow ANNOTATE_STRUCTURAL_VARIANTS { + + take: + ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_svdb_bedpedbs // channel: [optional] + ch_svdb_dbs // channel: [optional] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + ch_vep_cache // channel: [mandatory] [ path(cache) ] + ch_vep_extra_files // channel: [mandatory] [ path(files) ] + val_svdb_query_bedpedbs // String: [optional] params.svdb_query_bedpedbs + val_svdb_query_dbs // String: [optional] params.svdb_query_dbs + val_genome // string: [mandatory] GRCh37 or GRCh38 + val_vep_cache_version // string: [mandatory] default: 107 + + main: + if (val_svdb_query_dbs) { + ch_svdb_dbs + .multiMap { file, in_freq_info_key, in_allele_count_info_key, out_freq_info_key, out_allele_count_info_key -> + vcf_dbs: file + in_frqs: in_freq_info_key + in_occs: in_allele_count_info_key + out_frqs: out_freq_info_key + out_occs: out_allele_count_info_key + } + .set { ch_svdb_dbs } + + SVDB_QUERY_DB ( + ch_vcf, + ch_svdb_dbs.in_occs.toList(), + ch_svdb_dbs.in_frqs.toList(), + ch_svdb_dbs.out_occs.toList(), + ch_svdb_dbs.out_frqs.toList(), + ch_svdb_dbs.vcf_dbs.toList(), + [] + ) + + ch_vcf = SVDB_QUERY_DB.out.vcf + } + + if (val_svdb_query_bedpedbs) { + ch_svdb_bedpedbs + .multiMap { file, in_freq_info_key, in_allele_count_info_key, out_freq_info_key, out_allele_count_info_key -> + bedpedbs: file + in_frqs: in_freq_info_key + in_occs: in_allele_count_info_key + out_frqs: out_freq_info_key + out_occs: out_allele_count_info_key + } + .set { ch_svdb_bedpedbs } + + SVDB_QUERY_BEDPE ( + ch_vcf, + ch_svdb_bedpedbs.in_occs.toList(), + ch_svdb_bedpedbs.in_frqs.toList(), + ch_svdb_bedpedbs.out_occs.toList(), + ch_svdb_bedpedbs.out_frqs.toList(), + [], + ch_svdb_bedpedbs.bedpedbs.toList() + ) + + ch_vcf = SVDB_QUERY_BEDPE.out.vcf + } + + PICARD_SORTVCF(ch_vcf, ch_genome_fasta, ch_genome_dictionary) + + PICARD_SORTVCF.out.vcf + .map { meta, vcf -> return [meta,vcf,[]] } + .set { ch_sortvcf } + + BCFTOOLS_VIEW(ch_sortvcf, [], [], []) + .vcf + .map { meta, vcf -> return [meta, vcf, []]} + .set { ch_vep_in } + + ENSEMBLVEP_SV( + ch_vep_in, + val_genome, + "homo_sapiens", + val_vep_cache_version, + ch_vep_cache, + ch_genome_fasta, + ch_vep_extra_files + ) + + ch_publish = ENSEMBLVEP_SV.out.vcf + .mix(ENSEMBLVEP_SV.out.tbi) + .mix(ENSEMBLVEP_SV.out.report.map{ meta, _process, _vep, html -> return [meta, html] }) + .map { meta, value -> ['annotate_sv/', [meta, value]] } + + emit: + publish = ch_publish // channel: [ val(destination), val(value) ] + tbi = ENSEMBLVEP_SV.out.tbi // channel: [ val(meta), path(tbi) ] + vcf_ann = ENSEMBLVEP_SV.out.vcf // channel: [ val(meta), path(vcf) ] +} diff --git a/subworkflows/local/annotate_structural_variants/tests/main.nf.test b/subworkflows/local/annotate_structural_variants/tests/main.nf.test new file mode 100644 index 000000000..279486d02 --- /dev/null +++ b/subworkflows/local/annotate_structural_variants/tests/main.nf.test @@ -0,0 +1,114 @@ +nextflow_workflow { + + name "Test Workflow ANNOTATE_STRUCTURAL_VARIANTS" + script "subworkflows/local/annotate_structural_variants/main.nf" + workflow "ANNOTATE_STRUCTURAL_VARIANTS" + + tag "subworkflows" + tag "annotate_structural_variants" + + tag "svdb/query" + tag "picard/sortvcf" + tag "bcftools/view" + tag "ensemblvep/vep" + + config "./nextflow.config" + + test("ANNOTATE_STRUCTURAL_VARIANTS - no SVDB queries, stub") { + + options "-stub" + + when { + params { + bcftools_view = "--output-type z" + vep = "--compress_output bgzip --format vcf --vcf" + } + workflow { + """ + input[0] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[2] = channel.empty() + input[3] = channel.empty() + input[4] = channel.of([ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/sv_query.vcf.gz', checkIfExists: true) + ]) + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[6] = channel.value([]) + input[7] = null + input[8] = null + input[9] = 'GRCh37' + input[10] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List) { + sortKey = sortKey[-1] + } + sortKey.toString().split(':md5,')[0].tokenize('/')[-1] + } + [name, sorted_channel] + }.sort { it[0] } // Sort by channel name + ).match() } + ) + } + } + + test("ANNOTATE_STRUCTURAL_VARIANTS - with SVDB_QUERY_DB, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[2] = channel.empty() + input[3] = channel.of([ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/gnomAD.r2.1.1-sv.vcf.gz', checkIfExists: true), + 'AC', + 'AF', + 'gnomad_svAC', + 'gnomad_svAF' + ]) + input[4] = channel.of([ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/sv_query.vcf.gz', checkIfExists: true) + ]) + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz', checkIfExists: true)).collect() + input[6] = channel.value([]) + input[7] = null + input[8] = 'gnomAD.r2.1.1-sv.vcf.gz' + input[9] = 'GRCh37' + input[10] = 107 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List) { + sortKey = sortKey[-1] + } + sortKey.toString().split(':md5,')[0].tokenize('/')[-1] + } + [name, sorted_channel] + }.sort { it[0] } // Sort by channel name + ).match() } + ) + } + } +} diff --git a/subworkflows/local/annotate_structural_variants/tests/main.nf.test.snap b/subworkflows/local/annotate_structural_variants/tests/main.nf.test.snap new file mode 100644 index 000000000..3915529a0 --- /dev/null +++ b/subworkflows/local/annotate_structural_variants/tests/main.nf.test.snap @@ -0,0 +1,240 @@ +{ + "ANNOTATE_STRUCTURAL_VARIANTS - no SVDB queries, stub": { + "content": [ + [ + [ + "0", + [ + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "1", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "2", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "publish", + [ + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "tbi", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "vcf_ann", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ] + ] + ], + "timestamp": "2026-03-17T22:56:56.445250387", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "ANNOTATE_STRUCTURAL_VARIANTS - with SVDB_QUERY_DB, stub": { + "content": [ + [ + [ + "0", + [ + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "1", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "2", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "publish", + [ + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + "annotate_sv/", + [ + { + "id": "test" + }, + "test_svdbquery_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "tbi", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "vcf_ann", + [ + [ + { + "id": "test" + }, + "test_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ] + ] + ], + "timestamp": "2026-03-17T22:57:23.293047427", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/annotate_structural_variants/tests/nextflow.config b/subworkflows/local/annotate_structural_variants/tests/nextflow.config new file mode 100644 index 000000000..7ff620bd0 --- /dev/null +++ b/subworkflows/local/annotate_structural_variants/tests/nextflow.config @@ -0,0 +1,24 @@ +process { + + withName: 'SVDB_QUERY_DB' { + ext.prefix = { "${meta.id}_vcfdb" } + } + + withName: 'SVDB_QUERY_BEDPE' { + ext.prefix = { "${meta.id}_bedpedb" } + } + + withName: 'PICARD_SORTVCF' { + ext.prefix = { "${meta.id}_svdbquery" } + } + + withName: 'BCFTOOLS_VIEW' { + ext.prefix = { "${meta.id}_view" } + ext.args = { params.bcftools_view } + } + + withName: 'ENSEMBLVEP_SV' { + ext.prefix = { "${meta.id}_svdbquery_vep" } + ext.args = { params.vep } + } +} diff --git a/subworkflows/local/call_mobile_elements.nf b/subworkflows/local/call_mobile_elements/main.nf similarity index 57% rename from subworkflows/local/call_mobile_elements.nf rename to subworkflows/local/call_mobile_elements/main.nf index 9def4ccd3..7756770a9 100644 --- a/subworkflows/local/call_mobile_elements.nf +++ b/subworkflows/local/call_mobile_elements/main.nf @@ -2,34 +2,30 @@ // A subworkflow to call mobile elements in the genome // -include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_ME } from '../../modules/nf-core/bcftools/reheader/main' -include { BCFTOOLS_CONCAT as BCFTOOLS_CONCAT_ME } from '../../modules/nf-core/bcftools/concat/main' -include { BCFTOOLS_SORT as BCFTOOLS_SORT_ME } from '../../modules/nf-core/bcftools/sort/main' -include { RETROSEQ_CALL as RETROSEQ_CALL } from '../../modules/local/retroseq/call/main' -include { RETROSEQ_DISCOVER as RETROSEQ_DISCOVER } from '../../modules/local/retroseq/discover/main' -include { SAMTOOLS_INDEX as ME_INDEX_SPLIT_ALIGNMENT } from '../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_VIEW as ME_SPLIT_ALIGNMENT } from '../../modules/nf-core/samtools/view/main' -include { TABIX_TABIX as TABIX_ME } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_ME_SPLIT } from '../../modules/nf-core/tabix/tabix/main' -include { SVDB_MERGE as SVDB_MERGE_ME } from '../../modules/nf-core/svdb/merge/main' +include { BCFTOOLS_CONCAT as BCFTOOLS_CONCAT_ME } from '../../../modules/nf-core/bcftools/concat/main' +include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_ME } from '../../../modules/nf-core/bcftools/reheader/main' +include { BCFTOOLS_SORT as BCFTOOLS_SORT_ME } from '../../../modules/nf-core/bcftools/sort/main' +include { RETROSEQ_CALL as RETROSEQ_CALL } from '../../../modules/local/retroseq/call/main' +include { RETROSEQ_DISCOVER as RETROSEQ_DISCOVER } from '../../../modules/local/retroseq/discover/main' +include { SAMTOOLS_VIEW as ME_SPLIT_ALIGNMENT } from '../../../modules/nf-core/samtools/view/main' +include { SVDB_MERGE as SVDB_MERGE_ME } from '../../../modules/nf-core/svdb/merge/main' +include { TABIX_TABIX as TABIX_ME } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_ME_SPLIT } from '../../../modules/nf-core/tabix/tabix/main' workflow CALL_MOBILE_ELEMENTS { take: + ch_case_info // channel: [mandatory] [ val(case_info) ] ch_genome_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_me_references // channel: [mandatory] [path(tsv)] - ch_case_info // channel: [mandatory] [ val(case_info) ] - val_genome_build // string: [mandatory] GRCh37 or GRCh38 main: - ch_versions = Channel.empty() - // Building chromosome channels based on fasta index ch_genome_fai - .splitCsv( sep: "\t", elem: 1, limit: 25 ) - .map { meta, fai -> [ fai.first() ] } + .splitCsv( sep: "\t", elem: 1, limit: 24 ) + .map { _meta, fai -> [ fai.first() ] } .collect() .map { chr -> [ chr, chr.size() ] } .transpose() @@ -44,11 +40,10 @@ workflow CALL_MOBILE_ELEMENTS { .set { ch_genome_bam_bai_interval } // Split bam file on chromosome and index - ME_SPLIT_ALIGNMENT ( ch_genome_bam_bai_interval, [[:], []], [] ) - ME_INDEX_SPLIT_ALIGNMENT ( ME_SPLIT_ALIGNMENT.out.bam ) + ME_SPLIT_ALIGNMENT ( ch_genome_bam_bai_interval, [[:], [], []], [], 'bai' ) ME_SPLIT_ALIGNMENT.out.bam - .join( ME_INDEX_SPLIT_ALIGNMENT.out.bai, failOnMismatch: true, failOnDuplicate: true ) + .join( ME_SPLIT_ALIGNMENT.out.bai, failOnMismatch: true, failOnDuplicate: true ) .set { ch_retroseq_input } ch_me_references @@ -94,13 +89,13 @@ workflow CALL_MOBILE_ELEMENTS { } .set { ch_vcfs } - TABIX_ME_SPLIT.out.tbi - .map { meta, vcf -> - [ groupKey( meta - meta.subMap('interval'), meta.nr_of_intervals ), vcf ] + TABIX_ME_SPLIT.out.index + .map { meta, tbi -> + [ groupKey( meta - meta.subMap('interval'), meta.nr_of_intervals ), tbi ] } .groupTuple() - .map { meta, vcf -> - [ meta - meta.subMap('nr_of_intervals'), vcf ] + .map { meta, tbi -> + [ meta - meta.subMap('nr_of_intervals'), tbi ] } .set { ch_tbis } @@ -112,7 +107,7 @@ workflow CALL_MOBILE_ELEMENTS { // Merge sample vcfs to a case vcf BCFTOOLS_CONCAT_ME.out.vcf - .collect{it[1]} + .collect{_meta, vcf -> vcf} .toList() .collect() .set { ch_vcf_list } @@ -124,19 +119,7 @@ workflow CALL_MOBILE_ELEMENTS { SVDB_MERGE_ME ( ch_svdb_merge_me_input, [], true ) TABIX_ME ( SVDB_MERGE_ME.out.vcf ) - ch_versions = ch_versions.mix(ME_SPLIT_ALIGNMENT.out.versions.first()) - ch_versions = ch_versions.mix(ME_INDEX_SPLIT_ALIGNMENT.out.versions.first()) - ch_versions = ch_versions.mix(RETROSEQ_DISCOVER.out.versions.first()) - ch_versions = ch_versions.mix(RETROSEQ_CALL.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_REHEADER_ME.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_SORT_ME.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_ME_SPLIT.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_CONCAT_ME.out.versions.first()) - ch_versions = ch_versions.mix(SVDB_MERGE_ME.out.versions) - ch_versions = ch_versions.mix(TABIX_ME.out.versions) - emit: - vcf = SVDB_MERGE_ME.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = TABIX_ME.out.tbi // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] + tbi = TABIX_ME.out.index // channel: [ val(meta), path(tbi) ] + vcf = SVDB_MERGE_ME.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_mobile_elements/tests/main.nf.test b/subworkflows/local/call_mobile_elements/tests/main.nf.test new file mode 100644 index 000000000..143f8259d --- /dev/null +++ b/subworkflows/local/call_mobile_elements/tests/main.nf.test @@ -0,0 +1,46 @@ +nextflow_workflow { + + name "Test Workflow CALL_MOBILE_ELEMENTS" + script "subworkflows/local/call_mobile_elements/main.nf" + workflow "CALL_MOBILE_ELEMENTS" + + tag "subworkflows" + tag "call_mobile_elements" + + tag "bcftools/reheader" + tag "bcftools/concat" + tag "bcftools/sort" + tag "retroseq/discover" + tag "retroseq/call" + tag "samtools/view" + tag "tabix/tabix" + tag "svdb/merge" + + test("CALL_MOBILE_ELEMENTS - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([id:'justhusky']) + input[1] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[4] = channel.of(['LINE', file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/call_mobile_elements/tests/main.nf.test.snap b/subworkflows/local/call_mobile_elements/tests/main.nf.test.snap new file mode 100644 index 000000000..3fd01589b --- /dev/null +++ b/subworkflows/local/call_mobile_elements/tests/main.nf.test.snap @@ -0,0 +1,45 @@ +{ + "CALL_MOBILE_ELEMENTS - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_mobile_elements.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky_mobile_elements.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky_mobile_elements.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_mobile_elements.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-26T16:04:01.036079356", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_repeat_expansions.nf b/subworkflows/local/call_repeat_expansions/main.nf similarity index 55% rename from subworkflows/local/call_repeat_expansions.nf rename to subworkflows/local/call_repeat_expansions/main.nf index fb364aac5..edc0afa45 100644 --- a/subworkflows/local/call_repeat_expansions.nf +++ b/subworkflows/local/call_repeat_expansions/main.nf @@ -2,14 +2,13 @@ // Run ExpansionHunter and Stranger // -include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_EXP } from '../../modules/nf-core/bcftools/norm/main' -include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_EXP } from '../../modules/nf-core/bcftools/reheader/main' -include { EXPANSIONHUNTER } from '../../modules/nf-core/expansionhunter/main' -include { PICARD_RENAMESAMPLEINVCF as RENAMESAMPLE_EXP } from '../../modules/nf-core/picard/renamesampleinvcf/main' -include { SAMTOOLS_SORT } from '../../modules/nf-core/samtools/sort/main' -include { SAMTOOLS_INDEX } from '../../modules/nf-core/samtools/index/main' -include { SVDB_MERGE as SVDB_MERGE_REPEATS } from '../../modules/nf-core/svdb/merge/main' -include { TABIX_TABIX as TABIX_EXP_RENAME } from '../../modules/nf-core/tabix/tabix/main' +include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_EXP } from '../../../modules/nf-core/bcftools/norm/main' +include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_EXP } from '../../../modules/nf-core/bcftools/reheader/main' +include { EXPANSIONHUNTER } from '../../../modules/nf-core/expansionhunter/main' +include { PICARD_RENAMESAMPLEINVCF as RENAMESAMPLE_EXP } from '../../../modules/nf-core/picard/renamesampleinvcf/main' +include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main' +include { SVDB_MERGE as SVDB_MERGE_REPEATS } from '../../../modules/nf-core/svdb/merge/main' +include { TABIX_TABIX as TABIX_EXP_RENAME } from '../../../modules/nf-core/tabix/tabix/main' workflow CALL_REPEAT_EXPANSIONS { take: @@ -20,7 +19,6 @@ workflow CALL_REPEAT_EXPANSIONS { ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] main: - ch_versions = Channel.empty() EXPANSIONHUNTER ( ch_bam, @@ -30,8 +28,7 @@ workflow CALL_REPEAT_EXPANSIONS { ) // Sort and index realigned bam - SAMTOOLS_SORT(EXPANSIONHUNTER.out.bam, [[:],[]]) - SAMTOOLS_INDEX(SAMTOOLS_SORT.out.bam) + SAMTOOLS_SORT(EXPANSIONHUNTER.out.bam, [[:],[]], 'bai') // Fix header and rename sample BCFTOOLS_REHEADER_EXP ( @@ -43,13 +40,13 @@ workflow CALL_REPEAT_EXPANSIONS { // Split multi allelelic SPLIT_MULTIALLELICS_EXP ( - RENAMESAMPLE_EXP.out.vcf.join(TABIX_EXP_RENAME.out.tbi, failOnMismatch:true, failOnDuplicate:true), + RENAMESAMPLE_EXP.out.vcf.join(TABIX_EXP_RENAME.out.index, failOnMismatch:true, failOnDuplicate:true), ch_genome_fasta ) // Merge indiviual repeat expansions SPLIT_MULTIALLELICS_EXP.out.vcf - .collect{it[1]} + .collect{_meta, vcf -> vcf} .toList() .collect() .set {ch_exp_vcfs} @@ -60,16 +57,9 @@ workflow CALL_REPEAT_EXPANSIONS { SVDB_MERGE_REPEATS ( ch_svdb_merge_input, [], true ) - ch_versions = ch_versions.mix(EXPANSIONHUNTER.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_REHEADER_EXP.out.versions.first()) - ch_versions = ch_versions.mix(RENAMESAMPLE_EXP.out.versions.first() ) - ch_versions = ch_versions.mix(TABIX_EXP_RENAME.out.versions.first()) - ch_versions = ch_versions.mix(SPLIT_MULTIALLELICS_EXP.out.versions.first()) - ch_versions = ch_versions.mix(SVDB_MERGE_REPEATS.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first()) - -emit: - vcf = SVDB_MERGE_REPEATS.out.vcf // channel: [ val(meta), path(vcf) ] - versions = ch_versions // channel: [ path(versions.yml) ] + emit: + expansionhunter_bai = SAMTOOLS_SORT.out.bai // channel: [ val(meta), path(bai) ] + expansionhunter_bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), path(bam) ] + expansionhunter_vcf = BCFTOOLS_REHEADER_EXP.out.vcf // channel: [ val(meta), path(vcf) ] + vcf = SVDB_MERGE_REPEATS.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_repeat_expansions/tests/main.nf.test b/subworkflows/local/call_repeat_expansions/tests/main.nf.test new file mode 100644 index 000000000..58d94e1e4 --- /dev/null +++ b/subworkflows/local/call_repeat_expansions/tests/main.nf.test @@ -0,0 +1,83 @@ +nextflow_workflow { + + name "Test Workflow CALL_REPEAT_EXPANSIONS" + script "subworkflows/local/call_repeat_expansions/main.nf" + workflow "CALL_REPEAT_EXPANSIONS" + + tag "subworkflows" + tag "call_repeat_expansions" + + tag "bcftools/norm" + tag "bcftools/reheader" + tag "expansionhunter" + tag "picard/renamesampleinvcf" + tag "samtools/sort" + tag "svdb/merge" + tag "tabix/tabix" + + config "./nextflow.config" + + test("CALL_REPEAT_EXPANSIONS") { + + when { + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + '/reference/variant_catalog.json', checkIfExists: true)).collect() + input[2] = channel.of([id:'justhusky']) + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + """ + } + } + + then { + assert workflow.success + assert snapshot( + workflow.out.expansionhunter_bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] }, + workflow.out.expansionhunter_bai.collect { meta, f -> file(f).name }, + workflow.out.expansionhunter_vcf.collect { meta, f -> file(f).name }, + path(workflow.out.vcf[0][1].toString()).vcf.variantsMD5, + path(workflow.out.vcf[0][1].toString()).vcf.summary + ).match() + } + + } + + + test("CALL_REPEAT_EXPANSIONS, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + '/reference/variant_catalog.json', checkIfExists: true)).collect() + input[2] = channel.of([id:'justhusky']) + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + +} diff --git a/subworkflows/local/call_repeat_expansions/tests/main.nf.test.snap b/subworkflows/local/call_repeat_expansions/tests/main.nf.test.snap new file mode 100644 index 000000000..ed506b8b7 --- /dev/null +++ b/subworkflows/local/call_repeat_expansions/tests/main.nf.test.snap @@ -0,0 +1,172 @@ +{ + "CALL_REPEAT_EXPANSIONS, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_exphunter_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_exphunter_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_repeat_expansion.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "justhusky" + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "expansionhunter_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_exphunter_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "expansionhunter_bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_exphunter_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "expansionhunter_vcf": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_repeat_expansion.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-26T00:25:14.58580944", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "CALL_REPEAT_EXPANSIONS": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "79adf682f13384ba13be973a64e2db48" + ] + ], + [ + "earlycasualcaiman_exphunter_sorted.bam.bai" + ], + [ + "earlycasualcaiman_repeat_expansion.vcf" + ], + "5f06dccb7fc4ad3758bc23e3232f9abb", + "VcfFile [chromosomes=[21], sampleCount=1, variantCount=2, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-06-26T00:35:51.559219111", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_repeat_expansions/tests/nextflow.config b/subworkflows/local/call_repeat_expansions/tests/nextflow.config new file mode 100644 index 000000000..916cff868 --- /dev/null +++ b/subworkflows/local/call_repeat_expansions/tests/nextflow.config @@ -0,0 +1,43 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for defining DSL2 per module options and publishing paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Available keys to override module options: + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. + ext.when = Conditional clause +---------------------------------------------------------------------------------------- +*/ + +// +// Repeat expansion calling options +// + +process { + withName: '.*CALL_REPEAT_EXPANSIONS:EXPANSIONHUNTER' { + ext.args = { ("${meta.sex}" == '1') ? '--sex male' : '--sex female' } + ext.prefix = { "${meta.id}_exphunter" } + } + + withName: '.*CALL_REPEAT_EXPANSIONS:SAMTOOLS_SORT' { + ext.prefix = { "${meta.id}_exphunter_sorted" } + } + + withName: '.*CALL_REPEAT_EXPANSIONS:BCFTOOLS_REHEADER_EXP' { + ext.args = "--temp-prefix ." + ext.args2 = "-O v" + ext.prefix = { "${meta.id}_repeat_expansion" } + } + + withName: '.*CALL_REPEAT_EXPANSIONS:SPLIT_MULTIALLELICS_EXP' { + ext.args = '--output-type z --multiallelics -both' + ext.prefix = { "${meta.id}_split_exp" } + } + + withName: '.*CALL_REPEAT_EXPANSIONS:SVDB_MERGE_REPEATS' { + ext.args = {"--notag"} + } + +} diff --git a/subworkflows/local/call_snv.nf b/subworkflows/local/call_snv.nf deleted file mode 100644 index eac3adfec..000000000 --- a/subworkflows/local/call_snv.nf +++ /dev/null @@ -1,164 +0,0 @@ -// -// call Single-nucleotide Varinats -// - -include { CALL_SNV_DEEPVARIANT } from './call_snv_deepvariant' -include { CALL_SNV_SENTIEON } from './call_snv_sentieon' -include { CALL_SNV_MT } from './call_snv_MT' -include { CALL_SNV_MT as CALL_SNV_MT_SHIFT } from './call_snv_MT' -include { POSTPROCESS_MT_CALLS } from './postprocess_MT_calls' -include { GATK4_SELECTVARIANTS } from '../../modules/nf-core/gatk4/selectvariants/main' -include { BCFTOOLS_CONCAT } from '../../modules/nf-core/bcftools/concat' - -workflow CALL_SNV { - take: - ch_genome_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_mtshift_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_mt_intervals // channel: [optional] [ path(interval_list) ] - ch_mt_dictionary // channel: [optional] [ val(meta), path(dict) ] - ch_mt_fai // channel: [optional] [ val(meta), path(fai) ] - ch_mt_fasta // channel: [optional] [ val(meta), path(fasta) ] - ch_mtshift_dictionary // channel: [optional] [ val(meta), path(dict) ] - ch_mtshift_fai // channel: [optional] [ val(meta), path(fai) ] - ch_mtshift_fasta // channel: [optional] [ val(meta), path(fasta) ] - ch_mtshift_intervals // channel: [optional] [ path(interval_list) ] - ch_mtshift_backchain // channel: [mandatory] [ val(meta), path(back_chain) ] - ch_dbsnp // channel: [optional] [ val(meta), path(vcf) ] - ch_dbsnp_tbi // channel: [optional] [ val(meta), path(tbi) ] - ch_call_interval // channel: [mandatory] [ path(intervals) ] - ch_target_bed // channel: [mandatory] [ val(meta), path(bed), path(index) ] - ch_ml_model // channel: [mandatory] [ path(model) ] - ch_par_bed // channel: [optional] [ val(meta), path(bed) ] - ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_foundin_header // channel: [mandatory] [ path(header) ] - ch_pcr_indel_model // channel: [optional] [ val(sentieon_dnascope_pcr_indel_model) ] - - main: - ch_versions = Channel.empty() - ch_deepvar_vcf = Channel.empty() - ch_deepvar_tbi = Channel.empty() - ch_deepvar_gvcf = Channel.empty() - ch_deepvar_gtbi = Channel.empty() - ch_mt_vcf = Channel.empty() - ch_mt_tabix = Channel.empty() - ch_mt_vcf_tabix = Channel.empty() - ch_mt_txt = Channel.empty() - ch_sentieon_vcf = Channel.empty() - ch_sentieon_tbi = Channel.empty() - ch_sentieon_gvcf = Channel.empty() - ch_sentieon_gtbi = Channel.empty() - - if (params.variant_caller.equals("deepvariant") && !params.analysis_type.equals("mito")) { - CALL_SNV_DEEPVARIANT ( // triggered only when params.variant_caller is set as deepvariant - ch_genome_bam_bai, - ch_genome_fasta, - ch_genome_fai, - ch_target_bed, - ch_par_bed, - ch_case_info, - ch_foundin_header, - ch_genome_chrsizes - ) - ch_deepvar_vcf = CALL_SNV_DEEPVARIANT.out.vcf - ch_deepvar_tbi = CALL_SNV_DEEPVARIANT.out.tabix - ch_deepvar_gvcf = CALL_SNV_DEEPVARIANT.out.gvcf - ch_deepvar_gtbi = CALL_SNV_DEEPVARIANT.out.gvcf_tabix - ch_versions = ch_versions.mix(CALL_SNV_DEEPVARIANT.out.versions) - } else if (params.variant_caller.equals("sentieon")) { - CALL_SNV_SENTIEON( // triggered only when params.variant_caller is set as sentieon - ch_genome_bam_bai, - ch_genome_fasta, - ch_genome_fai, - ch_dbsnp, - ch_dbsnp_tbi, - ch_call_interval, - ch_ml_model, - ch_case_info, - ch_pcr_indel_model, - ch_foundin_header, - ch_genome_chrsizes - ) - ch_sentieon_vcf = CALL_SNV_SENTIEON.out.vcf - ch_sentieon_tbi = CALL_SNV_SENTIEON.out.tabix - ch_sentieon_gvcf = CALL_SNV_SENTIEON.out.gvcf - ch_sentieon_gtbi = CALL_SNV_SENTIEON.out.gvcf_tbi - ch_versions = ch_versions.mix(CALL_SNV_SENTIEON.out.versions) - } - - ch_vcf = Channel.empty().mix(ch_deepvar_vcf, ch_sentieon_vcf) - ch_tabix = Channel.empty().mix(ch_deepvar_tbi, ch_sentieon_tbi) - ch_gvcf = Channel.empty().mix(ch_deepvar_gvcf, ch_sentieon_gvcf) - ch_gtabix = Channel.empty().mix(ch_deepvar_gtbi, ch_sentieon_gtbi) - - ch_vcf - .join(ch_tabix, failOnMismatch:true, failOnDuplicate:true) - .map { meta, vcf, tbi -> return [meta, vcf, tbi, []]} - .set {ch_selvar_in} - GATK4_SELECTVARIANTS(ch_selvar_in) // remove mitochondrial variants - - ch_genome_vcf = GATK4_SELECTVARIANTS.out.vcf - ch_genome_tabix = GATK4_SELECTVARIANTS.out.tbi - ch_genome_vcf_tabix = ch_genome_vcf.join(ch_genome_tabix, failOnMismatch:true, failOnDuplicate:true) - - if (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) { - CALL_SNV_MT( - ch_mt_bam_bai, - ch_mt_fasta, - ch_mt_fai, - ch_mt_dictionary, - ch_mt_intervals - ) - - CALL_SNV_MT_SHIFT( - ch_mtshift_bam_bai, - ch_mtshift_fasta, - ch_mtshift_fai, - ch_mtshift_dictionary, - ch_mtshift_intervals - ) - - POSTPROCESS_MT_CALLS( - CALL_SNV_MT.out.vcf, - CALL_SNV_MT_SHIFT.out.vcf, - ch_mt_fasta, - ch_mt_dictionary, - ch_mt_fai, - ch_mtshift_backchain, - ch_case_info, - ch_foundin_header, - ch_genome_chrsizes - ) - ch_mt_vcf = POSTPROCESS_MT_CALLS.out.vcf - ch_mt_tabix = POSTPROCESS_MT_CALLS.out.tbi - ch_mt_vcf_tabix = ch_mt_vcf.join(ch_mt_tabix, failOnMismatch:true, failOnDuplicate:true) - ch_mt_txt = CALL_SNV_MT.out.txt - ch_versions = ch_versions.mix(CALL_SNV_MT.out.versions) - ch_versions = ch_versions.mix(CALL_SNV_MT_SHIFT.out.versions) - ch_versions = ch_versions.mix(POSTPROCESS_MT_CALLS.out.versions) - ch_versions = ch_versions.mix(GATK4_SELECTVARIANTS.out.versions) - } - - if (params.concatenate_snv_calls) { - ch_concat_vcf_in = ch_genome_vcf_tabix.concat(ch_mt_vcf_tabix).groupTuple() - BCFTOOLS_CONCAT ( - ch_concat_vcf_in - ) - ch_versions = ch_versions.mix(BCFTOOLS_CONCAT.out.versions) - } - - emit: - genome_vcf = ch_genome_vcf // channel: [ val(meta), path(vcf) ] - genome_tabix = ch_genome_tabix // channel: [ val(meta), path(tbi) ] - genome_vcf_tabix = ch_genome_vcf_tabix // channel: [ val(meta), path(vcf), path(tbi) ] - genome_gvcf = ch_gvcf // channel: [ val(meta), path(gvcf) ] - genome_gtabix = ch_gtabix // channel: [ val(meta), path(gtbi) ] - mt_vcf = ch_mt_vcf // channel: [ val(meta), path(vcf) ] - mt_tabix = ch_mt_tabix // channel: [ val(meta), path(tbi) ] - mt_txt = ch_mt_txt // channel: [ val(meta), path(txt) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/call_snv/main.nf b/subworkflows/local/call_snv/main.nf new file mode 100644 index 000000000..7ce27b358 --- /dev/null +++ b/subworkflows/local/call_snv/main.nf @@ -0,0 +1,172 @@ +// +// call Single-nucleotide Varinats +// + +include { BCFTOOLS_CONCAT } from '../../../modules/nf-core/bcftools/concat' +include { CALL_SNV_DEEPVARIANT } from '../call_snv_deepvariant' +include { CALL_SNV_MT } from '../call_snv_MT' +include { CALL_SNV_MT as CALL_SNV_MT_SHIFT } from '../call_snv_MT' +include { CALL_SNV_SENTIEON } from '../call_snv_sentieon' +include { GATK4_SELECTVARIANTS } from '../../../modules/nf-core/gatk4/selectvariants/main' +include { POSTPROCESS_MT_CALLS } from '../postprocess_MT_calls' + +workflow CALL_SNV { + take: + ch_call_interval // channel: [mandatory] [ path(intervals) ] + ch_case_info // channel: [mandatory] [ val(case_info) ] + ch_dbsnp // channel: [optional] [ val(meta), path(vcf) ] + ch_dbsnp_tbi // channel: [optional] [ val(meta), path(tbi) ] + ch_foundin_header // channel: [mandatory] [ path(header) ] + ch_genome_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_ml_model // channel: [mandatory] [ path(model) ] + ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_mt_dictionary // channel: [optional] [ val(meta), path(dict) ] + ch_mt_fai // channel: [optional] [ val(meta), path(fai) ] + ch_mt_fasta // channel: [optional] [ val(meta), path(fasta) ] + ch_mt_intervals // channel: [optional] [ path(interval_list) ] + ch_mtshift_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_mtshift_dictionary // channel: [optional] [ val(meta), path(dict) ] + ch_mtshift_fai // channel: [optional] [ val(meta), path(fai) ] + ch_mtshift_fasta // channel: [optional] [ val(meta), path(fasta) ] + ch_mtshift_intervals // channel: [optional] [ path(interval_list) ] + ch_mtshift_backchain // channel: [mandatory] [ val(meta), path(back_chain) ] + ch_par_bed // channel: [optional] [ val(meta), path(bed) ] + ch_pcr_indel_model // channel: [optional] [ val(sentieon_dnascope_pcr_indel_model) ] + ch_target_bed // channel: [mandatory] [ val(meta), path(bed), path(index) ] + val_analysis_type // string: 'wgs', 'wes', or 'mito' + val_concatenate_snv_calls // boolean + val_run_mt_for_wes // boolean + val_skip_split_multiallelics // boolean + val_variant_caller // string: 'deepvariant' or 'sentieon' + + main: + ch_bcftools_concat_csi = channel.empty() + ch_bcftools_concat_tbi = channel.empty() + ch_bcftools_concat_vcf = channel.empty() + ch_deepvariant_gvcf = channel.empty() + ch_deepvariant_gtbi = channel.empty() + ch_deepvariant_report = channel.empty() + ch_deepvariant_tbi = channel.empty() + ch_deepvariant_vcf = channel.empty() + ch_mt_tabix = channel.empty() + ch_mt_vcf = channel.empty() + ch_mt_vcf_tabix = channel.empty() + ch_sentieon_gvcf = channel.empty() + ch_sentieon_gtbi = channel.empty() + ch_sentieon_tbi = channel.empty() + ch_sentieon_vcf = channel.empty() + + if (val_variant_caller.equals("deepvariant") && !val_analysis_type.equals("mito")) { + CALL_SNV_DEEPVARIANT ( + ch_genome_bam_bai, + ch_case_info, + ch_foundin_header, + ch_genome_chrsizes, + ch_genome_fai, + ch_genome_fasta, + ch_par_bed, + ch_target_bed, + val_analysis_type, + val_skip_split_multiallelics + ) + ch_deepvariant_vcf = CALL_SNV_DEEPVARIANT.out.vcf + ch_deepvariant_tbi = CALL_SNV_DEEPVARIANT.out.tabix + ch_deepvariant_gvcf = CALL_SNV_DEEPVARIANT.out.gvcf + ch_deepvariant_gtbi = CALL_SNV_DEEPVARIANT.out.gvcf_tabix + ch_deepvariant_report = CALL_SNV_DEEPVARIANT.out.deepvariant_report + } else if (val_variant_caller.equals("sentieon")) { + CALL_SNV_SENTIEON( + ch_genome_bam_bai, + ch_call_interval, + ch_case_info, + ch_dbsnp, + ch_dbsnp_tbi, + ch_foundin_header, + ch_genome_chrsizes, + ch_genome_fai, + ch_genome_fasta, + ch_ml_model, + ch_pcr_indel_model, + val_skip_split_multiallelics + ) + ch_sentieon_vcf = CALL_SNV_SENTIEON.out.vcf + ch_sentieon_tbi = CALL_SNV_SENTIEON.out.tabix + ch_sentieon_gvcf = CALL_SNV_SENTIEON.out.gvcf + ch_sentieon_gtbi = CALL_SNV_SENTIEON.out.gvcf_tbi + } + + ch_vcf = channel.empty().mix(ch_deepvariant_vcf, ch_sentieon_vcf) + ch_tabix = channel.empty().mix(ch_deepvariant_tbi, ch_sentieon_tbi) + ch_gvcf = channel.empty().mix(ch_deepvariant_gvcf, ch_sentieon_gvcf) + ch_gtabix = channel.empty().mix(ch_deepvariant_gtbi, ch_sentieon_gtbi) + + ch_vcf + .join(ch_tabix, failOnMismatch:true, failOnDuplicate:true) + .map { meta, vcf, tbi -> return [meta, vcf, tbi, []]} + .set {ch_select_variants_in} + GATK4_SELECTVARIANTS(ch_select_variants_in) // remove mitochondrial variants + + ch_genome_vcf = GATK4_SELECTVARIANTS.out.vcf + ch_genome_tabix = GATK4_SELECTVARIANTS.out.tbi + ch_genome_vcf_tabix = ch_genome_vcf.join(ch_genome_tabix, failOnMismatch:true, failOnDuplicate:true) + + if (val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) { + CALL_SNV_MT( + ch_mt_bam_bai, + ch_mt_dictionary, + ch_mt_fai, + ch_mt_fasta, + ch_mt_intervals + ) + + CALL_SNV_MT_SHIFT( + ch_mtshift_bam_bai, + ch_mtshift_dictionary, + ch_mtshift_fai, + ch_mtshift_fasta, + ch_mtshift_intervals + ) + + POSTPROCESS_MT_CALLS( + ch_case_info, + ch_foundin_header, + ch_genome_chrsizes, + ch_mt_dictionary, + ch_mt_fai, + ch_mt_fasta, + CALL_SNV_MT.out.vcf, + ch_mtshift_backchain, + CALL_SNV_MT_SHIFT.out.vcf + ) + ch_mt_vcf = POSTPROCESS_MT_CALLS.out.vcf + ch_mt_tabix = POSTPROCESS_MT_CALLS.out.tbi + ch_mt_vcf_tabix = ch_mt_vcf.join(ch_mt_tabix, failOnMismatch:true, failOnDuplicate:true) + } + + if (val_concatenate_snv_calls) { + ch_concat_vcf_in = ch_genome_vcf_tabix.concat(ch_mt_vcf_tabix).groupTuple() + BCFTOOLS_CONCAT ( + ch_concat_vcf_in + ) + ch_bcftools_concat_vcf = BCFTOOLS_CONCAT.out.vcf + ch_bcftools_concat_tbi = BCFTOOLS_CONCAT.out.tbi + ch_bcftools_concat_csi = BCFTOOLS_CONCAT.out.csi + } + + emit: + bcftools_concat_csi = ch_bcftools_concat_csi // channel: [ val(meta), path(csi) ] + bcftools_concat_tbi = ch_bcftools_concat_tbi // channel: [ val(meta), path(tbi) ] + bcftools_concat_vcf = ch_bcftools_concat_vcf // channel: [ val(meta), path(vcf) ] + deepvariant_report = ch_deepvariant_report // channel: [ val(meta), path(html) ] + genome_gtabix = ch_gtabix // channel: [ val(meta), path(gtbi) ] + genome_gvcf = ch_gvcf // channel: [ val(meta), path(gvcf) ] + genome_tabix = ch_genome_tabix // channel: [ val(meta), path(tbi) ] + genome_vcf = ch_genome_vcf // channel: [ val(meta), path(vcf) ] + genome_vcf_tabix = ch_genome_vcf_tabix // channel: [ val(meta), path(vcf), path(tbi) ] + mt_tabix = ch_mt_tabix // channel: [ val(meta), path(tbi) ] + mt_vcf = ch_mt_vcf // channel: [ val(meta), path(vcf) ] + mt_vcf_tbi = ch_mt_vcf_tabix // channel: [ val(meta), path(vcf), path(tbi)] +} diff --git a/subworkflows/local/call_snv/tests/main.nf.test b/subworkflows/local/call_snv/tests/main.nf.test new file mode 100644 index 000000000..20efee6b9 --- /dev/null +++ b/subworkflows/local/call_snv/tests/main.nf.test @@ -0,0 +1,144 @@ +nextflow_workflow { + + name "Test Workflow CALL_SNV" + script "subworkflows/local/call_snv/main.nf" + workflow "CALL_SNV" + + tag "subworkflows" + tag "call_snv" + tag "call_snv_deepvariant" + tag "call_snv_sentieon" + tag "call_snv_MT" + tag "postprocess_MT_calls" + + tag "gatk4_selectvariants" + tag "bcftools_concat" + + + test("CALL_SNV - deepvariant wgs") { + + when { + workflow { + """ + input[0] = channel.of([[id:'interval'], []]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/dbsnp_-138-.vcf.gz', checkIfExists: true)]) + input[3] = channel.of([[id:'genome'], []]) + input[4] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[5] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[6] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[9] = channel.of([[id:'model'], []]) + input[10] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[11] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[12] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[13] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[14] = channel.of(file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease/reference/mt.intervals', checkIfExists: true)).collect() + input[15] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[16] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.dict', checkIfExists: true)]).collect() + input[17] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.fasta.fai', checkIfExists: true)]).collect() + input[18] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.fasta', checkIfExists: true)]).collect() + input[19] = channel.of(file(params.pipelines_testdata_base_path + 'reference/mt_shift8000.intervals', checkIfExists: true)).collect() + input[20] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/mt_shift8000.back_chain', checkIfExists: true)]).collect() + input[21] = channel.of([[id:'par'], []]) + input[22] = channel.of([[id:'model'], []]) + input[23] = channel.of([[id:'target'], [], []]) + input[24] = 'wgs' + input[25] = false + input[26] = false + input[27] = false + input[28] = 'deepvariant' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.genome_vcf[0][1]).vcf.variantsMD5, + path(workflow.out.genome_vcf[0][1]).vcf.summary, + workflow.out.deepvariant_report.collect { meta, report -> file(report).name }, + workflow.out.genome_tabix.collect { meta, tbi -> file(tbi).name }, + workflow.out.mt_vcf.collect { meta, vcf -> file(vcf).name }, + workflow.out.mt_tabix.collect { meta, tbi -> file(tbi).name } + ).match() } + ) + } + } + + test("CALL_SNV - deepvariant wgs, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([[id:'interval'], []]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/dbsnp_-138-.vcf.gz', checkIfExists: true)]) + input[3] = channel.of([[id:'genome'], []]) + input[4] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[5] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[6] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[9] = channel.of([[id:'model'], []]) + input[10] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[11] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[12] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[13] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[14] = channel.of(file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease/reference/mt.intervals', checkIfExists: true)).collect() + input[15] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[16] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.dict', checkIfExists: true)]).collect() + input[17] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.fasta.fai', checkIfExists: true)]).collect() + input[18] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_shift.fasta', checkIfExists: true)]).collect() + input[19] = channel.of(file(params.pipelines_testdata_base_path + 'reference/mt_shift8000.intervals', checkIfExists: true)).collect() + input[20] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/mt_shift8000.back_chain', checkIfExists: true)]).collect() + input[21] = channel.of([[id:'par'], []]) + input[22] = channel.of([[id:'model'], []]) + input[23] = channel.of([[id:'target'], [], []]) + input[24] = 'wgs' + input[25] = true + input[26] = false + input[27] = false + input[28] = 'deepvariant' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_snv/tests/main.nf.test.snap b/subworkflows/local/call_snv/tests/main.nf.test.snap new file mode 100644 index 000000000..a405628f6 --- /dev/null +++ b/subworkflows/local/call_snv/tests/main.nf.test.snap @@ -0,0 +1,252 @@ +{ + "CALL_SNV - deepvariant wgs": { + "content": [ + "dfc0eeae02f4c1f04034e0fff555bf50", + "VcfFile [chromosomes=[21], sampleCount=1, variantCount=7562, phased=false, phasedAutodetect=false]", + [ + "earlycasualcaiman_deepvar.visual_report.html" + ], + [ + "justhusky_snv.vcf.gz.tbi" + ], + [ + "justhusky_mitochondria.vcf.gz" + ], + [ + "justhusky_mitochondria.vcf.gz.tbi" + ] + ], + "timestamp": "2026-05-30T00:18:20.446833954", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "CALL_SNV - deepvariant wgs, stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky_mt_and_nuclear_snvs.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "11": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "justhusky" + }, + "justhusky_mt_and_nuclear_snvs.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "5": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "6": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "8": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_snv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bcftools_concat_csi": [ + + ], + "bcftools_concat_tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky_mt_and_nuclear_snvs.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bcftools_concat_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_mt_and_nuclear_snvs.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "deepvariant_report": [ + + ], + "genome_gtabix": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ], + "genome_gvcf": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "genome_tabix": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "genome_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "genome_vcf_tabix": [ + [ + { + "id": "justhusky" + }, + "justhusky_snv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_snv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "mt_tabix": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "mt_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "mt_vcf_tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-22T12:57:59.006104185", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_snv_MT/main.nf b/subworkflows/local/call_snv_MT/main.nf index 17135d33a..ac479f3be 100644 --- a/subworkflows/local/call_snv_MT/main.nf +++ b/subworkflows/local/call_snv_MT/main.nf @@ -2,31 +2,22 @@ // Call SNV MT // -include { HAPLOCHECK as HAPLOCHECK_MT } from '../../../modules/nf-core/haplocheck/main' -include { GATK4_MUTECT2 as GATK4_MUTECT2_MT } from '../../../modules/nf-core/gatk4/mutect2/main' -include { GATK4_FILTERMUTECTCALLS as GATK4_FILTERMUTECTCALLS_MT } from '../../../modules/nf-core/gatk4/filtermutectcalls/main' +include { GATK4_FILTERMUTECTCALLS as GATK4_FILTERMUTECTCALLS_MT } from '../../../modules/nf-core/gatk4/filtermutectcalls/main' +include { GATK4_MUTECT2 as GATK4_MUTECT2_MT } from '../../../modules/nf-core/gatk4/mutect2/main' workflow CALL_SNV_MT { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_fai // channel: [mandatory] [ val(meta), path(fai) ] ch_dict // channel: [mandatory] [ val(meta), path(dict) ] + ch_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_intervals // channel: [mandatory] [ path(interval_list) ] main: - ch_versions = Channel.empty() - ch_haplocheck_txt = Channel.empty() - ch_haplocheck_html = Channel.empty() - - ch_bam_bai_int = ch_bam_bai.combine(ch_intervals) - GATK4_MUTECT2_MT (ch_bam_bai_int, ch_fasta, ch_fai, ch_dict, [], [], [],[]) + ch_bam_bai_intervals = ch_bam_bai.combine(ch_intervals) - HAPLOCHECK_MT (GATK4_MUTECT2_MT.out.vcf).set { ch_haplocheck } - ch_versions = ch_versions.mix(HAPLOCHECK_MT.out.versions.first()) - ch_haplocheck_txt = HAPLOCHECK_MT.out.txt - ch_haplocheck_html = HAPLOCHECK_MT.out.html + GATK4_MUTECT2_MT (ch_bam_bai_intervals, ch_fasta, ch_fai.map{meta, fai -> return [meta,fai,[]]}, ch_dict, [], [], [], [], [],[]) // Filter Mutect2 calls ch_mutect_vcf = GATK4_MUTECT2_MT.out.vcf.join(GATK4_MUTECT2_MT.out.tbi, failOnMismatch:true, failOnDuplicate:true) @@ -38,15 +29,9 @@ workflow CALL_SNV_MT { GATK4_FILTERMUTECTCALLS_MT (ch_to_filt, ch_fasta, ch_fai, ch_dict) - ch_versions = ch_versions.mix(GATK4_MUTECT2_MT.out.versions.first()) - ch_versions = ch_versions.mix(GATK4_FILTERMUTECTCALLS_MT.out.versions.first()) - emit: - vcf = GATK4_FILTERMUTECTCALLS_MT.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = GATK4_FILTERMUTECTCALLS_MT.out.tbi // channel: [ val(meta), path(tbi) ] - stats = GATK4_MUTECT2_MT.out.stats // channel: [ val(meta), path(stats) ] filt_stats = GATK4_FILTERMUTECTCALLS_MT.out.stats // channel: [ val(meta), path(tsv) ] - txt = ch_haplocheck_txt // channel: [ val(meta), path(txt) ] - html = ch_haplocheck_html // channel: [ val(meta), path(html) ] - versions = ch_versions // channel: [ path(versions.yml) ] + stats = GATK4_MUTECT2_MT.out.stats // channel: [ val(meta), path(stats) ] + tbi = GATK4_FILTERMUTECTCALLS_MT.out.tbi // channel: [ val(meta), path(tbi) ] + vcf = GATK4_FILTERMUTECTCALLS_MT.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_snv_MT/tests/main.nf.test b/subworkflows/local/call_snv_MT/tests/main.nf.test new file mode 100644 index 000000000..bc4dee845 --- /dev/null +++ b/subworkflows/local/call_snv_MT/tests/main.nf.test @@ -0,0 +1,71 @@ +nextflow_workflow { + + name "Test Workflow CALL_SNV_MT" + script "subworkflows/local/call_snv_MT/main.nf" + workflow "CALL_SNV_MT" + + tag "subworkflows" + tag "call_snv_MT" + + tag "gatk4/mutect2" + tag "gatk4/filtermutectcalls" + + test("CALL_SNV_MT") { + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[2] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[3] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[4] = channel.of(file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease/reference/mt.intervals', checkIfExists: true)).collect() + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf.collect { meta, vcf -> file(vcf).name }, + workflow.out.tbi.collect { meta, tbi -> file(tbi).name } + ).match() } + ) + } + } + test("CALL_SNV_MT, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.dict', checkIfExists: true)).collect() + input[2] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)).collect() + input[3] = channel.of([id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)).collect() + input[4] = channel.of(file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease/reference/mt.intervals', checkIfExists: true)).collect() + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf.collect { meta, vcf -> file(vcf).name }, + workflow.out.tbi.collect { meta, tbi -> file(tbi).name } + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_snv_MT/tests/main.nf.test.snap b/subworkflows/local/call_snv_MT/tests/main.nf.test.snap new file mode 100644 index 000000000..63b18c146 --- /dev/null +++ b/subworkflows/local/call_snv_MT/tests/main.nf.test.snap @@ -0,0 +1,32 @@ +{ + "CALL_SNV_MT, stub": { + "content": [ + [ + "earlycasualcaiman_filtered.vcf.gz" + ], + [ + "earlycasualcaiman_filtered.vcf.gz.tbi" + ] + ], + "timestamp": "2026-03-04T17:12:30.676957964", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "CALL_SNV_MT": { + "content": [ + [ + "earlycasualcaiman_filtered.vcf.gz" + ], + [ + "earlycasualcaiman_filtered.vcf.gz.tbi" + ] + ], + "timestamp": "2026-03-03T20:17:50.085712628", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_snv_deepvariant/main.nf b/subworkflows/local/call_snv_deepvariant/main.nf index 826f2e6a3..5faeb6641 100644 --- a/subworkflows/local/call_snv_deepvariant/main.nf +++ b/subworkflows/local/call_snv_deepvariant/main.nf @@ -2,37 +2,35 @@ // A variant caller workflow for deepvariant // -include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' -include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_GL } from '../../../modules/nf-core/bcftools/norm/main' -include { BCFTOOLS_NORM as REMOVE_DUPLICATES_GL } from '../../../modules/nf-core/bcftools/norm/main' -include { DEEPVARIANT_RUNDEEPVARIANT as DEEPVARIANT } from '../../../modules/nf-core/deepvariant/rundeepvariant/main' -include { GLNEXUS } from '../../../modules/nf-core/glnexus/main' -include { TABIX_BGZIP } from '../../../modules/nf-core/tabix/bgzip/main' -include { TABIX_TABIX as TABIX_GL } from '../../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_ANNOTATE } from '../../../modules/nf-core/tabix/tabix/main' -include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' +include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' +include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' +include { BCFTOOLS_NORM as REMOVE_DUPLICATES_GL } from '../../../modules/nf-core/bcftools/norm/main' +include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_GL } from '../../../modules/nf-core/bcftools/norm/main' +include { DEEPVARIANT_RUNDEEPVARIANT as DEEPVARIANT } from '../../../modules/nf-core/deepvariant/rundeepvariant/main' +include { GLNEXUS } from '../../../modules/nf-core/glnexus/main' +include { TABIX_BGZIP } from '../../../modules/nf-core/tabix/bgzip/main' workflow CALL_SNV_DEEPVARIANT { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_target_bed // channel: [mandatory] [ val(meta), path(bed), path(index) ] - ch_par_bed // channel: [optional] [ val(meta), path(bed) ] ch_case_info // channel: [mandatory] [ val(case_info) ] ch_foundin_header // channel: [mandatory] [ path(header) ] ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_par_bed // channel: [optional] [ val(meta), path(bed) ] + ch_target_bed // channel: [mandatory] [ val(meta), path(bed), path(index) ] + val_analysis_type // boolean + val_skip_split_multiallelics // boolean main: - ch_versions = Channel.empty() - if (params.analysis_type.equals("wes")) { - TABIX_BGZIP(ch_target_bed.map{meta, gzbed, index -> return [meta, gzbed]}) + if (val_analysis_type.equals("wes")) { + TABIX_BGZIP(ch_target_bed.map{meta, gzbed, _index -> return [meta, gzbed]}) ch_bam_bai - .combine (TABIX_BGZIP.out.output.map {meta, bed -> return bed}) + .combine (TABIX_BGZIP.out.output.map {_meta, bed -> return bed}) .set { ch_deepvar_in } - ch_versions = ch_versions.mix(TABIX_BGZIP.out.versions) - } else if (params.analysis_type.equals("wgs")) { + } else if (val_analysis_type.equals("wgs")) { ch_bam_bai .map { meta, bam, bai -> return [meta, bam, bai, []] } @@ -41,13 +39,14 @@ workflow CALL_SNV_DEEPVARIANT { DEEPVARIANT ( ch_deepvar_in, ch_genome_fasta, ch_genome_fai, [[],[]], ch_par_bed ) DEEPVARIANT.out.gvcf - .map{ it -> it[1]} + .map{ _meta, gvcf -> gvcf} .toSortedList{a, b -> a.name <=> b.name} .toList() .set { ch_file_list } ch_case_info .combine(ch_file_list) + .map {meta, gvcf -> return [meta, gvcf, []]} .set { ch_gvcfs } GLNEXUS ( ch_gvcfs, [[:],[]] ) @@ -55,46 +54,39 @@ workflow CALL_SNV_DEEPVARIANT { ch_split_multi_in = GLNEXUS.out.bcf .map{ meta, bcf -> return [meta, bcf, []] } - SPLIT_MULTIALLELICS_GL (ch_split_multi_in, ch_genome_fasta) - ch_remove_dup_in = SPLIT_MULTIALLELICS_GL.out.vcf - .map{ meta, vcf -> - return [meta, vcf, []] } + if (!val_skip_split_multiallelics) { + SPLIT_MULTIALLELICS_GL (ch_split_multi_in, ch_genome_fasta) + ch_remove_dup_in = SPLIT_MULTIALLELICS_GL.out.vcf + .map{ meta, vcf -> + return [meta, vcf, []] } + } else { + ch_remove_dup_in = ch_split_multi_in + } REMOVE_DUPLICATES_GL (ch_remove_dup_in, ch_genome_fasta) - TABIX_GL (REMOVE_DUPLICATES_GL.out.vcf) - ch_genome_chrsizes.flatten().map{chromsizes -> return [[id:'deepvariant'], chromsizes] } .set { ch_varcallerinfo } ADD_VARCALLER_TO_BED (ch_varcallerinfo).gz_tbi - .map{meta,bed,tbi -> return [bed, tbi]} + .map{_meta,bed,tbi -> return [bed, tbi]} .set{ch_varcallerbed} REMOVE_DUPLICATES_GL.out.vcf - .join(TABIX_GL.out.tbi) + .join(REMOVE_DUPLICATES_GL.out.tbi) .combine(ch_varcallerbed) + .combine(ch_foundin_header) + .map { meta, vcf, vcf_tbi, bed, bed_tbi, hdr -> return [meta, vcf, vcf_tbi, bed, bed_tbi, [], hdr, []] } .set { ch_annotate_in } - BCFTOOLS_ANNOTATE(ch_annotate_in, ch_foundin_header) - - TABIX_ANNOTATE(BCFTOOLS_ANNOTATE.out.vcf) - - ch_versions = ch_versions.mix(DEEPVARIANT.out.versions.first()) - ch_versions = ch_versions.mix(GLNEXUS.out.versions) - ch_versions = ch_versions.mix(SPLIT_MULTIALLELICS_GL.out.versions) - ch_versions = ch_versions.mix(REMOVE_DUPLICATES_GL.out.versions) - ch_versions = ch_versions.mix(TABIX_GL.out.versions) - ch_versions = ch_versions.mix(ADD_VARCALLER_TO_BED.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(TABIX_ANNOTATE.out.versions) + BCFTOOLS_ANNOTATE(ch_annotate_in) emit: - vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] - tabix = TABIX_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] - gvcf = DEEPVARIANT.out.gvcf // channel: [ val(meta), path(gvcf)] - gvcf_tabix = DEEPVARIANT.out.gvcf_tbi // channel: [ val(meta), path(gvcf_tbi)] - versions = ch_versions // channel: [ path(versions.yml) ] + deepvariant_report = DEEPVARIANT.out.report // channel: [ val(meta), path(html) ] + gvcf = DEEPVARIANT.out.gvcf // channel: [ val(meta), path(gvcf)] + gvcf_tabix = DEEPVARIANT.out.gvcf_tbi // channel: [ val(meta), path(gvcf_tbi)] + tabix = BCFTOOLS_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] + vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_snv_deepvariant/tests/main.nf.test b/subworkflows/local/call_snv_deepvariant/tests/main.nf.test new file mode 100644 index 000000000..f87da44b3 --- /dev/null +++ b/subworkflows/local/call_snv_deepvariant/tests/main.nf.test @@ -0,0 +1,101 @@ +nextflow_workflow { + + name "Test Workflow CALL_SNV_DEEPVARIANT" + script "subworkflows/local/call_snv_deepvariant/main.nf" + workflow "CALL_SNV_DEEPVARIANT" + + tag "subworkflows" + tag "call_snv_deepvariant" + + tag "bcftools/annotate" + tag "bcftools/norm" + tag "deepvariant/rundeepvariant" + tag "glnexus" + tag "tabix/bgzip" + tag "local/add_varcallername_to_bed" + + config "./nextflow.config" + + test("CALL_SNV_DEEPVARIANT - wgs") { + + when { + params { + bcftools_args = "--write-index=tbi --output-type z" + } + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[3] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[6] = channel.of([[id:'par'], []]) + input[7] = channel.of([[id:'target'], [], []]) + input[8] = 'wgs' + input[9] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.vcf[0][1]).vcf.summary, + workflow.out.deepvariant_report.collect { meta, report -> file(report).name }, + workflow.out.tabix.collect { meta, tbi -> file(tbi).name }, + workflow.out.gvcf.collect { meta, gvcf -> file(gvcf).name } + ).match() } + ) + } + } + + test("CALL_SNV_DEEPVARIANT - wgs, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[3] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[5] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[6] = channel.of([[id:'par'], []]) + input[7] = channel.of([[id:'target'], [], []]) + input[8] = 'wgs' + input[9] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List) { + sortKey = sortKey[-1] + } + sortKey.toString().split(':md5,')[0].tokenize('/')[-1] + } + [name, sorted_channel] + }.sort { it[0] } // Sort by channel name + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_snv_deepvariant/tests/main.nf.test.snap b/subworkflows/local/call_snv_deepvariant/tests/main.nf.test.snap new file mode 100644 index 000000000..a67a60a2b --- /dev/null +++ b/subworkflows/local/call_snv_deepvariant/tests/main.nf.test.snap @@ -0,0 +1,172 @@ +{ + "CALL_SNV_DEEPVARIANT - wgs, stub": { + "content": [ + [ + [ + "0", + [ + + ] + ], + [ + "1", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ] + ], + [ + "2", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ] + ], + [ + "3", + [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "4", + [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + [ + "deepvariant_report", + [ + + ] + ], + [ + "gvcf", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ] + ], + [ + "gvcf_tabix", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_deepvar.g.vcf.gz.tbi:md5,1f7f65ca1a1b41bec29194966ca37228" + ] + ] + ], + [ + "tabix", + [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "vcf", + [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ] + ] + ], + "timestamp": "2026-05-29T18:32:43.797748048", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "CALL_SNV_DEEPVARIANT - wgs": { + "content": [ + "VcfFile [chromosomes=[MT, 21], sampleCount=1, variantCount=7601, phased=false, phasedAutodetect=false]", + [ + "earlycasualcaiman_deepvar.visual_report.html" + ], + [ + "justhusky_split_rmdup_info.vcf.gz.tbi" + ], + [ + "earlycasualcaiman_deepvar.g.vcf.gz" + ] + ], + "timestamp": "2026-05-29T20:33:43.828437561", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_snv_deepvariant/tests/nextflow.config b/subworkflows/local/call_snv_deepvariant/tests/nextflow.config new file mode 100644 index 000000000..28d487092 --- /dev/null +++ b/subworkflows/local/call_snv_deepvariant/tests/nextflow.config @@ -0,0 +1,12 @@ +process { + + withName: 'REMOVE_DUPLICATES_GL' { + ext.args = { params.bcftools_args } + ext.prefix = { "${meta.id}_split_rmdup" } + } + + withName: 'BCFTOOLS_ANNOTATE' { + ext.args = { params.bcftools_args } + ext.prefix = { "${meta.id}_split_rmdup_info" } + } +} diff --git a/subworkflows/local/call_snv_sentieon/main.nf b/subworkflows/local/call_snv_sentieon/main.nf index 6ff570097..15b0b5b78 100644 --- a/subworkflows/local/call_snv_sentieon/main.nf +++ b/subworkflows/local/call_snv_sentieon/main.nf @@ -2,39 +2,36 @@ // A subworkflow to call SNVs by sentieon dnascope with a machine learning model. // -include { SENTIEON_DNASCOPE } from '../../../modules/nf-core/sentieon/dnascope/main' -include { SENTIEON_DNAMODELAPPLY } from '../../../modules/nf-core/sentieon/dnamodelapply/main' -include { BCFTOOLS_MERGE } from '../../../modules/nf-core/bcftools/merge/main' -include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_SEN } from '../../../modules/nf-core/bcftools/norm/main' -include { BCFTOOLS_NORM as REMOVE_DUPLICATES_SEN } from '../../../modules/nf-core/bcftools/norm/main' -include { TABIX_TABIX as TABIX_SEN } from '../../../modules/nf-core/tabix/tabix/main' -include { BCFTOOLS_FILTER as BCF_FILTER_ONE } from '../../../modules/nf-core/bcftools/filter/main' -include { BCFTOOLS_FILTER as BCF_FILTER_TWO } from '../../../modules/nf-core/bcftools/filter/main' -include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' -include { TABIX_TABIX as TABIX_ANNOTATE } from '../../../modules/nf-core/tabix/tabix/main' -include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' +include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' +include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' +include { BCFTOOLS_FILTER as BCF_FILTER_ONE } from '../../../modules/nf-core/bcftools/filter/main' +include { BCFTOOLS_FILTER as BCF_FILTER_TWO } from '../../../modules/nf-core/bcftools/filter/main' +include { BCFTOOLS_MERGE } from '../../../modules/nf-core/bcftools/merge/main' +include { BCFTOOLS_NORM as REMOVE_DUPLICATES_SEN } from '../../../modules/nf-core/bcftools/norm/main' +include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_SEN } from '../../../modules/nf-core/bcftools/norm/main' +include { SENTIEON_DNAMODELAPPLY } from '../../../modules/nf-core/sentieon/dnamodelapply/main' +include { SENTIEON_DNASCOPE } from '../../../modules/nf-core/sentieon/dnascope/main' workflow CALL_SNV_SENTIEON { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_dbsnp // channel: [mandatory] [ val(meta), path(vcf) ] - ch_dbsnp_index // channel: [mandatory] [ val(meta), path(tbi) ] ch_call_interval // channel: [mandatory] [ val(meta), path(interval) ] - ch_ml_model // channel: [mandatory] [ val(meta), path(model) ] ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_pcr_indel_model // channel: [optional] [ val(sentieon_dnascope_pcr_indel_model) ] + ch_dbsnp // channel: [mandatory] [ val(meta), path(vcf) ] + ch_dbsnp_index // channel: [mandatory] [ val(meta), path(tbi) ] ch_foundin_header // channel: [mandatory] [ path(header) ] ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_ml_model // channel: [mandatory] [ val(meta), path(model) ] + ch_pcr_indel_model // channel: [optional] [ val(sentieon_dnascope_pcr_indel_model) ] + val_skip_split_multiallelics // boolean main: - ch_versions = Channel.empty() - // Combine bam and intervals bam_bai_intervals = ch_bam_bai.combine(ch_call_interval) .map{ - meta, bam, bai, meta2, interval -> [meta, bam, bai, interval] + meta, bam, bai, _meta2, interval -> [meta, bam, bai, interval] } SENTIEON_DNASCOPE( @@ -53,26 +50,29 @@ workflow CALL_SNV_SENTIEON { SENTIEON_DNAMODELAPPLY ( ch_dnamodelapply_in, ch_genome_fasta, ch_genome_fai, ch_ml_model ) - ch_bcffilterone_in = SENTIEON_DNAMODELAPPLY.out.vcf.join(SENTIEON_DNAMODELAPPLY.out.index, failOnMismatch: true) + ch_bcffilterone_in = SENTIEON_DNAMODELAPPLY.out.vcf.join(SENTIEON_DNAMODELAPPLY.out.tbi, failOnMismatch: true) BCF_FILTER_ONE (ch_bcffilterone_in) ch_bcffiltertwo_in = BCF_FILTER_ONE.out.vcf.join(BCF_FILTER_ONE.out.tbi, failOnMismatch: true) BCF_FILTER_TWO ( ch_bcffiltertwo_in ) BCF_FILTER_TWO.out.vcf.join(BCF_FILTER_TWO.out.tbi, failOnMismatch:true, failOnDuplicate:true) - .map { meta,vcf,tbi -> return [vcf,tbi] } + .map { _meta, vcf, tbi -> return [vcf, tbi] } .set { ch_vcf_idx } ch_case_info .combine(ch_vcf_idx) .groupTuple() - .branch{ // branch the channel into multiple channels (single, multiple) depending on size of list - single: it[1].size() == 1 - multiple: it[1].size() > 1 + .branch{ _meta, vcfs, _idx -> // branch the channel into multiple channels (single, multiple) depending on size of list + single: vcfs.size() == 1 + multiple: vcfs.size() > 1 } .set{ ch_vcf_idx_merge_in } - BCFTOOLS_MERGE(ch_vcf_idx_merge_in.multiple, ch_genome_fasta, ch_genome_fai, [[:],[]]) + BCFTOOLS_MERGE( + ch_vcf_idx_merge_in.multiple.map { meta, vcf, idx -> return [meta, vcf, idx, []] }, + ch_genome_fasta.join(ch_genome_fai, failOnMismatch:true, failOnDuplicate:true).collect() + ) ch_split_multi_in = BCFTOOLS_MERGE.out.vcf .map{meta, bcf -> @@ -80,50 +80,40 @@ workflow CALL_SNV_SENTIEON { ch_vcf_idx_case = ch_vcf_idx_merge_in.single.mix(ch_split_multi_in) - SPLIT_MULTIALLELICS_SEN(ch_vcf_idx_case, ch_genome_fasta) - - ch_remove_dup_in = SPLIT_MULTIALLELICS_SEN.out.vcf - .map{meta, vcf -> - return [meta, vcf, []]} + if (!val_skip_split_multiallelics) { + SPLIT_MULTIALLELICS_SEN(ch_vcf_idx_case, ch_genome_fasta) + ch_remove_dup_in = SPLIT_MULTIALLELICS_SEN.out.vcf + .map{meta, vcf -> + return [meta, vcf, []]} + } else { + ch_remove_dup_in = ch_vcf_idx_case + .map{meta, vcf, _idx -> + return [meta, vcf, []]} + } REMOVE_DUPLICATES_SEN(ch_remove_dup_in, ch_genome_fasta) - TABIX_SEN(REMOVE_DUPLICATES_SEN.out.vcf) - ch_genome_chrsizes.flatten().map{chromsizes -> return [[id:'sentieon_dnascope'], chromsizes] } .set { ch_varcallerinfo } ADD_VARCALLER_TO_BED (ch_varcallerinfo).gz_tbi - .map{meta,bed,tbi -> return [bed, tbi]} + .map{_meta, bed, tbi -> return [bed, tbi]} .set{ch_varcallerbed} REMOVE_DUPLICATES_SEN.out.vcf - .join(TABIX_SEN.out.tbi) + .join(REMOVE_DUPLICATES_SEN.out.tbi) .combine(ch_varcallerbed) + .combine(ch_foundin_header) + .map { meta, vcf, vcf_tbi, bed, bed_tbi, hdr -> return [meta, vcf, vcf_tbi, bed, bed_tbi, [], hdr, []] } .set { ch_annotate_in } - BCFTOOLS_ANNOTATE(ch_annotate_in, ch_foundin_header) - - TABIX_ANNOTATE(BCFTOOLS_ANNOTATE.out.vcf) - - ch_versions = ch_versions.mix(SENTIEON_DNASCOPE.out.versions.first()) - ch_versions = ch_versions.mix(SENTIEON_DNAMODELAPPLY.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_MERGE.out.versions.first()) - ch_versions = ch_versions.mix(SPLIT_MULTIALLELICS_SEN.out.versions.first()) - ch_versions = ch_versions.mix(REMOVE_DUPLICATES_SEN.out.versions.first()) - ch_versions = ch_versions.mix(TABIX_SEN.out.versions.first()) - ch_versions = ch_versions.mix(BCF_FILTER_ONE.out.versions.first()) - ch_versions = ch_versions.mix(BCF_FILTER_TWO.out.versions.first()) - ch_versions = ch_versions.mix(ADD_VARCALLER_TO_BED.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(TABIX_ANNOTATE.out.versions) + BCFTOOLS_ANNOTATE(ch_annotate_in) emit: - vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] - tabix = TABIX_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] gvcf = SENTIEON_DNASCOPE.out.gvcf // channel: [ val(meta), path(gvcf) ] gvcf_tbi = SENTIEON_DNASCOPE.out.gvcf_tbi // channel: [ val(meta), path(gvcf_tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] + tabix = BCFTOOLS_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] + vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_snv_sentieon/tests/main.nf.test b/subworkflows/local/call_snv_sentieon/tests/main.nf.test new file mode 100644 index 000000000..9011c759f --- /dev/null +++ b/subworkflows/local/call_snv_sentieon/tests/main.nf.test @@ -0,0 +1,96 @@ +nextflow_workflow { + + name "Test Workflow CALL_SNV_SENTIEON" + script "subworkflows/local/call_snv_sentieon/main.nf" + workflow "CALL_SNV_SENTIEON" + + tag "subworkflows" + tag "call_snv_sentieon" + + tag "sentieon/dnascope" + tag "sentieon/dnamodelapply" + tag "bcftools/merge" + tag "bcftools/norm" + tag "bcftools/filter" + tag "bcftools/annotate" + tag "add_varcallername_to_bed" + + config "./nextflow.config" + + test("CALL_SNV_SENTIEON - single sample, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([[id:'interval'], []]) + input[2] = channel.of([id:'justhusky']) + input[3] = channel.of([[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true)]) + input[4] = channel.of([[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true)]) + input[5] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[6] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[9] = channel.of([[id:'model'], []]) + input[10] = channel.value([]) + input[11] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("CALL_SNV_SENTIEON - two samples (merge), stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ], + [ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([[id:'interval'], []]) + input[2] = channel.of([id:'justhusky']) + input[3] = channel.of([[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true)]) + input[4] = channel.of([[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true)]) + input[5] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[6] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[9] = channel.of([[id:'model'], []]) + input[10] = channel.value([]) + input[11] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/call_snv_sentieon/tests/main.nf.test.snap b/subworkflows/local/call_snv_sentieon/tests/main.nf.test.snap new file mode 100644 index 000000000..7002614d1 --- /dev/null +++ b/subworkflows/local/call_snv_sentieon/tests/main.nf.test.snap @@ -0,0 +1,232 @@ +{ + "CALL_SNV_SENTIEON - two samples (merge), stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "gvcf": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tabix": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-10T14:40:02.625974988", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "CALL_SNV_SENTIEON - single sample, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "gvcf": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_dnascope.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tabix": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_split_rmdup_info.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-10T14:39:28.659577535", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_snv_sentieon/tests/nextflow.config b/subworkflows/local/call_snv_sentieon/tests/nextflow.config new file mode 100644 index 000000000..f13feedfc --- /dev/null +++ b/subworkflows/local/call_snv_sentieon/tests/nextflow.config @@ -0,0 +1,40 @@ +process { + + withName: 'SENTIEON_DNASCOPE' { + ext.prefix = { "${meta.id}_dnascope" } + } + + withName: 'SENTIEON_DNAMODELAPPLY' { + ext.prefix = { "${meta.id}_dnamodelapply" } + } + + withName: 'BCF_FILTER_ONE' { + ext.args = "-s 'ML_FAIL' -i 'INFO/ML_PROB <= 0.95' -m x --output-type z --write-index=tbi" + ext.prefix = { "${meta.id}_mlfiltered_0.95" } + } + + withName: 'BCF_FILTER_TWO' { + ext.args = "-i FILTER='\"PASS\"' -m x --output-type z --write-index=tbi" + ext.prefix = { "${meta.id}_passed" } + } + + withName: 'SPLIT_MULTIALLELICS_SEN' { + ext.args = '--output-type z --multiallelics -both' + ext.prefix = { "${meta.id}_split" } + } + + withName: 'REMOVE_DUPLICATES_SEN' { + ext.args = '--output-type z --rm-dup none --write-index=tbi' + ext.prefix = { "${meta.id}_split_rmdup" } + } + + withName: 'ADD_VARCALLER_TO_BED' { + ext.args2 = '-s 1 -b 2 -e 3' + } + + withName: 'BCFTOOLS_ANNOTATE' { + ext.args = '-c CHROM,FROM,TO,FOUND_IN --output-type z --write-index=tbi' + ext.prefix = { "${meta.id}_split_rmdup_info" } + } + +} diff --git a/subworkflows/local/call_structural_variants.nf b/subworkflows/local/call_structural_variants.nf deleted file mode 100644 index ae0a4ae71..000000000 --- a/subworkflows/local/call_structural_variants.nf +++ /dev/null @@ -1,119 +0,0 @@ -// -// A nested subworkflow to call structural variants. -// - -include { CALL_SV_MANTA } from './call_sv_manta' -include { CALL_SV_MT } from './call_sv_MT' -include { CALL_SV_TIDDIT } from './call_sv_tiddit' -include { SVDB_MERGE } from '../../modules/nf-core/svdb/merge/main' -include { CALL_SV_GERMLINECNVCALLER } from './call_sv_germlinecnvcaller' -include { CALL_SV_CNVNATOR } from './call_sv_cnvnator' -include { TABIX_TABIX } from '../../modules/nf-core/tabix/tabix/main' - -workflow CALL_STRUCTURAL_VARIANTS { - - take: - ch_genome_bam // channel: [mandatory] [ val(meta), path(bam) ] - ch_genome_bai // channel: [mandatory] [ val(meta), path(bai) ] - ch_genome_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_mtshift_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_bwa_index // channel: [mandatory] [ val(meta), path(index)] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_mtshift_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_target_bed // channel: [mandatory for WES] [ val(meta), path(bed), path(tbi) ] - ch_genome_dictionary // channel: [optional; used by mandatory for GATK's cnvcaller][ val(meta), path(dict) ] - ch_svcaller_priority // channel: [mandatory] [ val(["var caller tag 1", ...]) ] - ch_readcount_intervals // channel: [optional; used by mandatory for GATK's cnvcaller][ path(intervals) ] - ch_ploidy_model // channel: [optional; used by mandatory for GATK's cnvcaller][ path(ploidy_model) ] - ch_gcnvcaller_model // channel: [optional; used by mandatory for GATK's cnvcaller][ path(gcnvcaller_model) ] - - main: - ch_versions = Channel.empty() - ch_merged_svs = Channel.empty() - ch_merged_tbi = Channel.empty() - - if (!params.analysis_type.equals("mito")) { - CALL_SV_MANTA (ch_genome_bam, ch_genome_bai, ch_genome_fasta, ch_genome_fai, ch_case_info, ch_target_bed) - .filtered_diploid_sv_vcf_tbi - .collect{it[1]} - .set{ manta_vcf } - ch_versions = ch_versions.mix(CALL_SV_MANTA.out.versions) - } - - if (params.analysis_type.equals("wgs")) { - CALL_SV_TIDDIT (ch_genome_bam_bai, ch_genome_fasta, ch_bwa_index, ch_case_info) - .vcf - .collect{it[1]} - .set { tiddit_vcf } - ch_versions = ch_versions.mix(CALL_SV_TIDDIT.out.versions) - - CALL_SV_CNVNATOR (ch_genome_bam_bai, ch_genome_fasta, ch_genome_fai, ch_case_info) - .vcf - .collect{it[1]} - .set { cnvnator_vcf } - ch_versions = ch_versions.mix(CALL_SV_CNVNATOR.out.versions) - } - - if (!(params.skip_tools && params.skip_tools.split(',').contains('germlinecnvcaller'))) { - CALL_SV_GERMLINECNVCALLER (ch_genome_bam_bai, ch_genome_fasta, ch_genome_fai, ch_readcount_intervals, ch_genome_dictionary, ch_ploidy_model, ch_gcnvcaller_model, ch_case_info) - .genotyped_filtered_segments_vcf - .collect{it[1]} - .set { gcnvcaller_vcf } - - ch_versions = ch_versions.mix(CALL_SV_GERMLINECNVCALLER.out.versions) - } - - if (params.analysis_type.matches("wgs|mito") || params.run_mt_for_wes) { - CALL_SV_MT (ch_mt_bam_bai, ch_genome_fasta) - ch_versions = ch_versions.mix(CALL_SV_MT.out.versions) - } - - //merge - if (params.skip_tools && params.skip_tools.split(',').contains('germlinecnvcaller')) { - if (params.analysis_type.equals("wgs")) { - tiddit_vcf - .combine(manta_vcf) - .combine(cnvnator_vcf) - .toList() - .set { vcf_list } - } else if (!params.analysis_type.equals("mito")) { - manta_vcf - .toList() - .set { vcf_list } - } - } else if (params.analysis_type.equals("wgs")) { - tiddit_vcf - .combine(manta_vcf) - .combine(gcnvcaller_vcf) - .combine(cnvnator_vcf) - .toList() - .set { vcf_list } - } else if (!params.analysis_type.equals("mito")) { - manta_vcf - .combine(gcnvcaller_vcf) - .toList() - .set { vcf_list } - } - - if (!params.analysis_type.equals("mito")) { - ch_case_info - .combine(vcf_list) - .set { merge_input_vcfs } - - SVDB_MERGE (merge_input_vcfs, ch_svcaller_priority, true) - - TABIX_TABIX (SVDB_MERGE.out.vcf) - ch_merged_svs = SVDB_MERGE.out.vcf - ch_merged_tbi = TABIX_TABIX.out.tbi - ch_versions = ch_versions.mix(TABIX_TABIX.out.versions) - ch_versions = ch_versions.mix(SVDB_MERGE.out.versions) - } - - emit: - vcf = ch_merged_svs // channel: [ val(meta), path(vcf)] - tbi = ch_merged_tbi // channel: [ val(meta), path(tbi)] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/call_structural_variants/main.nf b/subworkflows/local/call_structural_variants/main.nf new file mode 100644 index 000000000..3551fc1c7 --- /dev/null +++ b/subworkflows/local/call_structural_variants/main.nf @@ -0,0 +1,163 @@ +// +// A nested subworkflow to call structural variants. +// + +include { CALL_SV_CNVNATOR } from '../call_sv_cnvnator' +include { CALL_SV_GERMLINECNVCALLER } from '../call_sv_germlinecnvcaller' +include { CALL_SV_MANTA } from '../call_sv_manta' +include { CALL_SV_MT } from '../call_sv_MT' +include { CALL_SV_TIDDIT } from '../call_sv_tiddit' +include { SVDB_MERGE } from '../../../modules/nf-core/svdb/merge/main' +include { TABIX_TABIX } from '../../../modules/nf-core/tabix/tabix/main' + +workflow CALL_STRUCTURAL_VARIANTS { + + take: + ch_bwa_index // channel: [mandatory] [ val(meta), path(index)] + ch_case_info // channel: [mandatory] [ val(case_info) ] + ch_gcnvcaller_model // channel: [optional; used by mandatory for GATK's cnvcaller][ path(gcnvcaller_model) ] + ch_genome_bai // channel: [mandatory] [ val(meta), path(bai) ] + ch_genome_bam // channel: [mandatory] [ val(meta), path(bam) ] + ch_genome_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_genome_dictionary // channel: [optional; used by mandatory for GATK's cnvcaller][ val(meta), path(dict) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_genome_hisat2index // channel: [mandatory] [ val(meta), path(hisat2index) ] + ch_manta_regions // channel: [mandatory] [ path(bed), path(tbi) ] + ch_mitosalt_config // channel: [mandatory] [val(mitosalt_breakspan),val(mitosalt_breakthreshold),...,val(mitosalt_split_length)] + ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_mt_fai // channel: [mandatory] [ val(meta), path(mtfai) ] + ch_mt_fasta // channel: [mandatory] [ val(meta), path(mtfasta) ] + ch_mt_lastdb // channel: [mandatory] [ val(meta), path(lastindex) ] + ch_ploidy_model // channel: [optional; used by mandatory for GATK's cnvcaller][ path(ploidy_model) ] + ch_readcount_intervals // channel: [optional; used by mandatory for GATK's cnvcaller][ path(intervals) ] + ch_reads // channel: [mandatory] [ val(meta), [path(reads)] ] + ch_sample_id_map // channel: [optional] [val(sample_id), val(customer_id)] + ch_subdepth // channel: [mandatory] [ val(mitosalt_depth) ] + ch_svcaller_priority // channel: [mandatory] [ val(["var caller tag 1", ...]) ] + skip_germlinecnvcaller // boolean + skip_mitosalt // boolean + val_analysis_type // string: "wes", "wgs", or "mito" + val_heavy_strand_origin_end // string: [mandatory] mitochondira_heavy_strand_origin_end + val_heavy_strand_origin_start // string: [mandatory] mitochondira_heavy_strand_origin_start + val_light_strand_origin_end // string: [mandatory] mitochondira_light_strand_origin_end + val_light_strand_origin_start // string: [mandatory] mitochondira_light_strand_origin_start + val_mitochondria_length // string: [mandatory] mito_length + val_mitochondria_name // string: [mandatory] mito_name + val_mitosalt_flank // string: [mandatory] mitosalt_flank + val_mitosalt_heteroplasmy_limit // string: [mandatory] mitosalt_heteroplasmy_limit + val_run_mt_for_wes // boolean: [mandatory] run_mt_for_wes + + main: + ch_cnvnator_vcf = channel.empty() + ch_gcnvcaller_vcf = channel.empty() + ch_manta_vcf = channel.empty() + ch_merged_svs = channel.empty() + ch_merged_tbi = channel.empty() + ch_mt_del_result = channel.empty() + ch_saltshaker_html = channel.empty() + ch_saltshaker_plot = channel.empty() + ch_saltshaker_vcf = channel.empty() + ch_tiddit_vcf = channel.empty() + + if (!val_analysis_type.equals("mito")) { + CALL_SV_MANTA (ch_genome_bam, ch_genome_bai, ch_genome_fasta, ch_genome_fai, ch_case_info, ch_manta_regions) + .filtered_diploid_sv_vcf + .collect{ _meta, vcf -> vcf } + .set{ ch_manta_vcf } + } + + if (val_analysis_type.equals("wgs")) { + CALL_SV_TIDDIT (ch_genome_bam_bai, ch_genome_fai, ch_genome_fasta, ch_bwa_index, ch_case_info) + .vcf + .collect{ _meta, vcf -> vcf } + .set { ch_tiddit_vcf } + + CALL_SV_CNVNATOR (ch_genome_bam_bai, ch_genome_fasta, ch_case_info) + .vcf + .collect{ _meta, vcf -> vcf } + .set { ch_cnvnator_vcf } + } + + if (!skip_germlinecnvcaller) { + CALL_SV_GERMLINECNVCALLER (ch_genome_bam_bai, ch_genome_fasta, ch_genome_fai, ch_readcount_intervals, ch_genome_dictionary, ch_ploidy_model, ch_gcnvcaller_model, ch_case_info) + .genotyped_filtered_segments_vcf + .collect{ _meta, vcf -> vcf } + .set { ch_gcnvcaller_vcf } + + } + + if (val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) { + CALL_SV_MT( + ch_mt_bam_bai, + ch_case_info, + ch_genome_chrsizes, + ch_genome_fai, + ch_genome_fasta, + ch_genome_hisat2index, + ch_mt_fai, + ch_mt_fasta, + ch_mt_lastdb, + ch_reads, + ch_sample_id_map, + ch_subdepth, + ch_svcaller_priority, + ch_mitosalt_config, + skip_mitosalt, + val_heavy_strand_origin_start, + val_heavy_strand_origin_end, + val_light_strand_origin_start, + val_light_strand_origin_end, + val_mitochondria_length, + val_mitochondria_name, + val_mitosalt_flank, + val_mitosalt_heteroplasmy_limit, + ) + .set { ch_sv_mt_out } + + ch_sv_mt_out.saltshaker_vcf + .collect{ _meta, vcf -> vcf } + .set { ch_saltshaker_vcf } + ch_saltshaker_html = ch_sv_mt_out.saltshaker_html + ch_saltshaker_plot = ch_sv_mt_out.saltshaker_plot + ch_mt_del_result = ch_sv_mt_out.mt_del_result + ch_svcaller_priority = ch_sv_mt_out.updated_priority + } + + // Merge - with consistent ordering using concat + if (!val_analysis_type.equals("mito")) { + // Concatenate in specific order: tiddit -> manta -> gcnvcaller -> cnvnator -> mitosalt + // Empty channels won't contribute any items + ch_tiddit_vcf + .concat(ch_manta_vcf) + .concat(ch_gcnvcaller_vcf) + .concat(ch_cnvnator_vcf) + .concat(ch_saltshaker_vcf) + .collect() + .map { vcf_list -> [vcf_list] } + .set { ch_vcf_paths } + ch_case_info + .combine(ch_vcf_paths) + .set { ch_merge_vcfs_in } + SVDB_MERGE (ch_merge_vcfs_in, ch_svcaller_priority, true) + + TABIX_TABIX (SVDB_MERGE.out.vcf) + ch_merged_svs = SVDB_MERGE.out.vcf + ch_merged_tbi = TABIX_TABIX.out.index + + } else { + // For mito-only analysis, use saltshaker_vcf with meta directly (ch_saltshaker_vcf + // holds collected paths only, ch_sv_mt_out.saltshaker_vcf holds [meta, vcf] tuples) + TABIX_TABIX (ch_sv_mt_out.saltshaker_vcf) + ch_merged_svs = ch_sv_mt_out.saltshaker_vcf + ch_merged_tbi = TABIX_TABIX.out.index + } + + emit: + mt_del_result = ch_mt_del_result // channel: [ val(meta), path(txt) ] + saltshaker_html = ch_saltshaker_html // channel: [ val(meta), path(html) ] + saltshaker_plot = ch_saltshaker_plot // channel: [ val(meta), path(png) ] + tbi = ch_merged_tbi // channel: [ val(meta), path(tbi)] + vcf = ch_merged_svs // channel: [ val(meta), path(vcf)] +} diff --git a/subworkflows/local/call_structural_variants/tests/main.nf.test b/subworkflows/local/call_structural_variants/tests/main.nf.test new file mode 100644 index 000000000..ee60aa4fe --- /dev/null +++ b/subworkflows/local/call_structural_variants/tests/main.nf.test @@ -0,0 +1,92 @@ +nextflow_workflow { + + name "Test Workflow CALL_STRUCTURAL_VARIANTS" + script "subworkflows/local/call_structural_variants/main.nf" + workflow "CALL_STRUCTURAL_VARIANTS" + + tag "subworkflows" + tag "call_structural_variants" + tag "call_sv_manta" + tag "call_sv_tiddit" + tag "call_sv_germlinecnvcaller" + tag "call_sv_cnvnator" + + tag "svdb/merge" + tag "tabix/tabix" + + test("CALL_STRUCTURAL_VARIANTS - wgs, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([[id:'bwa'], []]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of([[id:'gcnvcaller'], []]) + input[3] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[4] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true) + ]) + input[5] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[6] = channel.from(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)) + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[9] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[10] = Channel.from(System.getenv('PWD')).map { dir -> [[id:'genome'], file(dir)] } + input[11] = channel.value([[], []]) + input[12] = channel.of([15, 2, 5, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[13] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[14] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[15] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[16] = Channel.from("${projectDir}/subworkflows/local/variant_evaluation/tests").map { dir -> [[id:'mt'], file(dir)] } + input[17] = channel.of([[id:'ploidy'], []]) + input[18] = channel.of([[]]) + input[19] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ]) + input[20] = channel.empty() + input[21] = channel.value(10000000) + input[22] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[23] = true + input[24] = false + input[25] = 'wgs' + input[26] = 407 + input[27] = 16081 + input[28] = 5763 + input[29] = 5730 + input[30] = 16569 + input[31] = 'MT' + input[32] = 15 + input[33] = 0.01 + input[34] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_structural_variants/tests/main.nf.test.snap b/subworkflows/local/call_structural_variants/tests/main.nf.test.snap new file mode 100644 index 000000000..0e2924421 --- /dev/null +++ b/subworkflows/local/call_structural_variants/tests/main.nf.test.snap @@ -0,0 +1,129 @@ +{ + "CALL_STRUCTURAL_VARIANTS - wgs, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "justhusky" + }, + "justhusky_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "justhusky" + }, + "justhusky_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "mt_del_result": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_html": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_plot": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-26T14:04:04.593301052", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_MT/main.nf b/subworkflows/local/call_sv_MT/main.nf index 8ce67fec3..97512f9bc 100644 --- a/subworkflows/local/call_sv_MT/main.nf +++ b/subworkflows/local/call_sv_MT/main.nf @@ -1,36 +1,171 @@ // -// Call SV MT +// Calls SV MT, concatenates FASTQs per sample, then runs MitoSalt and SaltShaker. +// Also detects the number of discordant pairs using the mitodel script. // -include { MT_DELETION } from '../../../modules/local/mt_deletion_script' -include { EKLIPSE } from '../../../modules/nf-core/eklipse/main' +include { CAT_FASTQ } from '../../../modules/nf-core/cat/fastq/main' +include { MITOSALT } from '../../../modules/local/mitosalt/main' +include { MT_DELETION } from '../../../modules/local/mt_deletion_script' +include { PREP_MITOSALT } from '../../../modules/local/prep_mitosalt/main' +include { SALTSHAKER_CALL } from '../../../modules/nf-core/saltshaker/call/main' +include { SALTSHAKER_CLASSIFY } from '../../../modules/nf-core/saltshaker/classify/main' +include { SALTSHAKER_PLOT } from '../../../modules/nf-core/saltshaker/plot/main' +include { SALTSHAKER_TO_HTML } from '../../../modules/local/saltshaker_to_html/main' +include { SEQTK_SAMPLE } from '../../../modules/nf-core/seqtk/sample/main' +include { SVDB_MERGE } from '../../../modules/nf-core/svdb/merge/main' workflow CALL_SV_MT { take: - ch_bam_bai // channel: [mandatory] [ val(meta), path(bam) ] - ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_bam_bai // channel: [mandatory] [ val(meta), path(bam) ] + ch_case_info // channel: [mandatory] [ val(case_info) ] + ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(genomefai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_genome_hisat2index // channel: [mandatory] [ val(meta), path(hisat2index) ] + ch_mt_fai // channel: [mandatory] [ val(meta), path(mtfai) ] + ch_mt_fasta // channel: [mandatory] [ val(meta), path(mtfasta) ] + ch_mt_lastdb // channel: [mandatory] [ val(meta), path(lastindex) ] + ch_reads // channel: [mandatory] [ val(meta), [path(reads)] ] + ch_sample_id_map // channel: [optional] [ val(sample_id), val(customer_id) ] + ch_subdepth // channel: [mandatory] [ val(mitosalt_depth) ] + ch_svcaller_priority // channel: [mandatory] [ val(["var caller tag 1", ...]) ] + ch_mitosalt_config // channel: [mandatory] [val(mitosalt_breakspan),val(mitosalt_breakthreshold),...,val(mitosalt_split_length)] + skip_mitosalt // Boolean + val_heavy_strand_origin_start // string: [mandatory] mitochondira_heavy_strand_origin_start + val_heavy_strand_origin_end // string: [mandatory] mitochondira_heavy_strand_origin_end + val_light_strand_origin_start // string: [mandatory] mitochondira_light_strand_origin_start + val_light_strand_origin_end // string: [mandatory] mitochondira_light_strand_origin_end + val_mitochondria_length // string: [mandatory] mito_length + val_mitochondria_name // string: [mandatory] mito_name + val_mitosalt_flank // string: [mandatory] mitosalt_flank + val_mitosalt_heteroplasmy_limit // string: [mandatory] mitosalt_heteroplasmy_limit main: - ch_versions = Channel.empty() - ch_eklipse_del = Channel.empty() - ch_eklipse_genes = Channel.empty() - ch_eklipse_circos = Channel.empty() - - if (!(params.skip_tools && params.skip_tools.split(',').contains('eklipse'))) { - EKLIPSE(ch_bam_bai,[]) - ch_eklipse_del = EKLIPSE.out.deletions - ch_eklipse_genes = EKLIPSE.out.genes - ch_eklipse_circos = EKLIPSE.out.circos - ch_versions = ch_versions.mix(EKLIPSE.out.versions.first()) + ch_saltshaker_html = channel.empty() + ch_saltshaker_vcf = channel.empty() + ch_saltshaker_plot = channel.empty() + + if (!skip_mitosalt) { + ch_reads + .map { meta, reads -> + def sample_group_key = meta.sample + return [sample_group_key, meta, reads] + } + .groupTuple() + .map { sample_id, meta_list, reads_list -> + def combined_meta = meta_list[0].clone() + combined_meta.id = sample_id + combined_meta.remove('lane') + combined_meta.remove('read_group') + + def all_reads = reads_list.flatten() + + [combined_meta, all_reads] + } + .set { ch_cat_fastq } + + CAT_FASTQ(ch_cat_fastq) + + ch_reads_subdepth = CAT_FASTQ.out.reads.combine(ch_subdepth) + + SEQTK_SAMPLE(ch_reads_subdepth) + + PREP_MITOSALT( + ch_genome_chrsizes, + ch_genome_fai, + ch_genome_hisat2index, + ch_mitosalt_config, + ch_mt_fai, + ch_mt_fasta, + ch_mt_lastdb, + val_mitosalt_flank, + val_mitosalt_heteroplasmy_limit, + val_mitochondria_name + ) + + ch_prepmitosalt_config = PREP_MITOSALT.out.msconfig.collect() + MITOSALT( + SEQTK_SAMPLE.out.reads, + ch_prepmitosalt_config, + ch_genome_chrsizes, + ch_genome_fai, + ch_genome_hisat2index, + ch_mt_fai, + ch_mt_fasta, + ch_mt_lastdb + ) + + MITOSALT.out.breakpoint + .join(MITOSALT.out.cluster) + .set { ch_saltshaker_in } + + SALTSHAKER_CALL( + ch_saltshaker_in, + ch_mt_fasta, + val_mitosalt_flank, + val_mitosalt_heteroplasmy_limit, + val_mitochondria_length, + val_heavy_strand_origin_start, + val_heavy_strand_origin_end, + val_light_strand_origin_start, + val_light_strand_origin_end + ) + + SALTSHAKER_CLASSIFY( + SALTSHAKER_CALL.out.call, + val_mitochondria_name + ) + + // Create case-level channel ch_saltshaker_html_input, consisting of all saltshaker txt reports and all + // customer IDs (or sample ID if no customer ID) so individual reports have identifers in the final HTML. + SALTSHAKER_CLASSIFY.out.txt + .map { meta, txt -> [['id':meta.sample], meta.case_id, txt] } + .join(ch_sample_id_map, remainder: true, failOnDuplicate: true) + .map { sample_meta, case_id, txt, cust_id -> + cust_id ? [['id':case_id], txt, cust_id] : [['id':case_id], txt, sample_meta.id] + } + .groupTuple() + .set { ch_saltshaker_html_input } + + SALTSHAKER_TO_HTML( + ch_saltshaker_html_input + ) + ch_saltshaker_html = SALTSHAKER_TO_HTML.out.classify_html + + SALTSHAKER_PLOT( + SALTSHAKER_CLASSIFY.out.classify + ) + ch_saltshaker_plot = SALTSHAKER_PLOT.out.plot + + // Only merge if Saltshaker produced VCFs; filter on the flat list before wrapping so + // combine never sees an empty-spread issue (combining case_info with [[]] would produce + // a 1-element channel item that breaks 2-param destructuring closures downstream). + SALTSHAKER_CLASSIFY.out.vcf + .collect { _meta, vcf -> vcf } + .filter { !it.isEmpty() } + .map { vcf_list -> [vcf_list] } + .set { ch_vcf_file_list } + + ch_case_info + .combine(ch_vcf_file_list) + .set { ch_merge_input_vcfs } + + SVDB_MERGE( ch_merge_input_vcfs, [], true ).vcf + .set {ch_saltshaker_vcf} + // Saltshaker only runs if there are mitosalt calls. We update priority list when the + // saltshaker vcf is created so the priority matches the list of vcfs that will be merged later + ch_svcaller_priority = ch_svcaller_priority + .concat(ch_saltshaker_vcf.map{ _it -> ["mitosalt"] }) + .collect() + } - MT_DELETION(ch_bam_bai, ch_fasta) + MT_DELETION(ch_bam_bai, ch_genome_fasta) - ch_versions = ch_versions.mix(MT_DELETION.out.versions.first()) emit: - eklipse_del = ch_eklipse_del // channel: [ val(meta), path(csv) ] - eklipse_genes = ch_eklipse_genes // channel: [ val(meta), path(csv) ] - eklipse_circos = ch_eklipse_circos // channel: [ val(meta), path(png) ] - mt_del_result = MT_DELETION.out.mt_del_result // channel: [ val(meta), path(txt) ] - versions = ch_versions // channel: [ path(versions.yml) ] + saltshaker_vcf = ch_saltshaker_vcf // channel: [ val(meta), path(vcf) ] + saltshaker_html = ch_saltshaker_html // channel: [ val(meta), path(html) ] + saltshaker_plot = ch_saltshaker_plot // channel: [ val(meta), path(png) ] + mt_del_result = MT_DELETION.out.mt_del_result // channel: [ val(meta), path(txt) ] + updated_priority = ch_svcaller_priority // channel: [ val(["caller1", "caller2", ...]) ] - includes "mitosalt" if it ran } diff --git a/subworkflows/local/call_sv_MT/tests/main.nf.test b/subworkflows/local/call_sv_MT/tests/main.nf.test new file mode 100644 index 000000000..1f32a3123 --- /dev/null +++ b/subworkflows/local/call_sv_MT/tests/main.nf.test @@ -0,0 +1,436 @@ +nextflow_workflow { + + name "Test Workflow CALL_SV_MT" + script "subworkflows/local/call_sv_MT/main.nf" + workflow "CALL_SV_MT" + + tag "subworkflows" + tag "call_sv_mt" + + tag "mt_deletion_script" + tag "prep_mitosalt" + tag "mitosalt" + tag "seqtk/sample" + + config "./nextflow.config" + + setup { + run("HISAT2_BUILD") { + script "../../../../modules/nf-core/hisat2/build/main.nf" + config "./nextflow.config" + process { + """ + input[0] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]) + input[1] = [[:],[]] + input[2] = [[:],[]] + """ + } + } + + run("LAST_LASTDB") { + script "../../../../modules/nf-core/last/lastdb/main.nf" + config "./nextflow.config" + process { + """ + input[0] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]) + """ + } + } + } + + test("CALL_SV_MT - 1 sample") { + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = HISAT2_BUILD.out.index.collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = LAST_LASTDB.out.index.collect() + input[9] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ]) + input[10] = channel.of([[id:'earlycasualcaiman'], 'cust_ecc']) + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.saltshaker_vcf.get(0).get(1)).vcf.variantsMD5, + workflow.out.saltshaker_html, + file(workflow.out.saltshaker_plot.get(0).get(1)).name, // pngs are unstable so we just check that the name matches + workflow.out.mt_del_result, + workflow.out.updated_priority + ).match() } + ) + } + } + + test("CALL_SV_MT - 1 sample - no sample map") { + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = HISAT2_BUILD.out.index.collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = LAST_LASTDB.out.index.collect() + input[9] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ]) + input[10] = channel.empty() + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.saltshaker_vcf.get(0).get(1)).vcf.variantsMD5, + workflow.out.saltshaker_html, + file(workflow.out.saltshaker_plot.get(0).get(1)).name, // pngs are unstable so we just check that the name matches + workflow.out.mt_del_result, + workflow.out.updated_priority + ).match() } + ) + } + } + + test("CALL_SV_MT - 2 samples") { + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = HISAT2_BUILD.out.index.collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = LAST_LASTDB.out.index.collect() + input[9] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true) + ] + ] + ) + input[10] = channel.of([[id:'earlycasualcaiman'], 'cust_ecc'], [[id:'hugelymodelbat'], 'cust_hmb']) + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.saltshaker_vcf.get(0).get(1)).vcf.variantsMD5, + workflow.out.saltshaker_html, + file(workflow.out.saltshaker_plot.get(0).get(1)).name, // pngs are unstable so we just check that the name matches + workflow.out.mt_del_result, + workflow.out.updated_priority + ).match() } + ) + } + } + + test("CALL_SV_MT - 1 sample - stub") { + + options "-stub" + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = channel.of([[id:'mt'], file("${projectDir}/subworkflows/local/variant_evaluation/tests")]).collect() + input[9] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true) + ] + ] + ) + input[10] = channel.of([[id:'earlycasualcaiman'], 'cust_ecc']) + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } + + test("CALL_SV_MT - 1 sample - no sample map - stub") { + + options "-stub" + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = HISAT2_BUILD.out.index.collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = LAST_LASTDB.out.index.collect() + input[9] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ]) + input[10] = channel.empty() + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } + + test("CALL_SV_MT - 2 samples - stub") { + + options "-stub" + + when { + params { + mt_del = "-s --insert-size 16000" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([id:'justhusky']) + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[5] = HISAT2_BUILD.out.index.collect() + input[6] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa.fai', checkIfExists: true)]).collect() + input[7] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference_mt.fa', checkIfExists: true)]).collect() + input[8] = LAST_LASTDB.out.index.collect() + input[9] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_mt_2.fastq.gz', checkIfExists: true) + ] + ], + [ + [id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [ + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_1.fastq.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_mt_2.fastq.gz', checkIfExists: true) + ] + ] + ) + input[10] = channel.of([[id:'earlycasualcaiman'], 'cust_ecc'], [[id:'hugelymodelbat'], 'cust_hmb']) + input[11] = channel.value(10000000) + input[12] = channel.value(['manta', 'tiddit', 'cnvnator']) + input[13] = channel.of([15, 2, 2, 30000, 30, 0.00001, 5, 1000, 80, 10000, 5, 15]) + input[14] = false + input[15] = 16081 + input[16] = 407 + input[17] = 5730 + input[18] = 5763 + input[19] = 16569 + input[20] = 'chrM' + input[21] = 15 + input[22] = 0.01 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_sv_MT/tests/main.nf.test.snap b/subworkflows/local/call_sv_MT/tests/main.nf.test.snap new file mode 100644 index 000000000..3b742cad6 --- /dev/null +++ b/subworkflows/local/call_sv_MT/tests/main.nf.test.snap @@ -0,0 +1,654 @@ +{ + "CALL_SV_MT - 2 samples": { + "content": [ + "77d88012f833253be9666bb792c60aee", + [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d3e9be4deac01d3a53937edca7238709" + ] + ], + "earlycasualcaiman.saltshaker.png", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,43ed4cf81974ace8ec3085340d56a294" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat_mitochondria_deletions.txt:md5,186bf9bc3fc8d20a6e0e6b5207a20673" + ] + ], + [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + ], + "timestamp": "2026-06-26T14:11:01.187532567", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "CALL_SV_MT - 2 samples - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ], + "mt_del_result": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_html": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_plot": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "updated_priority": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + } + ], + "timestamp": "2026-06-23T12:43:15.024082", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "CALL_SV_MT - 1 sample - no sample map - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ], + "mt_del_result": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_html": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_plot": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "updated_priority": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + } + ], + "timestamp": "2026-06-23T12:53:00.309943", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "CALL_SV_MT - 1 sample - no sample map": { + "content": [ + "619fc9380aac6cccd9d3f4d1df17a0ed", + [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,3731f46a7d81fb5f43498eef28f46856" + ] + ], + "earlycasualcaiman.saltshaker.png", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,43ed4cf81974ace8ec3085340d56a294" + ] + ], + [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + ], + "timestamp": "2026-06-23T12:39:18.333366", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "CALL_SV_MT - 1 sample - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ], + "mt_del_result": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:hugelymodelbat\\tPL:illumina\\tSM:hugelymodelbat'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_html": [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_plot": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "hugelymodelbat", + "sample": "hugelymodelbat", + "single_end": false, + "num_lanes": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "hugelymodelbat.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "saltshaker_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_saltshaker.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "updated_priority": [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + } + ], + "timestamp": "2026-06-23T12:42:09.390542", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "CALL_SV_MT - 1 sample": { + "content": [ + "619fc9380aac6cccd9d3f4d1df17a0ed", + [ + [ + { + "id": "justhusky" + }, + "justhusky.saltshaker_classify.html:md5,1999c31d1c6880fc5f3021397f2111d3" + ] + ], + "earlycasualcaiman.saltshaker.png", + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mitochondria_deletions.txt:md5,43ed4cf81974ace8ec3085340d56a294" + ] + ], + [ + [ + "manta", + "tiddit", + "cnvnator", + "mitosalt" + ] + ] + ], + "timestamp": "2026-06-26T14:08:06.381190074", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_MT/tests/nextflow.config b/subworkflows/local/call_sv_MT/tests/nextflow.config new file mode 100644 index 000000000..d0a2a2e68 --- /dev/null +++ b/subworkflows/local/call_sv_MT/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + + withName: 'MT_DELETION' { + ext.args = { params.mt_del } + ext.prefix = { "${meta.id}_mitochondria_deletions" } + } + +} diff --git a/subworkflows/local/call_sv_cnvnator/main.nf b/subworkflows/local/call_sv_cnvnator/main.nf index dbf13db52..20db0edca 100644 --- a/subworkflows/local/call_sv_cnvnator/main.nf +++ b/subworkflows/local/call_sv_cnvnator/main.nf @@ -2,35 +2,35 @@ // A subworkflow to call CNVs using cnvnator // -include { CNVNATOR_CNVNATOR as CNVNATOR_RD } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' +include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_CNVNATOR } from '../../../modules/nf-core/bcftools/view/main.nf' +include { CNVNATOR_CNVNATOR as CNVNATOR_CALL } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' include { CNVNATOR_CNVNATOR as CNVNATOR_HIST } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' -include { CNVNATOR_CNVNATOR as CNVNATOR_STAT } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' include { CNVNATOR_CNVNATOR as CNVNATOR_PARTITION } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' -include { CNVNATOR_CNVNATOR as CNVNATOR_CALL } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' +include { CNVNATOR_CNVNATOR as CNVNATOR_RD } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' +include { CNVNATOR_CNVNATOR as CNVNATOR_STAT } from '../../../modules/nf-core/cnvnator/cnvnator/main.nf' include { CNVNATOR_CONVERT2VCF } from '../../../modules/nf-core/cnvnator/convert2vcf/main.nf' -include { TABIX_BGZIPTABIX as INDEX_CNVNATOR } from '../../../modules/nf-core/tabix/bgziptabix/main' -include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_CNVNATOR } from '../../../modules/nf-core/bcftools/view/main.nf' +include { SPLIT_CHR } from '../../../modules/local/split_chr/main.nf' include { SVDB_MERGE as SVDB_MERGE_CNVNATOR } from '../../../modules/nf-core/svdb/merge/main' +include { TABIX_BGZIPTABIX as INDEX_CNVNATOR } from '../../../modules/nf-core/tabix/bgziptabix/main' workflow CALL_SV_CNVNATOR { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] ch_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_fai // channel: [mandatory] [ val(meta), path(fai) ] ch_case_info // channel: [mandatory] [ val(case_info) ] main: - ch_versions = Channel.empty() + SPLIT_CHR (ch_fasta) CNVNATOR_RD ( ch_bam_bai, [[:],[]], [[:],[]], [[:],[]], "rd" ) - CNVNATOR_HIST ( [[:],[],[]], CNVNATOR_RD.out.root, ch_fasta, ch_fai, "his" ) + CNVNATOR_HIST ( [[:],[],[]], CNVNATOR_RD.out.root, SPLIT_CHR.out.output, [[:],[]], "his" ) CNVNATOR_STAT ( [[:],[],[]], CNVNATOR_HIST.out.root, [[:],[]], [[:],[]], "stat" ) CNVNATOR_PARTITION ( [[:],[],[]], CNVNATOR_STAT.out.root, [[:],[]], [[:],[]], "partition" ) CNVNATOR_CALL ( [[:],[],[]], CNVNATOR_PARTITION.out.root, [[:],[]], [[:],[]], "call" ) CNVNATOR_CONVERT2VCF (CNVNATOR_CALL.out.tab) INDEX_CNVNATOR (CNVNATOR_CONVERT2VCF.out.vcf) - BCFTOOLS_VIEW_CNVNATOR (INDEX_CNVNATOR.out.gz_tbi, [], [], []).vcf - .collect{it[1]} + BCFTOOLS_VIEW_CNVNATOR (INDEX_CNVNATOR.out.gz_index, [], [], []).vcf + .collect{_meta, vcf -> vcf} .toList() .set { vcf_file_list } @@ -40,17 +40,6 @@ workflow CALL_SV_CNVNATOR { SVDB_MERGE_CNVNATOR ( merge_input_vcfs, [], true ) - ch_versions = ch_versions.mix(CNVNATOR_RD.out.versions) - ch_versions = ch_versions.mix(CNVNATOR_HIST.out.versions) - ch_versions = ch_versions.mix(CNVNATOR_STAT.out.versions) - ch_versions = ch_versions.mix(CNVNATOR_PARTITION.out.versions) - ch_versions = ch_versions.mix(CNVNATOR_CALL.out.versions) - ch_versions = ch_versions.mix(CNVNATOR_CONVERT2VCF.out.versions) - ch_versions = ch_versions.mix(SVDB_MERGE_CNVNATOR.out.versions) - ch_versions = ch_versions.mix(INDEX_CNVNATOR.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW_CNVNATOR.out.versions) - emit: vcf = SVDB_MERGE_CNVNATOR.out.vcf // channel: [ val(meta), path(*.tar.gz) ] - versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/local/call_sv_cnvnator/tests/main.nf.test b/subworkflows/local/call_sv_cnvnator/tests/main.nf.test new file mode 100644 index 000000000..aae06a47f --- /dev/null +++ b/subworkflows/local/call_sv_cnvnator/tests/main.nf.test @@ -0,0 +1,77 @@ +nextflow_workflow { + + name "Test Workflow CALL_SV_CNVNATOR" + script "subworkflows/local/call_sv_cnvnator/main.nf" + workflow "CALL_SV_CNVNATOR" + + tag "subworkflows" + tag "call_sv_cnvnator" + + tag "cnvnator/cnvnator" + tag "cnvnator/convert2vcf" + tag "tabix/bgziptabix" + tag "bcftools/view" + tag "svdb/merge" + + config "./nextflow.config" + + test("CALL_SV_CNVNATOR") { + + when { + params { + cnvnator_binsize = "10000" + } + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[2] = channel.of([id:'justhusky']) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf.collect { meta, vcf -> file(vcf).name } + ).match() } + ) + } + } + + test("CALL_SV_CNVNATOR -stub") { + + options "-stub" + + when { + params { + cnvnator_binsize = "10000" + } + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[2] = channel.of([id:'justhusky']) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf.collect { meta, vcf -> file(vcf).name } + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_sv_cnvnator/tests/main.nf.test.snap b/subworkflows/local/call_sv_cnvnator/tests/main.nf.test.snap new file mode 100644 index 000000000..8f70996f8 --- /dev/null +++ b/subworkflows/local/call_sv_cnvnator/tests/main.nf.test.snap @@ -0,0 +1,26 @@ +{ + "CALL_SV_CNVNATOR -stub": { + "content": [ + [ + "justhusky_cnvnator.vcf.gz" + ] + ], + "timestamp": "2026-03-04T17:14:53.940820631", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "CALL_SV_CNVNATOR": { + "content": [ + [ + "justhusky_cnvnator.vcf.gz" + ] + ], + "timestamp": "2026-03-01T20:36:50.087101237", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_cnvnator/tests/nextflow.config b/subworkflows/local/call_sv_cnvnator/tests/nextflow.config new file mode 100644 index 000000000..e919f3438 --- /dev/null +++ b/subworkflows/local/call_sv_cnvnator/tests/nextflow.config @@ -0,0 +1,37 @@ +process { + + withName: "CNVNATOR_HIST" { + tag = { "$meta2.id" } + ext.args = { "-his ${params.cnvnator_binsize}" } + } + + withName: "CNVNATOR_STAT" { + tag = { "$meta2.id" } + ext.args = { "-stat ${params.cnvnator_binsize}" } + } + + withName: "CNVNATOR_PARTITION" { + tag = { "$meta2.id" } + ext.args = { "-partition ${params.cnvnator_binsize}" } + } + + withName: "CNVNATOR_CALL" { + tag = { "$meta2.id" } + ext.args = { "-call ${params.cnvnator_binsize}" } + } + + withName: "CNVNATOR_CONVERT2VCF" { + ext.prefix = { "${meta.id}_cnvnator" } + ext.args = { "-call ${params.cnvnator_binsize}" } + } + + withName: "BCFTOOLS_VIEW_CNVNATOR" { + ext.prefix = { "${meta.id}_cnvnator_filter" } + ext.args = { '--apply-filters .,PASS --output-type z' } + } + + withName: 'SVDB_MERGE_CNVNATOR' { + ext.args = '--notag --pass_only' + ext.prefix = { "${meta.id}_cnvnator" } + } +} diff --git a/subworkflows/local/call_sv_germlinecnvcaller/main.nf b/subworkflows/local/call_sv_germlinecnvcaller/main.nf index 262737f5d..46eb00212 100644 --- a/subworkflows/local/call_sv_germlinecnvcaller/main.nf +++ b/subworkflows/local/call_sv_germlinecnvcaller/main.nf @@ -2,13 +2,13 @@ // A variant caller workflow for GATK's GermlinceCNVCaller // +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' include { GATK4_COLLECTREADCOUNTS } from '../../../modules/nf-core/gatk4/collectreadcounts/main.nf' include { GATK4_DETERMINEGERMLINECONTIGPLOIDY } from '../../../modules/nf-core/gatk4/determinegermlinecontigploidy/main.nf' include { GATK4_GERMLINECNVCALLER } from '../../../modules/nf-core/gatk4/germlinecnvcaller/main.nf' include { GATK4_POSTPROCESSGERMLINECNVCALLS } from '../../../modules/nf-core/gatk4/postprocessgermlinecnvcalls/main.nf' -include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view/main' -include { TABIX_TABIX } from '../../../modules/nf-core/tabix/tabix/main' include { SVDB_MERGE as SVDB_MERGE_GCNVCALLER } from '../../../modules/nf-core/svdb/merge/main' +include { TABIX_TABIX } from '../../../modules/nf-core/tabix/tabix/main' workflow CALL_SV_GERMLINECNVCALLER { take: @@ -22,7 +22,6 @@ workflow CALL_SV_GERMLINECNVCALLER { ch_case_info // channel: [mandatory] [ val(case_info) ] main: - ch_versions = Channel.empty() input = ch_bam_bai.combine( ch_readcount_intervals ) @@ -37,7 +36,7 @@ workflow CALL_SV_GERMLINECNVCALLER { GATK4_COLLECTREADCOUNTS.out.tsv .join(GATK4_DETERMINEGERMLINECONTIGPLOIDY.out.calls) .combine(ch_gcnvcaller_model) - .map({ meta, tsv, calls, meta2, model -> return [meta, tsv, [], calls, model ]}) + .map({ meta, tsv, calls, _meta2, model -> return [meta, tsv, [], calls, model ]}) .set{ch_gcnvc_in} GATK4_GERMLINECNVCALLER ( ch_gcnvc_in ) @@ -47,12 +46,12 @@ workflow CALL_SV_GERMLINECNVCALLER { return [meta.sample, meta, model_calls] } .groupTuple(by: 0) - .map { sample, metas, model_calls -> + .map { _sample, metas, model_calls -> def meta = metas[0] // All metas should be the same for a given sample - def models = model_calls.collect { it.toString() } + def models = model_calls.collect { file -> file.toString() } return [meta, models] } - .combine(ch_gcnvcaller_model.collect{it[1]}.toList()) + .combine(ch_gcnvcaller_model.collect{_meta, model -> model}.toList()) .join(GATK4_DETERMINEGERMLINECONTIGPLOIDY.out.calls) .set {ch_postproc_in} @@ -60,13 +59,13 @@ workflow CALL_SV_GERMLINECNVCALLER { TABIX_TABIX(GATK4_POSTPROCESSGERMLINECNVCALLS.out.segments) GATK4_POSTPROCESSGERMLINECNVCALLS.out.segments - .join(TABIX_TABIX.out.tbi, failOnMismatch:true) + .join(TABIX_TABIX.out.index, failOnMismatch:true) .set {ch_segments_in} // Filter out reference only (0/0) segments BCFTOOLS_VIEW (ch_segments_in , [], [], [] ) BCFTOOLS_VIEW.out.vcf - .collect{it[1]} + .collect{_meta, vcf -> vcf} .toList() .set { vcf_file_list } @@ -76,18 +75,9 @@ workflow CALL_SV_GERMLINECNVCALLER { SVDB_MERGE_GCNVCALLER ( merge_input_vcfs, [], true ) - ch_versions = ch_versions.mix(GATK4_COLLECTREADCOUNTS.out.versions) - ch_versions = ch_versions.mix(GATK4_DETERMINEGERMLINECONTIGPLOIDY.out.versions) - ch_versions = ch_versions.mix(GATK4_GERMLINECNVCALLER.out.versions) - ch_versions = ch_versions.mix(GATK4_POSTPROCESSGERMLINECNVCALLS.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions) - ch_versions = ch_versions.mix(SVDB_MERGE_GCNVCALLER.out.versions) - emit: genotyped_intervals_vcf = GATK4_POSTPROCESSGERMLINECNVCALLS.out.intervals // channel: [ val(meta), path(*.vcf.gz) ] genotyped_segments_vcf = GATK4_POSTPROCESSGERMLINECNVCALLS.out.segments // channel: [ val(meta), path(*.vcf.gz) ] genotyped_filtered_segments_vcf = SVDB_MERGE_GCNVCALLER.out.vcf // channel: [ val(meta), path(*.vcf.gz) ] denoised_vcf = GATK4_POSTPROCESSGERMLINECNVCALLS.out.denoised // channel: [ val(meta), path(*.vcf.gz) ] - versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test b/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test new file mode 100644 index 000000000..6a37ee5d3 --- /dev/null +++ b/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test @@ -0,0 +1,52 @@ +nextflow_workflow { + + name "Test Workflow CALL_SV_GERMLINECNVCALLER" + script "subworkflows/local/call_sv_germlinecnvcaller/main.nf" + workflow "CALL_SV_GERMLINECNVCALLER" + + tag "subworkflows" + tag "call_sv_germlinecnvcaller" + + tag "gatk4/collectreadcounts" + tag "gatk4/determinegermlinecontigploidy" + tag "gatk4/germlinecnvcaller" + tag "gatk4/postprocessgermlinecnvcalls" + tag "bcftools/view" + tag "tabix/tabix" + tag "svdb/merge" + + config "./nextflow.config" + + test("CALL_SV_GERMLINECNVCALLER - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[3] = channel.of(file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease/reference/target.interval_list', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[5] = channel.of([[id:'ploidy'], []]) + input[6] = channel.of([[id:'gcnvcaller'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)])//Just a placeholder + input[7] = channel.of([id:'justhusky']) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.genotyped_filtered_segments_vcf.collect { meta, vcf -> file(vcf).name } + ).match() } + ) + } + } +} diff --git a/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test.snap b/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test.snap new file mode 100644 index 000000000..9ff12a7d4 --- /dev/null +++ b/subworkflows/local/call_sv_germlinecnvcaller/tests/main.nf.test.snap @@ -0,0 +1,14 @@ +{ + "CALL_SV_GERMLINECNVCALLER - stub": { + "content": [ + [ + "justhusky_gcnvcaller.vcf.gz" + ] + ], + "timestamp": "2026-03-01T22:17:21.509267479", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_germlinecnvcaller/tests/nextflow.config b/subworkflows/local/call_sv_germlinecnvcaller/tests/nextflow.config new file mode 100644 index 000000000..d09f408c3 --- /dev/null +++ b/subworkflows/local/call_sv_germlinecnvcaller/tests/nextflow.config @@ -0,0 +1,23 @@ + +process { + + withName: "GATK4_COLLECTREADCOUNTS" { + ext.args = "--format TSV" + } + + withName: "GATK4_DETERMINEGERMLINECONTIGPLOIDY" { + ext.prefix = { "${meta.id}_ploidy" } + } + + withName: "GATK4_GERMLINECNVCALLER" { + ext.args = "--run-mode CASE" + } + + withName: 'BCFTOOLS_VIEW' { + ext.prefix = { "${meta.id}_gatkcnv_segments_refiltered" } + } + + withName: 'SVDB_MERGE_GCNVCALLER' { + ext.prefix = { "${meta.id}_gcnvcaller" } + } +} diff --git a/subworkflows/local/call_sv_manta/main.nf b/subworkflows/local/call_sv_manta/main.nf index 816b4fa3a..2c01d251f 100644 --- a/subworkflows/local/call_sv_manta/main.nf +++ b/subworkflows/local/call_sv_manta/main.nf @@ -2,8 +2,8 @@ // A structural variant caller workflow for manta // -include { MANTA_GERMLINE as MANTA } from '../../../modules/nf-core/manta/germline/main' include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_MANTA } from '../../../modules/nf-core/bcftools/view/main.nf' +include { MANTA_GERMLINE as MANTA } from '../../../modules/nf-core/manta/germline/main' workflow CALL_SV_MANTA { take: @@ -12,44 +12,30 @@ workflow CALL_SV_MANTA { ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_bed // channel: [mandatory for WES] [ val(meta), path(bed), path(tbi) ] + ch_regions // channel: [mandatory] [ path(bed), path(tbi) ] main: - ch_bam.collect{it[1]} + ch_bam.map{ _meta, bam -> bam } + .collect(sort: { a, b -> a.getName() <=> b.getName() }) .toList() .set { bam_file_list } - ch_bai.collect{it[1]} + ch_bai.map{ _meta, bai -> bai } + .collect(sort: { a, b -> a.getName() <=> b.getName() }) .toList() .set { bai_file_list } - ch_bed.map { - id, bed_file, index -> - return [bed_file, index]} - .set { bed_input } - - if (params.analysis_type == "wgs" ) { - ch_case_info.combine(bam_file_list) - .combine(bai_file_list) - .map { it -> it + [ [], [] ] } - .set { manta_input } - MANTA ( manta_input, ch_genome_fasta, ch_genome_fai, [] ) - } else { - ch_case_info.combine(bam_file_list) - .combine(bai_file_list) - .combine(bed_input) - .set { manta_input } - MANTA ( manta_input, ch_genome_fasta, ch_genome_fai, [] ) - } + ch_case_info.combine(bam_file_list) + .combine(bai_file_list) + .combine(ch_regions) + .set { manta_input } + MANTA ( manta_input, ch_genome_fasta, ch_genome_fai, [] ) MANTA.out.diploid_sv_vcf .join(MANTA.out.diploid_sv_vcf_tbi) .set {ch_filter_in} BCFTOOLS_VIEW_MANTA (ch_filter_in, [], [], []) - ch_versions = MANTA.out.versions - ch_versions = ch_versions.mix(BCFTOOLS_VIEW_MANTA.out.versions) - emit: candidate_small_indels_vcf = MANTA.out.candidate_small_indels_vcf // channel: [ val(meta), path(vcf) ] candidate_small_indels_vcf_tbi = MANTA.out.candidate_small_indels_vcf_tbi // channel: [ val(meta), path(tbi) ] @@ -57,6 +43,5 @@ workflow CALL_SV_MANTA { candidate_sv_vcf_tbi = MANTA.out.candidate_sv_vcf_tbi // channel: [ val(meta), path(tbi) ] diploid_sv_vcf = MANTA.out.diploid_sv_vcf // channel: [ val(meta), path(vcf) ] diploid_sv_vcf_tbi = MANTA.out.diploid_sv_vcf_tbi // channel: [ val(meta), path(tbi) ] - filtered_diploid_sv_vcf_tbi = BCFTOOLS_VIEW_MANTA.out.vcf // channel: [ val(meta), path(vcf), path(tbi) ] - versions = ch_versions + filtered_diploid_sv_vcf = BCFTOOLS_VIEW_MANTA.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/call_sv_manta/tests/main.nf.test b/subworkflows/local/call_sv_manta/tests/main.nf.test new file mode 100644 index 000000000..1757244d9 --- /dev/null +++ b/subworkflows/local/call_sv_manta/tests/main.nf.test @@ -0,0 +1,92 @@ +nextflow_workflow { + + name "Test Workflow CALL_SV_MANTA" + script "subworkflows/local/call_sv_manta/main.nf" + workflow "CALL_SV_MANTA" + + tag "subworkflows" + tag "call_sv_manta" + + tag "manta/germline" + tag "bcftools/view" + + config "./nextflow.config" + + test("CALL_SV_MANTA") { + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [[id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true)] + ) + input[1] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)], + [[id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam.bai', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true)] + ) + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'justhusky']) + input[5] = channel.value([[], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.diploid_sv_vcf[0][1]).vcf.variantsMD5, + path(workflow.out.filtered_diploid_sv_vcf[0][1]).vcf.variantsMD5 + ).match() } + ) + } + } + test("CALL_SV_MANTA - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [[id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true)] + ) + input[1] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)], + [[id:'hugelymodelbat', sample:'hugelymodelbat', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:hugelymodelbat\\\\tPL:illumina\\\\tSM:hugelymodelbat'", lane:1, sex:1, phenotype:2, paternal:'earlycasualcaiman', maternal:'slowlycivilbuck', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/hugelymodelbat_sorted_md.bam.bai', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true)] + ) + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'justhusky']) + input[5] = channel.value([[], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/call_sv_manta/tests/main.nf.test.snap b/subworkflows/local/call_sv_manta/tests/main.nf.test.snap new file mode 100644 index 000000000..b2b600081 --- /dev/null +++ b/subworkflows/local/call_sv_manta/tests/main.nf.test.snap @@ -0,0 +1,136 @@ +{ + "CALL_SV_MANTA": { + "content": [ + "9f37331609347a1685ba4862d8583b2f", + "2111e88e54fdd01f0492901606bcea6f" + ], + "timestamp": "2026-06-03T11:38:41.791162924", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "CALL_SV_MANTA - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_small_indels.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_small_indels.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "3": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "justhusky" + }, + "justhusky.diploid_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "5": [ + [ + { + "id": "justhusky" + }, + "justhusky.diploid_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "justhusky" + }, + "justhusky_manta_filtered.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "candidate_small_indels_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_small_indels.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "candidate_small_indels_vcf_tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_small_indels.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "candidate_sv_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "candidate_sv_vcf_tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky.candidate_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "diploid_sv_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky.diploid_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "diploid_sv_vcf_tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky.diploid_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "filtered_diploid_sv_vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_manta_filtered.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-03T11:39:05.440330127", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_manta/tests/nextflow.config b/subworkflows/local/call_sv_manta/tests/nextflow.config new file mode 100644 index 000000000..34fd1a2e9 --- /dev/null +++ b/subworkflows/local/call_sv_manta/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: '.*CALL_SV_MANTA:BCFTOOLS_VIEW_MANTA' { + ext.args = '--min-ac 1' + ext.prefix = { "${meta.id}_manta_filtered" } + } +} diff --git a/subworkflows/local/call_sv_tiddit/main.nf b/subworkflows/local/call_sv_tiddit/main.nf index 3d8190224..0abe8294e 100644 --- a/subworkflows/local/call_sv_tiddit/main.nf +++ b/subworkflows/local/call_sv_tiddit/main.nf @@ -2,24 +2,26 @@ // A structural variant caller workflow for tiddit // -include { TIDDIT_SV } from '../../../modules/nf-core/tiddit/sv/main' +include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_TIDDIT } from '../../../modules/nf-core/bcftools/view/main.nf' include { SVDB_MERGE as SVDB_MERGE_TIDDIT } from '../../../modules/nf-core/svdb/merge/main' include { TABIX_BGZIPTABIX as INDEX_TIDDIT } from '../../../modules/nf-core/tabix/bgziptabix/main' -include { BCFTOOLS_VIEW as BCFTOOLS_VIEW_TIDDIT } from '../../../modules/nf-core/bcftools/view/main.nf' +include { TIDDIT_SV } from '../../../modules/nf-core/tiddit/sv/main' workflow CALL_SV_TIDDIT { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fasta) ] ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] ch_bwa_index // channel: [mandatory] [ val(meta), path(index)] ch_case_info // channel: [mandatory] [ val(case_info) ] main: - TIDDIT_SV ( ch_bam_bai, ch_genome_fasta, ch_bwa_index ) + ch_genome_fa_fai = ch_genome_fasta.join(ch_genome_fai).collect() + TIDDIT_SV ( ch_bam_bai, ch_genome_fa_fai, ch_bwa_index ) INDEX_TIDDIT (TIDDIT_SV.out.vcf) - BCFTOOLS_VIEW_TIDDIT (INDEX_TIDDIT.out.gz_tbi, [], [], []).vcf - .collect{it[1]} + BCFTOOLS_VIEW_TIDDIT (INDEX_TIDDIT.out.gz_index, [], [], []).vcf + .collect{ _meta, vcf -> vcf} .toList() .set { vcf_file_list } @@ -29,12 +31,6 @@ workflow CALL_SV_TIDDIT { SVDB_MERGE_TIDDIT ( merge_input_vcfs, [], true ) - ch_versions = TIDDIT_SV.out.versions.first() - ch_versions = ch_versions.mix(SVDB_MERGE_TIDDIT.out.versions) - ch_versions = ch_versions.mix(INDEX_TIDDIT.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_VIEW_TIDDIT.out.versions) - emit: vcf = SVDB_MERGE_TIDDIT.out.vcf // channel: [ val(meta), path(vcf) ] - versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/call_sv_tiddit/tests/main.nf.test b/subworkflows/local/call_sv_tiddit/tests/main.nf.test new file mode 100644 index 000000000..c3ad01291 --- /dev/null +++ b/subworkflows/local/call_sv_tiddit/tests/main.nf.test @@ -0,0 +1,105 @@ +nextflow_workflow { + + name "Test Workflow CALL_SV_TIDDIT" + script "subworkflows/local/call_sv_tiddit/main.nf" + workflow "CALL_SV_TIDDIT" + + tag "subworkflows" + tag "call_sv_tiddit" + + tag "tiddit/sv" + tag "svdb/merge" + tag "tabix/bgziptabix" + tag "bcftools/view" + + config "./nextflow.config" + + test("CALL_SV_TIDDIT") { + + setup { + run("BWA_INDEX") { + script "modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[3] = BWA_INDEX.out.index.collect() + input[4] = channel.of([id:'justhusky']) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + path(workflow.out.vcf[0][1]).vcf.chromosomes == ['MT', '21'] as Set + ).match() } + ) + } + } + test("CALL_SV_TIDDIT, stub") { + + options "-stub" + + setup { + run("BWA_INDEX") { + script "modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = channel.of([ + [id:'genome'], + file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true) + ]) + """ + } + } + } + + when { + workflow { + """ + input[0] = channel.of( + [[id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)], + [[id:'slowlycivilbuck', sample:'slowlycivilbuck', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:slowlycivilbuck\\\\tPL:illumina\\\\tSM:slowlycivilbuck'", lane:1, sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true)] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[3] = BWA_INDEX.out.index.collect() + input[4] = channel.of([id:'justhusky']) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/call_sv_tiddit/tests/main.nf.test.snap b/subworkflows/local/call_sv_tiddit/tests/main.nf.test.snap new file mode 100644 index 000000000..7d377df60 --- /dev/null +++ b/subworkflows/local/call_sv_tiddit/tests/main.nf.test.snap @@ -0,0 +1,39 @@ +{ + "CALL_SV_TIDDIT, stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_svdb_tiddit.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_svdb_tiddit.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-03-05T13:01:06.562601729", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "CALL_SV_TIDDIT": { + "content": [ + true + ], + "timestamp": "2026-03-04T20:29:06.356832656", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/call_sv_tiddit/tests/nextflow.config b/subworkflows/local/call_sv_tiddit/tests/nextflow.config new file mode 100644 index 000000000..dc0a83a03 --- /dev/null +++ b/subworkflows/local/call_sv_tiddit/tests/nextflow.config @@ -0,0 +1,16 @@ +process { + + withName: 'BCFTOOLS_VIEW_TIDDIT' { + ext.args = '--min-ac 1' + ext.prefix = { "${meta.id}_tiddit_filtered" } + } + + withName: 'INDEX_TIDDIT' { + ext.prefix = { "${meta.id}_tiddit" } + } + + withName: 'SVDB_MERGE_TIDDIT' { + ext.args = '--notag --pass_only' + ext.prefix = { "${meta.id}_svdb_tiddit" } + } +} diff --git a/subworkflows/local/contamination_check/main.nf b/subworkflows/local/contamination_check/main.nf new file mode 100644 index 000000000..cb6ba0a85 --- /dev/null +++ b/subworkflows/local/contamination_check/main.nf @@ -0,0 +1,63 @@ +// +// Subworkflow: Check sample contamination using GATK +// + +include { GATK4_GETPILEUPSUMMARIES } from '../../../modules/nf-core/gatk4/getpileupsummaries/main' +include { GATK4_CALCULATECONTAMINATION } from '../../../modules/nf-core/gatk4/calculatecontamination/main' + +workflow CONTAMINATION_CHECK { + + take: + ch_bam // channel: [ val(meta), path(bam), path(bai) ] + ch_fasta // channel: [ val(meta), path(fasta) ] + ch_fai // channel: [ val(meta), path(fai) ] + ch_dict // channel: [ val(meta), path(dict) ] + ch_contamination_vcf // channel: [ path(vcf), path(tbi) ] + ch_intervals // channel: [ path(bed) ] - only used for WES, empty for WGS + + main: + + // Prepare BAM with intervals - conditionally based on analysis type + // For WGS: intervals will be empty [], for WES: intervals will contain the BED file + ch_bam_with_intervals = ch_bam + .combine(ch_intervals.ifEmpty([[]])) + .map { meta, bam, bai, bed -> + // If bed is an empty list, pass empty list; otherwise pass bed file + def intervals = (bed instanceof List && bed.isEmpty()) ? [] : (bed ?: []) + [ meta, bam, bai, intervals ] + } + + // Separate VCF and TBI - collect them to make value channels + ch_variants_vcf = ch_contamination_vcf + .map { vcf, tbi -> vcf } + .collect() + + ch_variants_tbi = ch_contamination_vcf + .map { vcf, tbi -> tbi } + .collect() + + // Run GetPileupSummaries + GATK4_GETPILEUPSUMMARIES ( + ch_bam_with_intervals, // [meta, bam, bai, intervals] + ch_fasta, // [meta2, fasta] + ch_fai, // [meta3, fai] + ch_dict, // [meta4, dict] + ch_variants_vcf, // path(vcf) + ch_variants_tbi // path(tbi) + ) + + // Run CalculateContamination (tumor-only, no matched normal) + // Format: [meta, pileup_table, matched_normal_table] + // matched_normal_table is empty [] for tumor-only mode + ch_contamination_input = GATK4_GETPILEUPSUMMARIES.out.table + .map { meta, table -> [ meta, table, [] ] } + + GATK4_CALCULATECONTAMINATION ( + ch_contamination_input + ) + + emit: + contamination_table = GATK4_CALCULATECONTAMINATION.out.contamination + segmentation_table = GATK4_CALCULATECONTAMINATION.out.segmentation + pileup_table = GATK4_GETPILEUPSUMMARIES.out.table +} diff --git a/subworkflows/local/contamination_check/meta.yml b/subworkflows/local/contamination_check/meta.yml new file mode 100644 index 000000000..ab7f5937b --- /dev/null +++ b/subworkflows/local/contamination_check/meta.yml @@ -0,0 +1,41 @@ +name: contamination_check +description: Estimate sample contamination using GATK GetPileupSummaries and CalculateContamination +keywords: + - contamination + - QC + - GATK +components: + - gatk4/getpileupsummaries + - gatk4/calculatecontamination +input: + - ch_bam: + type: file + description: BAM files with their indices + pattern: "*.{bam,cram}" + - ch_fasta: + type: file + description: Reference genome FASTA file + pattern: "*.{fa,fasta}" + - ch_contamination_vcf: + type: file + description: VCF file containing common germline variants (gnomAD) + pattern: "*.vcf.gz" + - ch_intervals: + type: file + description: BED file with target intervals + pattern: "*.bed" +output: + - contamination_table: + type: file + description: Table containing contamination estimates + pattern: "*.contamination.table" + - segmentation_table: + type: file + description: Table containing tumor segmentation + pattern: "*.segmentation.table" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "56053vujinovic" diff --git a/subworkflows/local/contamination_check/tests/main.nf.test b/subworkflows/local/contamination_check/tests/main.nf.test new file mode 100644 index 000000000..f437201ba --- /dev/null +++ b/subworkflows/local/contamination_check/tests/main.nf.test @@ -0,0 +1,110 @@ +nextflow_workflow { + + name "Test Workflow CONTAMINATION_CHECK" + script "subworkflows/local/contamination_check/main.nf" + workflow "CONTAMINATION_CHECK" + tag "subworkflows" + tag "contamination_check" + config "./nextflow.config" + + test("CONTAMINATION_CHECK - WGS, no intervals") { + + when { + params { + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, sex:1, phenotype:1, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[4] = channel.of( + [ + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz.tbi', checkIfExists: true) + ] + ).collect() + input[5] = Channel.empty() + """ + } + } + + then { + assertAll ( + { assert workflow.success }, + { assert snapshot( + workflow.out.contamination_table + .collect { it[1] } + .flatten() + .collect { file(it).name } + .toSorted(), + workflow.out.pileup_table + .collect { it[1] } + .flatten() + .collect { file(it).name } + .toSorted() + ).match() + } + ) + } + + } + + test("CONTAMINATION_CHECK - WES, with intervals") { + + when { + params { + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, sex:1, phenotype:1, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ] + ) + input[1] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[2] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)).collect() + input[4] = channel.of( + [ + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'reference/grch37_gnomad_-r2.1.1-.vcf.gz.tbi', checkIfExists: true) + ] + ).collect() + input[5] = Channel.fromPath(params.pipelines_testdata_base_path + 'reference/target.bed', checkIfExists: true).collect() + """ + } + } + + then { + assertAll ( + { assert workflow.success }, + { assert snapshot( + workflow.out.contamination_table + .collect { it[1] } + .flatten() + .collect { file(it).name } + .toSorted(), + workflow.out.pileup_table + .collect { it[1] } + .flatten() + .collect { file(it).name } + .toSorted() + ).match() + } + ) + } + + } + +} diff --git a/subworkflows/local/contamination_check/tests/main.nf.test.snap b/subworkflows/local/contamination_check/tests/main.nf.test.snap new file mode 100644 index 000000000..f121b7efd --- /dev/null +++ b/subworkflows/local/contamination_check/tests/main.nf.test.snap @@ -0,0 +1,32 @@ +{ + "CONTAMINATION_CHECK - WGS, no intervals": { + "content": [ + [ + "earlycasualcaiman_contamination.contamination.table" + ], + [ + "earlycasualcaiman_pileups.pileups.table" + ] + ], + "timestamp": "2026-03-23T14:29:41.579345381", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "CONTAMINATION_CHECK - WES, with intervals": { + "content": [ + [ + "earlycasualcaiman_contamination.contamination.table" + ], + [ + "earlycasualcaiman_pileups.pileups.table" + ] + ], + "timestamp": "2026-03-23T14:31:02.497064504", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} diff --git a/subworkflows/local/contamination_check/tests/nextflow.config b/subworkflows/local/contamination_check/tests/nextflow.config new file mode 100644 index 000000000..3a5a56e5c --- /dev/null +++ b/subworkflows/local/contamination_check/tests/nextflow.config @@ -0,0 +1,12 @@ +process { + + withName: '.*CONTAMINATION_CHECK:GATK4_GETPILEUPSUMMARIES' { + ext.args = '--disable-sequence-dictionary-validation' + ext.prefix = { "${meta.id}_pileups" } + } + + withName: '.*CONTAMINATION_CHECK:GATK4_CALCULATECONTAMINATION' { + ext.args = '' + ext.prefix = { "${meta.id}_contamination" } + } +} diff --git a/subworkflows/local/convert_mt_bam_to_fastq/main.nf b/subworkflows/local/convert_mt_bam_to_fastq/main.nf index 156f71bb4..135721f06 100644 --- a/subworkflows/local/convert_mt_bam_to_fastq/main.nf +++ b/subworkflows/local/convert_mt_bam_to_fastq/main.nf @@ -5,32 +5,30 @@ include { GATK4_PRINTREADS as GATK4_PRINTREADS_MT } from '../../../modules/nf-core/gatk4/printreads/main' include { GATK4_REVERTSAM as GATK4_REVERTSAM_MT } from '../../../modules/nf-core/gatk4/revertsam/main' include { GATK4_SAMTOFASTQ as GATK4_SAMTOFASTQ_MT } from '../../../modules/nf-core/gatk4/samtofastq/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_MT } from '../../../modules/nf-core/samtools/index/main' workflow CONVERT_MT_BAM_TO_FASTQ { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] ch_genome_dict // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] main: - ch_versions = Channel.empty() // Outputs bam containing only MT GATK4_PRINTREADS_MT ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_genome_dict ) + SAMTOOLS_INDEX_MT (GATK4_PRINTREADS_MT.out.bam) + ch_bam_bai = GATK4_PRINTREADS_MT.out.bam.join(SAMTOOLS_INDEX_MT.out.bai) // Removes alignment information GATK4_REVERTSAM_MT ( GATK4_PRINTREADS_MT.out.bam ) // Outputs fastq files GATK4_SAMTOFASTQ_MT ( GATK4_REVERTSAM_MT.out.bam ) - ch_versions = ch_versions.mix(GATK4_PRINTREADS_MT.out.versions.first()) - ch_versions = ch_versions.mix(GATK4_REVERTSAM_MT.out.versions.first()) - ch_versions = ch_versions.mix(GATK4_SAMTOFASTQ_MT.out.versions.first()) - emit: + bam_bai = ch_bam_bai // channel: [ val(meta), path(bam), path(bai) ] fastq = GATK4_SAMTOFASTQ_MT.out.fastq // channel: [ val(meta), [ path(fastq) ] ] - bam = GATK4_REVERTSAM_MT.out.bam // channel: [ val(meta), path(bam) ] - versions = ch_versions // channel: [ path(versions.yml) ] + ubam = GATK4_REVERTSAM_MT.out.bam // channel: [ val(meta), path(bam) ] } diff --git a/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test b/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test new file mode 100644 index 000000000..f3451fd0f --- /dev/null +++ b/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test @@ -0,0 +1,70 @@ +nextflow_workflow { + + name "Test Workflow CONVERT_MT_BAM_TO_FASTQ" + script "subworkflows/local/convert_mt_bam_to_fastq/main.nf" + workflow "CONVERT_MT_BAM_TO_FASTQ" + + tag "subworkflows" + tag "convert_mt_bam_to_fastq" + + tag "gatk4/printreads" + tag "gatk4/revertsam" + tag "gatk4/samtofastq" + tag "samtools/index" + + test("CONVERT_MT_BAM_TO_FASTQ") { + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } + + test("CONVERT_MT_BAM_TO_FASTQ - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test.snap b/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test.snap new file mode 100644 index 000000000..15bf3061a --- /dev/null +++ b/subworkflows/local/convert_mt_bam_to_fastq/tests/main.nf.test.snap @@ -0,0 +1,258 @@ +{ + "CONVERT_MT_BAM_TO_FASTQ - stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.reverted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "ubam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.reverted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-03-05T13:04:42.938137711", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "CONVERT_MT_BAM_TO_FASTQ": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.bam:md5,424fcb1e097f4a0423e83e5af2c16ccf", + "earlycasualcaiman.bam.bai:md5,0c6f0728a82e2c893f2106b92e280648" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_1.fastq.gz:md5,e22db895fb1dd8bc4673f2a70fc87260", + "earlycasualcaiman_2.fastq.gz:md5,a4f49dbd116ebaec797c7beea82696db" + ] + ] + ], + "2": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.reverted.bam:md5,11a20cf34d72d3b8b4abf753099bbb90" + ] + ], + "bam_bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.bam:md5,424fcb1e097f4a0423e83e5af2c16ccf", + "earlycasualcaiman.bam.bai:md5,0c6f0728a82e2c893f2106b92e280648" + ] + ], + "fastq": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + [ + "earlycasualcaiman_1.fastq.gz:md5,e22db895fb1dd8bc4673f2a70fc87260", + "earlycasualcaiman_2.fastq.gz:md5,a4f49dbd116ebaec797c7beea82696db" + ] + ] + ], + "ubam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman.reverted.bam:md5,11a20cf34d72d3b8b4abf753099bbb90" + ] + ] + } + ], + "timestamp": "2026-03-01T22:25:34.791929735", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/generate_clinical_set.nf b/subworkflows/local/generate_clinical_set.nf deleted file mode 100644 index 3ed94ad63..000000000 --- a/subworkflows/local/generate_clinical_set.nf +++ /dev/null @@ -1,40 +0,0 @@ -// -// Generarte clinical set of variants -// - -include { ENSEMBLVEP_FILTERVEP } from '../../modules/nf-core/ensemblvep/filtervep' -include { TABIX_BGZIP } from '../../modules/nf-core/tabix/bgzip' -include { BCFTOOLS_FILTER } from '../../modules/nf-core/bcftools/filter' - -workflow GENERATE_CLINICAL_SET { - take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_hgnc_ids // channel: [mandatory] [ val(hgnc_ids) ] - val_ismt // value: if mitochondria, set to true - - main: - ch_versions = Channel.empty() - - ENSEMBLVEP_FILTERVEP( - ch_vcf, - ch_hgnc_ids - ) - .output - .set { ch_filtervep_out } - - if (val_ismt) { - BCFTOOLS_FILTER (ch_filtervep_out.map { meta, vcf -> return [meta, vcf, []]}) - ch_clinical = BCFTOOLS_FILTER.out.vcf - ch_versions = ch_versions.mix( BCFTOOLS_FILTER.out.versions ) - } else { - TABIX_BGZIP( ch_filtervep_out ) - ch_clinical = TABIX_BGZIP.out.output - ch_versions = ch_versions.mix( TABIX_BGZIP.out.versions ) - } - - ch_versions = ch_versions.mix( ENSEMBLVEP_FILTERVEP.out.versions ) - - emit: - vcf = ch_clinical // channel: [ val(meta), path(vcf) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/generate_cytosure_files.nf b/subworkflows/local/generate_cytosure_files/main.nf similarity index 51% rename from subworkflows/local/generate_cytosure_files.nf rename to subworkflows/local/generate_cytosure_files/main.nf index 569300db2..c345bb6a3 100644 --- a/subworkflows/local/generate_cytosure_files.nf +++ b/subworkflows/local/generate_cytosure_files/main.nf @@ -2,53 +2,53 @@ // Convert VCF with structural variations to the “.CGH” format used by the CytoSure Interpret Software // -include { BCFTOOLS_VIEW as SPLIT_AND_FILTER_SV_VCF } from '../../modules/nf-core/bcftools/view/main' -include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_SV_VCF } from '../../modules/nf-core/bcftools/reheader/main' -include { TIDDIT_COV as TIDDIT_COV_VCF2CYTOSURE } from '../../modules/nf-core/tiddit/cov/main' -include { VCF2CYTOSURE } from '../../modules/nf-core/vcf2cytosure/main' +include { BCFTOOLS_REHEADER as BCFTOOLS_REHEADER_SV_VCF } from '../../../modules/nf-core/bcftools/reheader/main' +include { BCFTOOLS_VIEW as SPLIT_AND_FILTER_SV_VCF } from '../../../modules/nf-core/bcftools/view/main' +include { TIDDIT_COV as TIDDIT_COV_VCF2CYTOSURE } from '../../../modules/nf-core/tiddit/cov/main' +include { VCF2CYTOSURE } from '../../../modules/nf-core/vcf2cytosure/main' workflow GENERATE_CYTOSURE_FILES { take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_tbi // channel: [mandatory] [ val(meta), path(vcf_index) ] - ch_bam // channel: [mandatory] [ val(meta), path(bam) ] - ch_sample_id_map // channel: [optional] [val(id), val(id)] - ch_blacklist // channel: [optional] [path(blacklist)] + ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_blacklist // channel: [optional] [path(blacklist)] + ch_sample_id_map // channel: [optional] [val(id), val(id)] + ch_tbi // channel: [mandatory] [ val(meta), path(vcf_index) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + val_sample_id_map // string: path to sample_id_map file main: - ch_versions = Channel.empty() - ch_reheader_out = Channel.empty() + ch_reheader_out = channel.empty() - TIDDIT_COV_VCF2CYTOSURE (ch_bam, [[],[]]) + TIDDIT_COV_VCF2CYTOSURE (ch_bam_bai, [[],[]]) // Build channel: [val(sample_meta), path(vcf), path(vcf_index)] ch_vcf.join( ch_tbi, failOnMismatch: true ) .set { ch_vcf_tbi } - ch_bam.combine(ch_vcf_tbi) + ch_bam_bai.combine(ch_vcf_tbi) .map { - meta_sample, bam, meta_case, vcf, tbi -> - id_meta = ['id':meta_sample.sample] - sex_meta = ['sex':meta_sample.sex] + meta_sample, _bam, _bai, _meta_case, vcf, tbi -> + def id_meta = ['id':meta_sample.sample] + def sex_meta = ['sex':meta_sample.sex] return [ id_meta, sex_meta, vcf, tbi ] } .join(ch_sample_id_map, remainder: true) - .branch { it -> - id: it[4].equals(null) - return [it[0] + [custid:it[0].id] + it[1], it[2], it[3]] - custid: !(it[4].equals(null)) - return [it[0] + [custid:it[4]] + it[1], it[2], it[3]] + .branch { id_meta, sex_meta, vcf, tbi, samplemap -> + id: samplemap.equals(null) + return [id_meta + [custid:id_meta.id] + sex_meta, vcf, tbi] + custid: !(samplemap.equals(null)) + return [id_meta + [custid:samplemap] + sex_meta, vcf, tbi] } .set { ch_for_mix } - Channel.empty() + channel.empty() .mix(ch_for_mix.id, ch_for_mix.custid) .set { ch_sample_vcf } // Split vcf into sample vcf:s and frequency filter SPLIT_AND_FILTER_SV_VCF ( ch_sample_vcf, [], [], [] ) - if (params.sample_id_map != null) { + if (!val_sample_id_map.equals(null)) { SPLIT_AND_FILTER_SV_VCF.out.vcf .map { meta, vcf -> return [meta, vcf, [], []]} @@ -57,20 +57,19 @@ workflow GENERATE_CYTOSURE_FILES { BCFTOOLS_REHEADER_SV_VCF ( ch_reheader_in, [[:],[]] ).vcf .set {ch_reheader_out} - ch_versions = ch_versions.mix(BCFTOOLS_REHEADER_SV_VCF.out.versions.first()) } SPLIT_AND_FILTER_SV_VCF.out.vcf .join(ch_reheader_out, remainder: true) - .branch { it -> - split: it[2].equals(null) - return [it[0], it[1]] - reheader: !(it[2].equals(null)) - return [it[0], it[2]] + .branch { meta, filteredvcf, reheaderedvcf -> + split: reheaderedvcf.equals(null) + return [meta, filteredvcf] + reheader: !(reheaderedvcf.equals(null)) + return [meta, reheaderedvcf] } .set { ch_for_mix } - Channel.empty() + channel.empty() .mix(ch_for_mix.split, ch_for_mix.reheader) .toSortedList { a, b -> a[0].id <=> b[0].id } .flatMap() @@ -88,10 +87,6 @@ workflow GENERATE_CYTOSURE_FILES { ch_blacklist ) - ch_versions = ch_versions.mix(TIDDIT_COV_VCF2CYTOSURE.out.versions.first()) - ch_versions = ch_versions.mix(SPLIT_AND_FILTER_SV_VCF.out.versions.first()) - ch_versions = ch_versions.mix(VCF2CYTOSURE.out.versions.first()) - emit: - versions = ch_versions // channel: [ versions.yml ] + cgh = VCF2CYTOSURE.out.cgh // channel: [ val(meta), path(cgh) ] } diff --git a/subworkflows/local/generate_cytosure_files/tests/main.nf.test b/subworkflows/local/generate_cytosure_files/tests/main.nf.test new file mode 100644 index 000000000..f124b6ef2 --- /dev/null +++ b/subworkflows/local/generate_cytosure_files/tests/main.nf.test @@ -0,0 +1,86 @@ +nextflow_workflow { + + name "Test Workflow GENERATE_CYTOSURE_FILES" + script "subworkflows/local/generate_cytosure_files/main.nf" + workflow "GENERATE_CYTOSURE_FILES" + + tag "subworkflows" + tag "generate_cytosure_files" + + tag "bcftools/view" + tag "bcftools/reheader" + tag "tiddit/cov" + tag "vcf2cytosure" + + config "./nextflow.config" + + test("GENERATE_CYTOSURE_FILES - no sample_id_map, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.value([]) + input[2] = channel.empty() + input[3] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[4] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true) + ]) + input[5] = null + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("GENERATE_CYTOSURE_FILES - with sample_id_map, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.value([]) + input[2] = channel.of([[id:'earlycasualcaiman'], 'CUST_001']) + input[3] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[4] = channel.of([ + [id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true) + ]) + input[5] = 'sample_id_map.csv' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/generate_cytosure_files/tests/main.nf.test.snap b/subworkflows/local/generate_cytosure_files/tests/main.nf.test.snap new file mode 100644 index 000000000..5cf68acf0 --- /dev/null +++ b/subworkflows/local/generate_cytosure_files/tests/main.nf.test.snap @@ -0,0 +1,64 @@ +{ + "GENERATE_CYTOSURE_FILES - no sample_id_map, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "custid": "earlycasualcaiman", + "sex": 1 + }, + "earlycasualcaiman.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cgh": [ + [ + { + "id": "earlycasualcaiman", + "custid": "earlycasualcaiman", + "sex": 1 + }, + "earlycasualcaiman.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-30T20:58:21.226904272", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "GENERATE_CYTOSURE_FILES - with sample_id_map, stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "custid": "CUST_001", + "sex": 1 + }, + "CUST_001.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cgh": [ + [ + { + "id": "earlycasualcaiman", + "custid": "CUST_001", + "sex": 1 + }, + "CUST_001.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-06-30T20:58:44.411334018", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/generate_cytosure_files/tests/nextflow.config b/subworkflows/local/generate_cytosure_files/tests/nextflow.config new file mode 100644 index 000000000..f4653e109 --- /dev/null +++ b/subworkflows/local/generate_cytosure_files/tests/nextflow.config @@ -0,0 +1,20 @@ +process { + + withName: 'TIDDIT_COV_VCF2CYTOSURE' { + ext.prefix = { "${meta.id}_cov" } + } + + withName: 'SPLIT_AND_FILTER_SV_VCF' { + ext.prefix = { "${meta.id}" } + } + + withName: 'BCFTOOLS_REHEADER_SV_VCF' { + beforeScript = { "echo ${meta.custid} > ${meta.custid}.txt" } + ext.prefix = { "${meta.custid}" } + } + + withName: 'VCF2CYTOSURE' { + ext.prefix = { "${meta.custid}" ? "${meta.custid}" : "${meta.id}" } + } + +} diff --git a/subworkflows/local/gens.nf b/subworkflows/local/gens/main.nf similarity index 63% rename from subworkflows/local/gens.nf rename to subworkflows/local/gens/main.nf index c491d2e5e..9edb7a421 100644 --- a/subworkflows/local/gens.nf +++ b/subworkflows/local/gens/main.nf @@ -2,27 +2,25 @@ // A preprocessing workflow for Gens // -include { GATK4_COLLECTREADCOUNTS as COLLECTREADCOUNTS } from '../../modules/nf-core/gatk4/collectreadcounts/main' -include { GATK4_DENOISEREADCOUNTS as DENOISEREADCOUNTS_FEMALE } from '../../modules/nf-core/gatk4/denoisereadcounts/main' -include { GATK4_DENOISEREADCOUNTS as DENOISEREADCOUNTS_MALE } from '../../modules/nf-core/gatk4/denoisereadcounts/main' -include { GENS as GENS_GENERATE } from '../../modules/local/gens/main' +include { GATK4_COLLECTREADCOUNTS as COLLECTREADCOUNTS } from '../../../modules/nf-core/gatk4/collectreadcounts/main' +include { GATK4_DENOISEREADCOUNTS as DENOISEREADCOUNTS_FEMALE } from '../../../modules/nf-core/gatk4/denoisereadcounts/main' +include { GATK4_DENOISEREADCOUNTS as DENOISEREADCOUNTS_MALE } from '../../../modules/nf-core/gatk4/denoisereadcounts/main' +include { PREPARECOVANDBAF as GENS_GENERATE } from '../../../modules/nf-core/gens/preparecovandbaf/main' workflow GENS { take: ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_gvcf // channel: [mandatory] [ val(meta), path(gvcf) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_gnomad_pos // channel: [mandatory] [ path(gnomad_pos) ] + ch_gvcf // channel: [mandatory] [ val(meta), path(gvcf) ] + ch_gvcf_tbi // channel: [mandatory] [ val(meta), path(gvcf.tbi) ] ch_interval_list // channel: [mandatory] [ path(interval_list) ] ch_pon_female // channel: [mandatory] [ path(pon) ] ch_pon_male // channel: [mandatory] [ path(pon) ] - ch_gnomad_pos // channel: [mandatory] [ path(gnomad_pos) ] - ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] main: - ch_versions = Channel.empty() - ch_bam_bai .combine(ch_interval_list) .set { ch_bam_bai_intervals } @@ -35,7 +33,7 @@ workflow GENS { ) COLLECTREADCOUNTS.out.hdf5 - .branch { meta, counts -> + .branch { meta, _counts -> female: meta.sex.toString().matches('2|other|0') male: meta.sex == 1 } @@ -55,18 +53,15 @@ workflow GENS { .set { ch_denoisereadcounts_out } GENS_GENERATE ( - ch_denoisereadcounts_out, - ch_gvcf, + ch_denoisereadcounts_out + .join(ch_gvcf) + .join(ch_gvcf_tbi), ch_gnomad_pos ) - ch_versions = ch_versions.mix(COLLECTREADCOUNTS.out.versions.first()) - ch_versions = ch_versions.mix(DENOISEREADCOUNTS_FEMALE.out.versions.first()) - ch_versions = ch_versions.mix(DENOISEREADCOUNTS_MALE.out.versions.first()) - ch_versions = ch_versions.mix(GENS_GENERATE.out.versions.first()) - emit: - gens_cov_bed_gz = GENS_GENERATE.out.cov // channel: [ val(meta), path(bed) ] - gens_baf_bed_gz = GENS_GENERATE.out.baf // channel: [ val(meta), path(bed) ] - versions = ch_versions // channel: [ path(versions.yml) ] + gens_baf_bed_gz = GENS_GENERATE.out.baf_gz // channel: [ val(meta), path(bed.gz) ] + gens_baf_bed_tbi = GENS_GENERATE.out.baf_tbi // channel: [ val(meta), path(tbi) ] + gens_cov_bed_gz = GENS_GENERATE.out.cov_gz // channel: [ val(meta), path(bed.gz) ] + gens_cov_bed_tbi = GENS_GENERATE.out.cov_tbi // channel: [ val(meta), path(tbi) ] } diff --git a/subworkflows/local/gens/tests/main.nf.test b/subworkflows/local/gens/tests/main.nf.test new file mode 100644 index 000000000..2fb340822 --- /dev/null +++ b/subworkflows/local/gens/tests/main.nf.test @@ -0,0 +1,107 @@ +nextflow_workflow { + + name "Test Workflow GENS" + script "subworkflows/local/gens/main.nf" + workflow "GENS" + + tag "subworkflows" + tag "gens" + + tag "gatk4/collectreadcounts" + tag "gatk4/denoisereadcounts" + tag "gens/preparecovandbaf" + + config "./nextflow.config" + + test("GENS - male sample, stub") { + + options "-stub" + + when { + params { + countreadcounts = "--format HDF5" + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[4] = channel.of(file(params.pipelines_testdata_base_path + 'reference/gnomad_reformated.tab.gz', checkIfExists: true)) + input[5] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true) + ]) + input[6] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[7] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)) + input[8] = channel.of([[id:'pon_female'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]) + input[9] = channel.of([[id:'pon_male'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.gens_baf_bed_gz, + workflow.out.gens_baf_bed_tbi, + workflow.out.gens_cov_bed_gz, + workflow.out.gens_cov_bed_tbi + ).match() } + ) + } + } + + test("GENS - female sample, stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/slowlycivilbuck_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[2] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[3] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[4] = channel.of(file(params.pipelines_testdata_base_path + 'reference/gnomad_reformated.tab.gz', checkIfExists: true)) + input[5] = channel.of([ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true) + ]) + input[6] = channel.of([ + [id:'slowlycivilbuck', sample:'slowlycivilbuck', sex:2, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ]) + input[7] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)) + input[8] = channel.of([[id:'pon_female'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]) + input[9] = channel.of([[id:'pon_male'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.gens_baf_bed_gz, + workflow.out.gens_baf_bed_tbi, + workflow.out.gens_cov_bed_gz, + workflow.out.gens_cov_bed_tbi + ).match() + } + ) + } + } +} diff --git a/subworkflows/local/gens/tests/main.nf.test.snap b/subworkflows/local/gens/tests/main.nf.test.snap new file mode 100644 index 000000000..d3822eed7 --- /dev/null +++ b/subworkflows/local/gens/tests/main.nf.test.snap @@ -0,0 +1,132 @@ +{ + "GENS - female sample, stub": { + "content": [ + [ + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_gens.baf.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_gens.baf.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_gens.cov.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "slowlycivilbuck", + "sample": "slowlycivilbuck", + "sex": 2, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "slowlycivilbuck_gens.cov.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "timestamp": "2026-03-17T11:26:00.382738988", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "GENS - male sample, stub": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_gens.baf.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_gens.baf.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_gens.cov.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_gens.cov.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "timestamp": "2026-03-17T11:25:27.677483077", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/gens/tests/nextflow.config b/subworkflows/local/gens/tests/nextflow.config new file mode 100644 index 000000000..bab811d82 --- /dev/null +++ b/subworkflows/local/gens/tests/nextflow.config @@ -0,0 +1,11 @@ +process { + + withName: 'COLLECTREADCOUNTS' { + ext.args = { params.countreadcounts } + } + + withName: 'GENS_GENERATE' { + ext.prefix = { "${meta.id}_gens" } + } + +} diff --git a/subworkflows/local/postprocess_MT_calls/main.nf b/subworkflows/local/postprocess_MT_calls/main.nf index 8657b5ffb..4d9038527 100644 --- a/subworkflows/local/postprocess_MT_calls/main.nf +++ b/subworkflows/local/postprocess_MT_calls/main.nf @@ -2,34 +2,33 @@ // Merge and normalize MT variants // +include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' +include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' +include { BCFTOOLS_MERGE as BCFTOOLS_MERGE_MT } from '../../../modules/nf-core/bcftools/merge/main' +include { BCFTOOLS_NORM as REMOVE_DUPLICATES_MT } from '../../../modules/nf-core/bcftools/norm/main' +include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_MT } from '../../../modules/nf-core/bcftools/norm/main' +include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_POSTMERGE_MT } from '../../../modules/nf-core/bcftools/norm/main' include { GATK4_MERGEVCFS as GATK4_MERGEVCFS_LIFT_UNLIFT_MT } from '../../../modules/nf-core/gatk4/mergevcfs/main' include { GATK4_VARIANTFILTRATION as GATK4_VARIANTFILTRATION_MT } from '../../../modules/nf-core/gatk4/variantfiltration/main' -include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_MT } from '../../../modules/nf-core/bcftools/norm/main' -include { TABIX_TABIX as TABIX_TABIX_MT } from '../../../modules/nf-core/tabix/tabix/main' -include { BCFTOOLS_NORM as REMOVE_DUPLICATES_MT } from '../../../modules/nf-core/bcftools/norm/main' -include { TABIX_TABIX as TABIX_TABIX_MT2 } from '../../../modules/nf-core/tabix/tabix/main' -include { BCFTOOLS_MERGE as BCFTOOLS_MERGE_MT } from '../../../modules/nf-core/bcftools/merge/main' -include { TABIX_TABIX as TABIX_TABIX_MERGE } from '../../../modules/nf-core/tabix/tabix/main' include { PICARD_LIFTOVERVCF } from '../../../modules/nf-core/picard/liftovervcf/main' -include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' -include { ADD_VARCALLER_TO_BED } from '../../../modules/local/add_varcallername_to_bed' include { TABIX_TABIX as TABIX_ANNOTATE } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_TABIX_MERGE } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_TABIX_MT } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_TABIX_MT2 } from '../../../modules/nf-core/tabix/tabix/main' workflow POSTPROCESS_MT_CALLS { take: - ch_mt_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_mtshift_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_mtshift_backchain // channel: [mandatory] [ val(meta), path(backchain) ] - ch_case_info // channel: [mandatory] [ val(case_info) ] - ch_foundin_header // channel: [mandatory] [ path(header) ] - ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_case_info // channel: [mandatory] [ val(case_info) ] + ch_foundin_header // channel: [mandatory] [ path(header) ] + ch_genome_chrsizes // channel: [mandatory] [ path(chrsizes) ] + ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_mt_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + ch_mtshift_backchain // channel: [mandatory] [ val(meta), path(backchain) ] + ch_mtshift_vcf // channel: [mandatory] [ val(meta), path(vcf) ] main: - ch_versions = Channel.empty() - // LIFTOVER SHIFTED VCF TO REFERENCE MT POSITIONS PICARD_LIFTOVERVCF ( ch_mtshift_vcf, @@ -50,7 +49,7 @@ workflow POSTPROCESS_MT_CALLS { GATK4_MERGEVCFS_LIFT_UNLIFT_MT.out.vcf .join(GATK4_MERGEVCFS_LIFT_UNLIFT_MT.out.tbi, failOnMismatch:true, failOnDuplicate:true) .set { ch_filt_vcf } - GATK4_VARIANTFILTRATION_MT (ch_filt_vcf, ch_genome_fasta, ch_genome_fai, ch_genome_dictionary) + GATK4_VARIANTFILTRATION_MT (ch_filt_vcf, ch_genome_fasta, ch_genome_fai, ch_genome_dictionary, [[:],[]]) // Spliting multiallelic calls GATK4_VARIANTFILTRATION_MT.out.vcf @@ -61,19 +60,19 @@ workflow POSTPROCESS_MT_CALLS { // Removing duplicates and merging if there is more than one sample SPLIT_MULTIALLELICS_MT.out.vcf - .join(TABIX_TABIX_MT.out.tbi, failOnMismatch:true, failOnDuplicate:true) + .join(TABIX_TABIX_MT.out.index, failOnMismatch:true, failOnDuplicate:true) .set { ch_in_remdup } REMOVE_DUPLICATES_MT(ch_in_remdup, ch_genome_fasta) TABIX_TABIX_MT2(REMOVE_DUPLICATES_MT.out.vcf) REMOVE_DUPLICATES_MT.out.vcf - .map{ it -> it[1]} + .map{ _meta, vcf -> vcf} .toSortedList{a, b -> a.name <=> b.name} .toList() .set { file_list_vcf } - TABIX_TABIX_MT2.out.tbi - .map{ it -> it[1]} + TABIX_TABIX_MT2.out.index + .map{ _meta, vcf -> vcf} .toSortedList{a, b -> a.name <=> b.name} .toList() .set { file_list_tbi } @@ -91,13 +90,17 @@ workflow POSTPROCESS_MT_CALLS { return [meta, vcf, tbi] }.set { ch_case_vcf } - BCFTOOLS_MERGE_MT( ch_case_vcf.multiple, - ch_genome_fasta, - ch_genome_fai, - [[:],[]] + BCFTOOLS_MERGE_MT( + ch_case_vcf.multiple.map { meta, vcf, tbi -> return [meta, vcf, tbi, []] }, + ch_genome_fasta.join(ch_genome_fai, failOnMismatch:true, failOnDuplicate:true).collect() ) - BCFTOOLS_MERGE_MT.out.vcf + SPLIT_MULTIALLELICS_POSTMERGE_MT( + BCFTOOLS_MERGE_MT.out.vcf.join(BCFTOOLS_MERGE_MT.out.index, failOnMismatch:true, failOnDuplicate:true).collect(), + ch_genome_fasta + ) + + SPLIT_MULTIALLELICS_POSTMERGE_MT.out.vcf .mix(ch_case_vcf.single) .set { ch_addfoundintag_in } @@ -109,33 +112,21 @@ workflow POSTPROCESS_MT_CALLS { .set { ch_varcallerinfo } ADD_VARCALLER_TO_BED (ch_varcallerinfo).gz_tbi - .map{meta,bed,tbi -> return [bed, tbi]} + .map{_meta,bed,tbi -> return [bed, tbi]} .set{ch_varcallerbed} ch_addfoundintag_in - .join(TABIX_TABIX_MERGE.out.tbi) + .join(TABIX_TABIX_MERGE.out.index) .combine(ch_varcallerbed) + .combine(ch_foundin_header) + .map { meta, vcf, vcf_tbi, bed, bed_tbi, hdr -> return [meta, vcf, vcf_tbi, bed, bed_tbi, [], hdr, []] } .set { ch_annotate_in } - BCFTOOLS_ANNOTATE(ch_annotate_in,ch_foundin_header) + BCFTOOLS_ANNOTATE(ch_annotate_in) TABIX_ANNOTATE(BCFTOOLS_ANNOTATE.out.vcf) - ch_versions = ch_versions.mix(PICARD_LIFTOVERVCF.out.versions.first()) - ch_versions = ch_versions.mix(GATK4_MERGEVCFS_LIFT_UNLIFT_MT.out.versions.first()) - ch_versions = ch_versions.mix(GATK4_VARIANTFILTRATION_MT.out.versions.first()) - ch_versions = ch_versions.mix(SPLIT_MULTIALLELICS_MT.out.versions.first()) - ch_versions = ch_versions.mix(REMOVE_DUPLICATES_MT.out.versions.first()) - ch_versions = ch_versions.mix(BCFTOOLS_MERGE_MT.out.versions) - ch_versions = ch_versions.mix(ADD_VARCALLER_TO_BED.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(TABIX_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX_MERGE.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX_MT.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX_MT2.out.versions) - emit: - vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] - tbi = TABIX_ANNOTATE.out.tbi // channel: [ val(meta), path(tbi) ] - versions = ch_versions // channel: [ path(versions.yml) ] + tbi = TABIX_ANNOTATE.out.index // channel: [ val(meta), path(tbi) ] + vcf = BCFTOOLS_ANNOTATE.out.vcf // channel: [ val(meta), path(vcf) ] } diff --git a/subworkflows/local/postprocess_MT_calls/tests/main.nf.test b/subworkflows/local/postprocess_MT_calls/tests/main.nf.test new file mode 100644 index 000000000..bcdc5217e --- /dev/null +++ b/subworkflows/local/postprocess_MT_calls/tests/main.nf.test @@ -0,0 +1,52 @@ +nextflow_workflow { + + name "Test Workflow POSTPROCESS_MT_CALLS" + script "subworkflows/local/postprocess_MT_calls/main.nf" + workflow "POSTPROCESS_MT_CALLS" + + tag "subworkflows" + tag "postprocess_MT_calls" + + tag "gatk4/mergevcfs" + tag "gatk4/variantfiltration" + tag "bcftools/norm" + tag "tabix/tabix" + tag "bcftools/merge" + tag "picard/liftovervcf" + tag "bcftools/annotate" + tag "local/add_varcallername_to_bed" + + test("POSTPROCESS_MT_CALLS - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([id:'justhusky']) + input[1] = channel.of(file('https://raw.githubusercontent.com/nf-core/raredisease/refs/heads/master/assets/foundin.hdr', checkIfExists: true)).collect() + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.dict', checkIfExists: true)]).collect() + input[4] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)]).collect() + input[5] = channel.of([[id:'mt'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)]).collect() + input[6] = channel.of([ + [id:'earlycasualcaiman', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'reference/vcfanno_gnomad_mt.vcf.gz', checkIfExists: true) + ]) + input[7] = channel.of([[id:'genome'], file(params.pipelines_testdata_base_path + 'reference/mt_shift8000.back_chain', checkIfExists: true)]).collect() + input[8] = channel.of([ + [id:'earlycasualcaiman', case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'reference/grch38_gnomad_reformated_-r3.1.1-.vcf.gz', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/postprocess_MT_calls/tests/main.nf.test.snap b/subworkflows/local/postprocess_MT_calls/tests/main.nf.test.snap new file mode 100644 index 000000000..373ecda38 --- /dev/null +++ b/subworkflows/local/postprocess_MT_calls/tests/main.nf.test.snap @@ -0,0 +1,45 @@ +{ + "POSTPROCESS_MT_CALLS - stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky" + }, + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-05-29T16:03:50.71832229", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/prepare_references.nf b/subworkflows/local/prepare_references.nf deleted file mode 100644 index e651a5218..000000000 --- a/subworkflows/local/prepare_references.nf +++ /dev/null @@ -1,225 +0,0 @@ -// -// Prepare reference files -// - -include { BEDTOOLS_SLOP as BEDTOOLS_PAD_TARGET_BED } from '../../modules/nf-core/bedtools/slop/main' -include { BWA_INDEX as BWA_INDEX_GENOME } from '../../modules/nf-core/bwa/index/main' -include { BWA_INDEX as BWA_INDEX_MT } from '../../modules/nf-core/bwa/index/main' -include { BWA_INDEX as BWA_INDEX_MT_SHIFT } from '../../modules/nf-core/bwa/index/main' -include { BWAMEM2_INDEX as BWAMEM2_INDEX_GENOME } from '../../modules/nf-core/bwamem2/index/main' -include { BWAMEM2_INDEX as BWAMEM2_INDEX_MT } from '../../modules/nf-core/bwamem2/index/main' -include { BWAMEM2_INDEX as BWAMEM2_INDEX_MT_SHIFT } from '../../modules/nf-core/bwamem2/index/main' -include { BWAMEME_INDEX as BWAMEME_INDEX_GENOME } from '../../modules/nf-core/bwameme/index/main' -include { CAT_CAT as CAT_CAT_BAIT } from '../../modules/nf-core/cat/cat/main' -include { GATK4_BEDTOINTERVALLIST as GATK_BILT } from '../../modules/nf-core/gatk4/bedtointervallist/main' -include { GATK4_CREATESEQUENCEDICTIONARY as GATK_SD } from '../../modules/nf-core/gatk4/createsequencedictionary/main' -include { GATK4_CREATESEQUENCEDICTIONARY as GATK_SD_MT } from '../../modules/nf-core/gatk4/createsequencedictionary/main' -include { GATK4_INTERVALLISTTOOLS as GATK_ILT } from '../../modules/nf-core/gatk4/intervallisttools/main' -include { GATK4_SHIFTFASTA as GATK_SHIFTFASTA } from '../../modules/nf-core/gatk4/shiftfasta/main' -include { GET_CHROM_SIZES } from '../../modules/local/get_chrom_sizes' -include { RTGTOOLS_FORMAT } from '../../modules/nf-core/rtgtools/format/main' -include { SAMTOOLS_FAIDX as SAMTOOLS_EXTRACT_MT } from '../../modules/nf-core/samtools/faidx/main' -include { SAMTOOLS_FAIDX as SAMTOOLS_FAIDX_GENOME } from '../../modules/nf-core/samtools/faidx/main' -include { SAMTOOLS_FAIDX as SAMTOOLS_FAIDX_MT } from '../../modules/nf-core/samtools/faidx/main' -include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_GENOME } from '../../modules/nf-core/sentieon/bwaindex/main' -include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_MT } from '../../modules/nf-core/sentieon/bwaindex/main' -include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_MT_SHIFT } from '../../modules/nf-core/sentieon/bwaindex/main' -include { TABIX_BGZIPTABIX as TABIX_PBT } from '../../modules/nf-core/tabix/bgziptabix/main' -include { TABIX_BGZIPTABIX as TABIX_BGZIPINDEX_PADDED_BED } from '../../modules/nf-core/tabix/bgziptabix/main' -include { TABIX_BGZIPTABIX as TABIX_BGZIPINDEX_VCFANNOEXTRA } from '../../modules/nf-core/tabix/bgziptabix/main' -include { TABIX_TABIX as TABIX_VCFANNOEXTRA } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_DBSNP } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_GNOMAD_AF } from '../../modules/nf-core/tabix/tabix/main' -include { TABIX_TABIX as TABIX_PT } from '../../modules/nf-core/tabix/tabix/main' -include { UNTAR as UNTAR_VEP_CACHE } from '../../modules/nf-core/untar/main' - -workflow PREPARE_REFERENCES { - take: - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(fai) ] - ch_mt_fasta // channel: [mandatory for dedicated mt analysis] [ val(meta), path(fasta) ] - ch_gnomad_af_tab // channel: [optional; used in for snv annotation] [ val(meta), path(tab) ] - ch_known_dbsnp // channel: [optional; used only by sentieon] [ val(meta), path(vcf) ] - ch_target_bed // channel: [mandatory for WES] [ path(bed) ] - ch_vcfanno_extra_unprocessed // channel: [mandatory] [ val(meta), path(vcf) ] - ch_vep_cache // channel: [mandatory for annotation] [ path(cache) ] - - main: - ch_versions = Channel.empty() - ch_tbi = Channel.empty() - ch_bgzip_tbi = Channel.empty() - ch_bwa = Channel.empty() - ch_sentieonbwa = Channel.empty() - ch_vcfanno_extra = Channel.empty() - ch_vcfanno_bgzip = Channel.empty() - ch_vcfanno_index = Channel.empty() - - // Genome indices - SAMTOOLS_FAIDX_GENOME(ch_genome_fasta, [[],[]]) - GATK_SD(ch_genome_fasta) - ch_fai = Channel.empty().mix(ch_genome_fai, SAMTOOLS_FAIDX_GENOME.out.fai).collect() - ch_dict = Channel.empty().mix(ch_genome_dictionary, GATK_SD.out.dict).collect() - GET_CHROM_SIZES( ch_fai ) - - // Genome alignment indices - BWA_INDEX_GENOME(ch_genome_fasta).index.set{ch_bwa} - BWAMEM2_INDEX_GENOME(ch_genome_fasta) - BWAMEME_INDEX_GENOME(ch_genome_fasta) - SENTIEON_BWAINDEX_GENOME(ch_genome_fasta).index.set{ch_sentieonbwa} - - // MT genome indices - SAMTOOLS_EXTRACT_MT(ch_genome_fasta, ch_fai) - ch_mt_fasta_in = Channel.empty().mix(ch_mt_fasta, SAMTOOLS_EXTRACT_MT.out.fa).collect() - SAMTOOLS_FAIDX_MT(ch_mt_fasta_in, [[],[]]) - GATK_SD_MT(ch_mt_fasta_in) - GATK_SHIFTFASTA(ch_mt_fasta_in, SAMTOOLS_FAIDX_MT.out.fai, GATK_SD_MT.out.dict) - - // MT alignment indices - BWAMEM2_INDEX_MT(ch_mt_fasta_in) - BWA_INDEX_MT(ch_mt_fasta_in) - SENTIEON_BWAINDEX_MT(ch_mt_fasta_in) - ch_bwa_mt = Channel.empty().mix(SENTIEON_BWAINDEX_MT.out.index, BWA_INDEX_MT.out.index).collect() - - BWAMEM2_INDEX_MT_SHIFT(GATK_SHIFTFASTA.out.shift_fa) - BWA_INDEX_MT_SHIFT(GATK_SHIFTFASTA.out.shift_fa) - SENTIEON_BWAINDEX_MT_SHIFT(GATK_SHIFTFASTA.out.shift_fa) - ch_bwa_mtshift = Channel.empty().mix(SENTIEON_BWAINDEX_MT_SHIFT.out.index, BWA_INDEX_MT_SHIFT.out.index).collect() - GATK_SHIFTFASTA.out.intervals - .multiMap{ meta, files -> - shift_intervals: - def ind = files.findIndexValues {it.toString().endsWith("shifted.intervals")} - files[ind] - intervals: - ind = files.findIndexValues {!(it.toString().endsWith("shifted.intervals"))} - files[ind] - } - .set {ch_shiftfasta_mtintervals} - - // Vcf, tab and bed indices - TABIX_DBSNP(ch_known_dbsnp) - TABIX_GNOMAD_AF(ch_gnomad_af_tab) - - // Index target bed file in case of gz input - TABIX_PT(ch_target_bed) - ch_target_bed - .join(TABIX_PT.out.tbi) - .set{ ch_trgt_bed_tbi } - // Compress and index target bed file in case of uncompressed input - TABIX_PBT(ch_target_bed).gz_tbi - .set { ch_bgzip_tbi } - ch_target_bed_gz_tbi = Channel.empty() - .mix(ch_trgt_bed_tbi, ch_bgzip_tbi) - - ch_vcfanno_extra_unprocessed - .branch { it -> - bgzipindex: !it[1].toString().endsWith(".gz") - index: it[1].toString().endsWith(".gz") - } - .set { ch_vcfanno_tabix_in } - - TABIX_VCFANNOEXTRA(ch_vcfanno_tabix_in.index).tbi - .join(ch_vcfanno_tabix_in.index) - .map { meta, tbi, vcf -> return [[vcf,tbi]]} - .set {ch_vcfanno_index} - - TABIX_BGZIPINDEX_VCFANNOEXTRA(ch_vcfanno_tabix_in.bgzipindex) - Channel.empty() - .mix(TABIX_BGZIPINDEX_VCFANNOEXTRA.out.gz_tbi, TABIX_BGZIPINDEX_VCFANNOEXTRA.out.gz_csi) - .map { meta, vcf, index -> return [[vcf,index]] } - .set {ch_vcfanno_bgzip} - - Channel.empty() - .mix(ch_vcfanno_bgzip, ch_vcfanno_index) - .collect() - .set{ch_vcfanno_extra} - - // Pad bed file - BEDTOOLS_PAD_TARGET_BED( - ch_target_bed, - ch_fai.map { _meta, fai -> return fai } - ) - TABIX_BGZIPINDEX_PADDED_BED(BEDTOOLS_PAD_TARGET_BED.out.bed).gz_tbi - .set { ch_target_bed_gz_tbi } - - // Generate bait and target intervals - GATK_BILT(ch_target_bed, ch_dict).interval_list - GATK_ILT(GATK_BILT.out.interval_list) - GATK_ILT.out.interval_list - .collect{ it[1] } - .map { it -> - def meta = it[0].toString().split("_split")[0].split("/")[-1] + "_bait.intervals_list" - return [[id:meta], it] - } - .set { ch_bait_intervals_cat_in } - CAT_CAT_BAIT ( ch_bait_intervals_cat_in ) - UNTAR_VEP_CACHE (ch_vep_cache) - - // RTG tools - ch_genome_fasta.map { meta, fasta -> return [meta, fasta, [], [] ] } - .set {ch_rtgformat_in} - RTGTOOLS_FORMAT(ch_rtgformat_in) - - // Gather versions - ch_versions = ch_versions.mix(BWA_INDEX_GENOME.out.versions) - ch_versions = ch_versions.mix(BWAMEM2_INDEX_GENOME.out.versions) - ch_versions = ch_versions.mix(BWAMEME_INDEX_GENOME.out.versions) - ch_versions = ch_versions.mix(SENTIEON_BWAINDEX_GENOME.out.versions) - ch_versions = ch_versions.mix(SAMTOOLS_FAIDX_GENOME.out.versions) - ch_versions = ch_versions.mix(GATK_SD.out.versions) - ch_versions = ch_versions.mix(GET_CHROM_SIZES.out.versions) - ch_versions = ch_versions.mix(SAMTOOLS_EXTRACT_MT.out.versions) - ch_versions = ch_versions.mix(SAMTOOLS_FAIDX_MT.out.versions) - ch_versions = ch_versions.mix(GATK_SD_MT.out.versions) - ch_versions = ch_versions.mix(GATK_SHIFTFASTA.out.versions) - ch_versions = ch_versions.mix(BWAMEM2_INDEX_MT.out.versions) - ch_versions = ch_versions.mix(BWA_INDEX_MT.out.versions) - ch_versions = ch_versions.mix(SENTIEON_BWAINDEX_MT.out.versions) - ch_versions = ch_versions.mix(BWAMEM2_INDEX_MT_SHIFT.out.versions) - ch_versions = ch_versions.mix(BWA_INDEX_MT_SHIFT.out.versions) - ch_versions = ch_versions.mix(SENTIEON_BWAINDEX_MT_SHIFT.out.versions) - ch_versions = ch_versions.mix(TABIX_GNOMAD_AF.out.versions) - ch_versions = ch_versions.mix(TABIX_PT.out.versions) - ch_versions = ch_versions.mix(TABIX_PBT.out.versions) - ch_versions = ch_versions.mix(TABIX_BGZIPINDEX_VCFANNOEXTRA.out.versions) - ch_versions = ch_versions.mix(TABIX_VCFANNOEXTRA.out.versions) - ch_versions = ch_versions.mix(TABIX_DBSNP.out.versions) - ch_versions = ch_versions.mix(BEDTOOLS_PAD_TARGET_BED.out.versions) - ch_versions = ch_versions.mix(TABIX_BGZIPINDEX_PADDED_BED.out.versions) - ch_versions = ch_versions.mix(GATK_BILT.out.versions) - ch_versions = ch_versions.mix(GATK_ILT.out.versions) - ch_versions = ch_versions.mix(CAT_CAT_BAIT.out.versions) - ch_versions = ch_versions.mix(UNTAR_VEP_CACHE.out.versions) - ch_versions = ch_versions.mix(RTGTOOLS_FORMAT.out.versions) - - emit: - genome_bwa_index = Channel.empty().mix(ch_bwa, ch_sentieonbwa).collect() // channel: [ val(meta), path(index) ] - genome_bwamem2_index = BWAMEM2_INDEX_GENOME.out.index.collect() // channel: [ val(meta), path(index) ] - genome_bwameme_index = BWAMEME_INDEX_GENOME.out.index.collect() // channel: [ val(meta), path(index) ] - genome_chrom_sizes = GET_CHROM_SIZES.out.sizes.collect() // channel: [ path(sizes) ] - genome_fai = ch_fai // channel: [ val(meta), path(fai) ] - genome_dict = ch_dict // channel: [ val(meta), path(dict) ] - sdf = RTGTOOLS_FORMAT.out.sdf // channel: [ val (meta), path(intervals) ] - mt_intervals = ch_shiftfasta_mtintervals.intervals.collect() // channel: [ path(intervals) ] - mt_bwa_index = ch_bwa_mt // channel: [ val(meta), path(index) ] - mt_bwamem2_index = BWAMEM2_INDEX_MT.out.index.collect() // channel: [ val(meta), path(index) ] - mt_dict = GATK_SD_MT.out.dict.collect() // channel: [ val(meta), path(dict) ] - mt_fasta = ch_mt_fasta_in.collect() // channel: [ val(meta), path(fasta) ] - mt_fai = SAMTOOLS_FAIDX_MT.out.fai.collect() // channel: [ val(meta), path(fai) ] - mtshift_intervals = ch_shiftfasta_mtintervals.shift_intervals.collect() // channel: [ path(intervals) ] - mtshift_backchain = GATK_SHIFTFASTA.out.shift_back_chain.collect() // channel: [ val(meta), path(backchain) ] - mtshift_dict = GATK_SHIFTFASTA.out.dict // channel: [ val(meta), path(dict) ] - mtshift_fai = GATK_SHIFTFASTA.out.shift_fai.collect() // channel: [ val(meta), path(fai) ] - mtshift_fasta = GATK_SHIFTFASTA.out.shift_fa.collect() // channel: [ val(meta), path(fasta) ] - mtshift_bwa_index = ch_bwa_mtshift // channel: [ val(meta), path(index) ] - mtshift_bwamem2_index = BWAMEM2_INDEX_MT_SHIFT.out.index.collect() // channel: [ val(meta), path(index) ] - gnomad_af_idx = TABIX_GNOMAD_AF.out.tbi.collect() // channel: [ val(meta), path(fasta) ] - known_dbsnp_tbi = TABIX_DBSNP.out.tbi.collect() // channel: [ val(meta), path(fasta) ] - target_bed = ch_target_bed_gz_tbi.collect() // channel: [ val(meta), path(bed), path(tbi) ] - vcfanno_extra = ch_vcfanno_extra.ifEmpty([[]]) // channel: [ [path(vcf), path(tbi)] ] - bait_intervals = CAT_CAT_BAIT.out.file_out.map{ meta, inter -> inter}.collect().ifEmpty([[]]) // channel: [ path(intervals) ] - target_intervals = GATK_BILT.out.interval_list.map{ meta, inter -> inter}.collect() // channel: [ path(interval_list) ] - vep_resources = UNTAR_VEP_CACHE.out.untar.map{meta, files -> [files]}.collect() // channel: [ path(cache) ] - versions = ch_versions // channel: [ path(versions.yml) ] - -} diff --git a/subworkflows/local/prepare_references/main.nf b/subworkflows/local/prepare_references/main.nf new file mode 100644 index 000000000..9f9aa8bc8 --- /dev/null +++ b/subworkflows/local/prepare_references/main.nf @@ -0,0 +1,317 @@ + +// +// Prepare reference files +// + +include { BEDTOOLS_SLOP as BEDTOOLS_PAD_TARGET_BED } from '../../../modules/nf-core/bedtools/slop/main' +include { BWAFASTALIGN_INDEX as BWAFASTALIGN_INDEX_GENOME } from '../../../modules/nf-core/bwafastalign/index/main' +include { BWAMEM2_INDEX as BWAMEM2_INDEX_GENOME } from '../../../modules/nf-core/bwamem2/index/main' +include { BWAMEM2_INDEX as BWAMEM2_INDEX_MT } from '../../../modules/nf-core/bwamem2/index/main' +include { BWAMEM2_INDEX as BWAMEM2_INDEX_MT_SHIFT } from '../../../modules/nf-core/bwamem2/index/main' +include { BWAMEME_INDEX as BWAMEME_INDEX_GENOME } from '../../../modules/nf-core/bwameme/index/main' +include { BWA_INDEX as BWA_INDEX_GENOME } from '../../../modules/nf-core/bwa/index/main' +include { BWA_INDEX as BWA_INDEX_MT } from '../../../modules/nf-core/bwa/index/main' +include { BWA_INDEX as BWA_INDEX_MT_SHIFT } from '../../../modules/nf-core/bwa/index/main' +include { CAT_CAT as CAT_CAT_BAIT } from '../../../modules/nf-core/cat/cat/main' +include { GATK4_BEDTOINTERVALLIST as GATK_BILT } from '../../../modules/nf-core/gatk4/bedtointervallist/main' +include { GATK4_CREATESEQUENCEDICTIONARY as GATK_SD } from '../../../modules/nf-core/gatk4/createsequencedictionary/main' +include { GATK4_CREATESEQUENCEDICTIONARY as GATK_SD_MT } from '../../../modules/nf-core/gatk4/createsequencedictionary/main' +include { GATK4_INTERVALLISTTOOLS as GATK_ILT } from '../../../modules/nf-core/gatk4/intervallisttools/main' +include { GATK4_SHIFTFASTA as GATK_SHIFTFASTA } from '../../../modules/nf-core/gatk4/shiftfasta/main' +include { GET_CHROM_SIZES } from '../../../modules/local/get_chrom_sizes' +include { HISAT2_BUILD as HISAT2_INDEX_GENOME } from '../../../modules/nf-core/hisat2/build' +include { LAST_LASTDB as LAST_INDEX_MT } from '../../../modules/nf-core/last/lastdb' +include { RTGTOOLS_FORMAT } from '../../../modules/nf-core/rtgtools/format/main' +include { SAMTOOLS_FAIDX as SAMTOOLS_EXTRACT_MT } from '../../../modules/nf-core/samtools/faidx/main' +include { SAMTOOLS_FAIDX as SAMTOOLS_FAIDX_GENOME } from '../../../modules/nf-core/samtools/faidx/main' +include { SAMTOOLS_FAIDX as SAMTOOLS_FAIDX_MT } from '../../../modules/nf-core/samtools/faidx/main' +include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_GENOME } from '../../../modules/nf-core/sentieon/bwaindex/main' +include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_MT } from '../../../modules/nf-core/sentieon/bwaindex/main' +include { SENTIEON_BWAINDEX as SENTIEON_BWAINDEX_MT_SHIFT } from '../../../modules/nf-core/sentieon/bwaindex/main' +include { TABIX_BGZIPTABIX as TABIX_BGZIPINDEX_PADDED_BED } from '../../../modules/nf-core/tabix/bgziptabix/main' +include { TABIX_BGZIPTABIX as TABIX_BGZIPINDEX_VCFANNOEXTRA } from '../../../modules/nf-core/tabix/bgziptabix/main' +include { TABIX_TABIX as TABIX_DBSNP } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_GNOMAD_AF } from '../../../modules/nf-core/tabix/tabix/main' +include { TABIX_TABIX as TABIX_VCFANNOEXTRA } from '../../../modules/nf-core/tabix/tabix/main' +include { UNTAR as UNTAR_VEP_CACHE } from '../../../modules/nf-core/untar/main' + +workflow PREPARE_REFERENCES { + take: + val_aligner // String: "bwa", "bwafastalign", "bwamem2", "sentieon" or "bwameme" + val_analysis_type // String: "wgs", "wes", or "mito" + val_bwa // String: path to bwa index + val_bwafastalign // String: path to bwafastalign index + val_bwamem2 // String: path to bwamem2 index + val_bwameme // String: path to bwameme index + val_fai // String: path to genome fasta index + val_fasta // String: path to genome fasta + val_gnomad_af // String: path to gnomad allele frequency file + val_gnomad_af_idx // String: path to gnomad allele frequency file's index + val_known_dbsnp // String: path to dbsnp file + val_known_dbsnp_tbi // String: path to dbsnp file's index + val_mtaligner // String: "bwa", "bwamem2", or "sentieon" + val_mtfasta // String: path to mitochondrial fasta + val_run_mt_for_wes // Boolean + val_run_rtgvcfeval // Boolean + val_sdf // String: path to sdf file + val_genome_dict // String: path to genome dictionary + val_target_bed // String: path to target bed file + val_vcfanno_extra // String: path to additional annotation files used by vcfanno + val_vep_cache // String: path to vep cache folder + + + main: + ch_bait_intervals = channel.empty() + ch_genome_bwa_index = channel.empty() + ch_genome_bwafastalign_index = channel.empty() + ch_genome_bwameme_index = channel.empty() + ch_genome_bwamem2_index = channel.empty() + ch_genome_hisat2_index = channel.empty() + ch_mt_last_index = channel.empty() + ch_gnomad_af_idx = channel.empty() + ch_dbsnp = channel.value([[:],[]]) + ch_dbsnp_tbi = channel.value([[:],[]]) + ch_mt_bwa_index = channel.empty() + ch_mt_bwamem2_index = channel.empty() + ch_mtshift_bwa_index = channel.empty() + ch_mtshift_bwamem2_index = channel.empty() + ch_mtshift_backchain = channel.empty() + ch_mtshift_dict = channel.empty() + ch_mtshift_fai = channel.empty() + ch_mtshift_fasta = channel.empty() + ch_mt_dict = channel.empty() + ch_mt_fai = channel.empty() + ch_mt_fasta = channel.empty() + ch_sdf = channel.empty() + ch_shiftfasta_mtintervals = channel.empty() + ch_shiftfasta_mtshiftintervals = channel.empty() + ch_target_bed_gz_tbi = channel.value([[:],[],[]]) + ch_target_intervals = channel.empty() + ch_vcfanno_extra = channel.value([[]]) + ch_vep_resources = channel.value([[]]) + + ch_genome_fasta = channel.fromPath(val_fasta).map { it -> [[id:it.simpleName], it] }.collect() + // + // Genome indices + // + if (!val_fai) { + SAMTOOLS_FAIDX_GENOME(ch_genome_fasta.map{meta, fasta -> return [meta,fasta,[]]}, true) + ch_genome_fai = SAMTOOLS_FAIDX_GENOME.out.fai.collect() + ch_chrom_sizes = SAMTOOLS_FAIDX_GENOME.out.sizes.map {_meta, sizes -> sizes}.collect() + } else { + ch_genome_fai = channel.fromPath(val_fai).map {fai -> [[id:fai.simpleName], fai]}.collect() + ch_chrom_sizes = GET_CHROM_SIZES( ch_genome_fai ).sizes.collect() + } + + + if (!val_genome_dict) { + ch_genome_dict = GATK_SD(ch_genome_fasta).dict.collect() + } else { + ch_genome_dict = channel.fromPath(val_genome_dict).map {it -> [[id:it.simpleName], it]}.collect() + } + // + // Genome alignment indices + // + if (!val_bwa) { + if (!val_aligner.equals("sentieon") || val_mtaligner.equals("bwa")) { + ch_genome_bwa_index = BWA_INDEX_GENOME(ch_genome_fasta).index.collect() + } + if (val_aligner.equals("sentieon") || val_mtaligner.equals("sentieon")) { + ch_genome_bwa_index = SENTIEON_BWAINDEX_GENOME(ch_genome_fasta).index.collect() + } + } else if (val_bwa) { + ch_genome_bwa_index = channel.fromPath(val_bwa).map {it -> [[id:it.simpleName], it]}.collect() + } + + if (!val_bwamem2 && (val_aligner.equals("bwamem2") || val_mtaligner.equals("bwamem2"))) { + ch_genome_bwamem2_index = BWAMEM2_INDEX_GENOME(ch_genome_fasta).index.collect() + } else if (val_bwamem2) { + ch_genome_bwamem2_index = channel.fromPath(val_bwamem2).map {it -> [[id:it.simpleName], it]}.collect() + } + + if (!val_bwamem2 && val_aligner.equals("bwameme")) { + ch_genome_bwameme_index = BWAMEME_INDEX_GENOME(ch_genome_fasta).index.collect() + } else if (val_bwameme) { + ch_genome_bwameme_index = channel.fromPath(val_bwameme).map {it -> [[id:it.simpleName], it]}.collect() + } + + if (!val_bwafastalign && val_aligner.equals("bwafastalign")) { + ch_genome_bwafastalign_index = BWAFASTALIGN_INDEX_GENOME(ch_genome_fasta).index.collect() + } else if (val_bwafastalign) { + ch_genome_bwafastalign_index = channel.fromPath(val_bwafastalign).map {it -> [[id:it.simpleName], it]}.collect() + } + // + // MT genome indices + // + if (val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) { + if (!val_mtfasta) { + ch_mt_fasta = SAMTOOLS_EXTRACT_MT(ch_genome_fasta.join(ch_genome_fai), false).fa.collect() + } else { + ch_mt_fasta = channel.fromPath(val_mtfasta).map { it -> [[id:it.simpleName], it] }.collect() + } + + ch_mt_fai = SAMTOOLS_FAIDX_MT(ch_mt_fasta.map{meta, fasta -> return [meta, fasta,[]]}, false).fai.collect() + ch_mt_dict = GATK_SD_MT(ch_mt_fasta).dict.collect() + + ch_genome_hisat2_index = HISAT2_INDEX_GENOME(ch_genome_fasta,[[:],[]], [[:],[]]).index.collect() + ch_mt_last_index = LAST_INDEX_MT(ch_mt_fasta).index.collect() + + GATK_SHIFTFASTA(ch_mt_fasta, ch_mt_fai, ch_mt_dict) + + ch_mtshift_backchain = GATK_SHIFTFASTA.out.shift_back_chain.collect() + ch_mtshift_dict = GATK_SHIFTFASTA.out.dict.collect() + ch_mtshift_fai = GATK_SHIFTFASTA.out.shift_fai.collect() + ch_mtshift_fasta = GATK_SHIFTFASTA.out.shift_fa.collect() + + GATK_SHIFTFASTA.out.intervals + .multiMap{ _meta, files -> + shift_intervals: + def ind = files.findIndexValues {file -> file.toString().endsWith("shifted.intervals")} + files[ind] + intervals: + ind = files.findIndexValues {file -> !(file.toString().endsWith("shifted.intervals"))} + files[ind] + } + .set {ch_mtintervals} + ch_shiftfasta_mtintervals = ch_mtintervals.intervals.collect() + ch_shiftfasta_mtshiftintervals = ch_mtintervals.shift_intervals.collect() + + + } + // + // MT alignment indices + // + if ((val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) && val_mtaligner.equals("bwamem2")) { + ch_mt_bwamem2_index = BWAMEM2_INDEX_MT(ch_mt_fasta).index.collect() + ch_mtshift_bwamem2_index = BWAMEM2_INDEX_MT_SHIFT(ch_mtshift_fasta).index.collect() + } + if ((val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) && val_mtaligner.equals("bwa")) { + ch_mt_bwa_index = BWA_INDEX_MT(ch_mt_fasta).index.collect() + ch_mtshift_bwa_index = BWA_INDEX_MT_SHIFT(ch_mtshift_fasta).index.collect() + } + if ((val_analysis_type.matches("wgs|mito") || val_run_mt_for_wes) && val_mtaligner.equals("sentieon")) { + ch_mt_bwa_index = SENTIEON_BWAINDEX_MT(ch_mt_fasta).index.collect() + ch_mtshift_bwa_index = SENTIEON_BWAINDEX_MT_SHIFT(ch_mtshift_fasta).index.collect() + } + // + // Vcf, tab and bed indices + // + if (val_known_dbsnp) { + ch_dbsnp = channel.fromPath(val_known_dbsnp).map{ it -> [[id:it.simpleName], it] }.collect() + if (val_known_dbsnp_tbi) { + ch_dbsnp_tbi = channel.fromPath(val_known_dbsnp_tbi).map{ it -> [[id:it.simpleName], it] }.collect() + } else { + ch_dbsnp_tbi = TABIX_DBSNP(ch_dbsnp).index.collect() + } + } + + if (val_gnomad_af) { + ch_gnomad_af = channel.fromPath(val_gnomad_af).map{ it -> [[id:it.simpleName], it] }.collect() + if (val_gnomad_af_idx) { + ch_gnomad_idx = channel.fromPath(val_gnomad_af_idx).map{ it -> [[id:it.simpleName], it] }.collect() + } else { + ch_gnomad_idx = TABIX_GNOMAD_AF(ch_gnomad_af).index.collect() + } + ch_gnomad_af_idx = ch_gnomad_af.join(ch_gnomad_idx).map {_meta, tab, idx -> [tab,idx]}.collect() + } + // + // Index target bed file + // + if (val_target_bed) { + ch_target_bed = channel.fromPath(val_target_bed).map{ it -> [[id:it.simpleName], it] }.collect() + + BEDTOOLS_PAD_TARGET_BED( + ch_target_bed, + ch_genome_fai.map { _meta, fai -> return fai } + ) + ch_target_bed_gz_tbi = TABIX_BGZIPINDEX_PADDED_BED(BEDTOOLS_PAD_TARGET_BED.out.bed).gz_index + + ch_target_intervals = GATK_BILT(ch_target_bed, ch_genome_dict).interval_list.map{ _meta, inter -> inter}.collect() + + GATK_ILT(GATK_BILT.out.interval_list) + + GATK_ILT.out.interval_list + .collect{ _meta, list -> list } + .map { list -> + // list is e.g. [/path/mybed_split_0001.interval_list, ...]; strip the _split suffix + // and directory to get the base name (e.g. "mybed"), then build the merged output name + def meta = list.toString().split("_split")[0].split("/")[-1] + "_bait.intervals_list" + return [[id:meta], list] + } + .set { ch_bait_intervals_cat_in } + + ch_bait_intervals = CAT_CAT_BAIT ( ch_bait_intervals_cat_in ).file_out.map {_meta, inter -> inter}.collect().ifEmpty([[]]) + + } + // + // Prepare vcfanno extra files + // + if (val_vcfanno_extra) { + ch_vcfanno_tabix_in = channel.fromPath(val_vcfanno_extra).map { it -> [[id:it.baseName], it] } + + if (val_vcfanno_extra.endsWith(".gz")) { + TABIX_VCFANNOEXTRA(ch_vcfanno_tabix_in).index + .join(ch_vcfanno_tabix_in) + .map { _meta, tbi, vcf -> return [[vcf,tbi]]} + .set {ch_vcfanno_extra} + } else { + TABIX_BGZIPINDEX_VCFANNOEXTRA(ch_vcfanno_tabix_in) + channel.empty() + .mix(TABIX_BGZIPINDEX_VCFANNOEXTRA.out.gz_index) + .map { _meta, vcf, index -> return [[vcf,index]] } + .set {ch_vcfanno_extra} + } + } + // + // Prepare vep cache files + // + if (val_vep_cache) { + if (val_vep_cache.endsWith("tar.gz")) { + ch_vep_resources = UNTAR_VEP_CACHE (channel.fromPath(val_vep_cache).map { it -> [[id:'vep_cache'], it] }.collect()).untar.map{ _meta, files -> [files]}.collect() + } else { + ch_vep_resources = channel.fromPath(val_vep_cache).collect() + } + } + // + // RTG tools + // + if (!val_sdf && val_run_rtgvcfeval) { + ch_genome_fasta.map { meta, fasta -> return [meta, fasta, [], [] ] } + .set {ch_rtgformat_in} + ch_sdf = RTGTOOLS_FORMAT(ch_rtgformat_in).out.sdf + } + + emit: + bait_intervals = ch_bait_intervals // channel:[ path(intervals) ] + dbsnp = ch_dbsnp // channel:[ val(meta), path(dbsnp) ] + dbsnp_tbi = ch_dbsnp_tbi // channel:[ val(meta), path(dbsnp_idx) ] + genome_bwa_index = ch_genome_bwa_index // channel:[ val(meta), path(index) ] + genome_bwafastalign_index = ch_genome_bwafastalign_index // channel:[ val(meta), path(index) ] + genome_bwamem2_index = ch_genome_bwamem2_index // channel:[ val(meta), path(index) ] + genome_bwameme_index = ch_genome_bwameme_index // channel:[ val(meta), path(index) ] + genome_chrom_sizes = ch_chrom_sizes // channel:[ path(sizes) ] + genome_fai = ch_genome_fai // channel:[ val(meta), path(fai) ] + genome_fasta = ch_genome_fasta // channel:[ val(meta), path(fasta) ] + genome_hisat2_index = ch_genome_hisat2_index // channel: [ val(meta), path(index) ] + genome_dict = ch_genome_dict // channel:[ val(meta), path(dict) ] + gnomad_af_idx = ch_gnomad_af_idx // channel:[ val(gnomad), path(idx) ] + mt_bwa_index = ch_mt_bwa_index // channel:[ val(meta), path(index) ] + mt_bwamem2_index = ch_mt_bwamem2_index // channel:[ val(meta), path(index) ] + mt_dict = ch_mt_dict // channel:[ val(meta), path(dict) ] + mt_fai = ch_mt_fai // channel:[ val(meta), path(fai) ] + mt_fasta = ch_mt_fasta // channel:[ val(meta), path(fasta) ] + mt_intervals = ch_shiftfasta_mtintervals // channel:[ path(intervals) ] + mt_last_index = ch_mt_last_index // channel: [ val(meta), path(index) ] + mtshift_backchain = ch_mtshift_backchain // channel:[ val(meta), path(backchain) ] + mtshift_bwa_index = ch_mtshift_bwa_index // channel:[ val(meta), path(index) ] + mtshift_bwamem2_index = ch_mtshift_bwamem2_index // channel:[ val(meta), path(index) ] + mtshift_dict = ch_mtshift_dict // channel:[ val(meta), path(dict) ] + mtshift_fai = ch_mtshift_fai // channel:[ val(meta), path(fai) ] + mtshift_fasta = ch_mtshift_fasta // channel:[ val(meta), path(fasta) ] + mtshift_intervals = ch_shiftfasta_mtshiftintervals // channel:[ path(intervals) ] + sdf = ch_sdf // channel:[ val (meta), path(sdf) ] + target_bed = ch_target_bed_gz_tbi.collect() // channel:[ val(meta), path(bed), path(tbi) ] + target_intervals = ch_target_intervals // channel:[ path(interval_list) ] + vcfanno_extra = ch_vcfanno_extra // channel:[ [path(vcf), path(tbi)] ] + vep_resources = ch_vep_resources // channel:[ path(cache) ] +} diff --git a/subworkflows/local/prepare_references/tests/main.nf.test b/subworkflows/local/prepare_references/tests/main.nf.test new file mode 100644 index 000000000..893b7f46a --- /dev/null +++ b/subworkflows/local/prepare_references/tests/main.nf.test @@ -0,0 +1,193 @@ +nextflow_workflow { + + name "Test Workflow PREPARE_REFERENCES" + script "subworkflows/local/prepare_references/main.nf" + workflow "PREPARE_REFERENCES" + + tag "subworkflows" + tag "prepare_references" + + tag "bedtools/slop" + tag "bwa/index" + tag "bwafastalign/index" + tag "bwamem2/index" + tag "bwameme/index" + tag "cat/cat" + tag "gatk4/bedtointervallist" + tag "gatk4/createsequencedictionary" + tag "gatk4/intervallisttools" + tag "gatk4/shiftfasta" + tag "get_chrom_sizes" + tag "hisat2/build" + tag "last/lastdb" + tag "rtgtools/format" + tag "samtools/faidx" + tag "sentieon/bwaindex" + tag "tabix/bgziptabix" + tag "tabix/tabix" + tag "untar" + + config "./nextflow.config" + + test("Should run without failures") { + + when { + params { + variant_caller = "deepvariant" + mito_name = "MT" + bait_padding = 100 + } + workflow { + """ + input[0] = "bwamem2" + input[1] = "wgs" + input[2] = null + input[3] = null + input[4] = null + input[5] = null + input[6] = null + input[7] = params.pipelines_testdata_base_path + 'reference/reference.fasta' + input[8] = params.pipelines_testdata_base_path + 'reference/gnomad_reformated.tab.gz' + input[9] = null + input[10] = params.pipelines_testdata_base_path + 'reference/dbsnp_-138-.vcf.gz' + input[11] = null + input[12] = "bwa" + input[13] = null + input[14] = false + input[15] = false + input[16] = null + input[17] = null + input[18] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[19] = null + input[20] = params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List && !sortKey.isEmpty()) { + def next = sortKey[-1] + if (next instanceof List && next.every { !(it instanceof List) }) { + // Leaf list: could be [meta, path] or [file1, file2, ...]. + // For directory outputs (e.g. BWA/BWAMEM2/HISAT2 index folders), + // nf-test represents the value as a Path at sort time rather than + // expanding it to a file list. List the directory contents to + // produce a stable, unique sort key across same-named directories. + return next.findAll { !(it instanceof Map) } + .collect { v -> + def s = v.toString() + if (s.contains(':md5,')) { + return s.split(':md5,')[0].tokenize('/').last() ?: '' + } + try { + def f = new File(s) + if (f.isDirectory()) { + return f.listFiles()?.collect { it.name }?.sort()?.join(',') ?: s.tokenize('/').last() ?: '' + } + } catch (e) {} + return s.tokenize('/').last() ?: '' + } + .sort() + .join(',') + } + sortKey = next + } + def parts = sortKey.toString().split(':md5,')[0].tokenize('/') + parts ? parts[-1] : '' + } + [name, sorted_channel] + }.sort { it[0] } + ).match() } + ) + } + + } + + test("Should run without failures, stub") { + + options "-stub" + + when { + params { + variant_caller = "deepvariant" + mito_name = "MT" + bait_padding = 100 + } + workflow { + """ + input[0] = "bwamem2" + input[1] = "wgs" + input[2] = null + input[3] = null + input[4] = null + input[5] = null + input[6] = null + input[7] = params.pipelines_testdata_base_path + 'reference/reference.fasta' + input[8] = params.pipelines_testdata_base_path + 'reference/gnomad_reformated.tab.gz' + input[9] = null + input[10] = params.pipelines_testdata_base_path + 'reference/dbsnp_-138-.vcf.gz' + input[11] = null + input[12] = "bwa" + input[13] = null + input[14] = false + input[15] = false + input[16] = null + input[17] = null + input[18] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[19] = null + input[20] = params.pipelines_testdata_base_path + 'reference/vep_cache_and_plugins.tar.gz' + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collect { name, channel -> + def sorted_channel = channel.toList().sort { item -> + def sortKey = item + while (sortKey instanceof List && !sortKey.isEmpty()) { + def next = sortKey[-1] + if (next instanceof List && next.every { !(it instanceof List) }) { + // Leaf list: could be [meta, path] or [file1, file2, ...]. + // For directory outputs (e.g. BWA/BWAMEM2/HISAT2 index folders), + // nf-test represents the value as a Path at sort time rather than + // expanding it to a file list. List the directory contents to + // produce a stable, unique sort key across same-named directories. + return next.findAll { !(it instanceof Map) } + .collect { v -> + def s = v.toString() + if (s.contains(':md5,')) { + return s.split(':md5,')[0].tokenize('/').last() ?: '' + } + try { + def f = new File(s) + if (f.isDirectory()) { + return f.listFiles()?.collect { it.name }?.sort()?.join(',') ?: s.tokenize('/').last() ?: '' + } + } catch (e) {} + return s.tokenize('/').last() ?: '' + } + .sort() + .join(',') + } + sortKey = next + } + def parts = sortKey.toString().split(':md5,')[0].tokenize('/') + parts ? parts[-1] : '' + } + [name, sorted_channel] + }.sort { it[0] } + ).match() } + ) + } + + } +} diff --git a/subworkflows/local/prepare_references/tests/main.nf.test.snap b/subworkflows/local/prepare_references/tests/main.nf.test.snap new file mode 100644 index 000000000..661ed64c5 --- /dev/null +++ b/subworkflows/local/prepare_references/tests/main.nf.test.snap @@ -0,0 +1,1858 @@ +{ + "Should run without failures, stub": { + "content": [ + [ + [ + "0", + [ + [ + "target_bait.intervals_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "1", + [ + [ + { + "id": "dbsnp_-138-" + }, + "/nf-core/test-datasets/raredisease/reference/dbsnp_-138-.vcf.gz" + ] + ] + ], + [ + "10", + [ + [ + { + "id": "reference" + }, + [ + + ] + ] + ] + ], + [ + "11", + [ + [ + { + "id": "reference" + }, + "reference.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "12", + [ + [ + "/nf-core/test-datasets/raredisease/reference/gnomad_reformated.tab.gz", + "gnomad_reformated.tab.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "13", + [ + [ + { + "id": "reference" + }, + [ + "reference_mt.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "14", + [ + + ] + ], + [ + "15", + [ + [ + { + "id": "reference" + }, + "reference_mt.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "16", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "17", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "18", + [ + [ + "reference.intervals:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "19", + [ + [ + { + "id": "reference" + }, + [ + "reference.bck:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.des:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.prj:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.sds:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.ssp:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.suf:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.tis:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "2", + [ + [ + { + "id": "dbsnp_-138-" + }, + "dbsnp_-138-.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "20", + [ + [ + { + "id": "reference" + }, + "reference_shift.back_chain:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "21", + [ + [ + { + "id": "reference" + }, + [ + "reference_shift.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "22", + [ + + ] + ], + [ + "23", + [ + [ + { + "id": "reference" + }, + "reference_shift.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "24", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "25", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "26", + [ + [ + "reference.shifted.intervals:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "27", + [ + + ] + ], + [ + "28", + [ + [ + { + "id": "target" + }, + "target_pad100.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "target_pad100.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "29", + [ + [ + "target_target.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "3", + [ + [ + { + "id": "reference" + }, + [ + "reference.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "30", + [ + [ + [ + + ] + ] + ] + ], + [ + "31", + [ + [ + [ + + ] + ] + ] + ], + [ + "4", + [ + + ] + ], + [ + "5", + [ + [ + { + "id": "reference" + }, + [ + "reference.fasta.0123:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.bwt.2bit.64:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "6", + [ + + ] + ], + [ + "7", + [ + [ + "reference.fasta.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "8", + [ + [ + { + "id": "reference" + }, + "reference.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "9", + [ + [ + { + "id": "reference" + }, + "/nf-core/test-datasets/raredisease/reference/reference.fasta" + ] + ] + ], + [ + "bait_intervals", + [ + [ + "target_bait.intervals_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "dbsnp", + [ + [ + { + "id": "dbsnp_-138-" + }, + "/nf-core/test-datasets/raredisease/reference/dbsnp_-138-.vcf.gz" + ] + ] + ], + [ + "dbsnp_tbi", + [ + [ + { + "id": "dbsnp_-138-" + }, + "dbsnp_-138-.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "genome_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "genome_bwafastalign_index", + [ + + ] + ], + [ + "genome_bwamem2_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.fasta.0123:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.bwt.2bit.64:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.fasta.pac:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "genome_bwameme_index", + [ + + ] + ], + [ + "genome_chrom_sizes", + [ + [ + "reference.fasta.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "genome_dict", + [ + [ + { + "id": "reference" + }, + "reference.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "genome_fai", + [ + [ + { + "id": "reference" + }, + "reference.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "genome_fasta", + [ + [ + { + "id": "reference" + }, + "/nf-core/test-datasets/raredisease/reference/reference.fasta" + ] + ] + ], + [ + "genome_hisat2_index", + [ + [ + { + "id": "reference" + }, + [ + + ] + ] + ] + ], + [ + "gnomad_af_idx", + [ + [ + "/nf-core/test-datasets/raredisease/reference/gnomad_reformated.tab.gz", + "gnomad_reformated.tab.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mt_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference_mt.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_mt.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "mt_bwamem2_index", + [ + + ] + ], + [ + "mt_dict", + [ + [ + { + "id": "reference" + }, + "reference_mt.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mt_fai", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mt_fasta", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mt_intervals", + [ + [ + "reference.intervals:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mt_last_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.bck:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.des:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.prj:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.sds:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.ssp:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.suf:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference.tis:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "mtshift_backchain", + [ + [ + { + "id": "reference" + }, + "reference_shift.back_chain:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mtshift_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference_shift.amb:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.ann:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.bwt:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.pac:md5,d41d8cd98f00b204e9800998ecf8427e", + "reference_shift.sa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ] + ], + [ + "mtshift_bwamem2_index", + [ + + ] + ], + [ + "mtshift_dict", + [ + [ + { + "id": "reference" + }, + "reference_shift.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mtshift_fai", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mtshift_fasta", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "mtshift_intervals", + [ + [ + "reference.shifted.intervals:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "sdf", + [ + + ] + ], + [ + "target_bed", + [ + [ + { + "id": "target" + }, + "target_pad100.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "target_pad100.bed.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "target_intervals", + [ + [ + "target_target.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + [ + "vcfanno_extra", + [ + [ + [ + + ] + ] + ] + ], + [ + "vep_resources", + [ + [ + [ + + ] + ] + ] + ] + ] + ], + "timestamp": "2026-06-30T13:03:29.65015608", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "Should run without failures": { + "content": [ + [ + [ + "0", + [ + [ + "target_bait.intervals_list:md5,84cbdac15bdfcd14b8a810e35f7ccc54" + ] + ] + ], + [ + "1", + [ + [ + { + "id": "dbsnp_-138-" + }, + "/nf-core/test-datasets/raredisease/reference/dbsnp_-138-.vcf.gz" + ] + ] + ], + [ + "10", + [ + [ + { + "id": "reference" + }, + [ + "reference.1.ht2:md5,f1f1779341ba9a0ab7078e358f6efdde", + "reference.2.ht2:md5,09f0021a3a29a0e4aee96083ea4d4020", + "reference.3.ht2:md5,3b641d6168aa70fe864844bb02ef39f2", + "reference.4.ht2:md5,2dd52cfb372404a3619c0f9367fc4012", + "reference.5.ht2:md5,999891dff8303f7c576f5a1ad4be5036", + "reference.6.ht2:md5,e1a25310dabfaeb7f0fa200785bad49f", + "reference.7.ht2:md5,9013eccd91ad614d7893c739275a394f", + "reference.8.ht2:md5,33cdeccccebe80329f1fdbee7f5874cb" + ] + ] + ] + ], + [ + "11", + [ + [ + { + "id": "reference" + }, + "reference.dict:md5,81abd0fc051c084405024e0927f7b436" + ] + ] + ], + [ + "12", + [ + [ + "/nf-core/test-datasets/raredisease/reference/gnomad_reformated.tab.gz", + "gnomad_reformated.tab.gz.tbi:md5,854afcf42d656c3d00a39dd9b69f66f7" + ] + ] + ], + [ + "13", + [ + [ + { + "id": "reference" + }, + [ + "reference_mt.amb:md5,6749f645487281112c254ab829ea048c", + "reference_mt.ann:md5,4111990d7eae543ed95cb82a5e32b04a", + "reference_mt.bwt:md5,96337a6d9dc0d7afc562fee8b1afb673", + "reference_mt.pac:md5,ecbea80d481b6e8e70da3f464b977d91", + "reference_mt.sa:md5,7c06a2c0b4f23e785e2f85383b9d1317" + ] + ] + ] + ], + [ + "14", + [ + + ] + ], + [ + "15", + [ + [ + { + "id": "reference" + }, + "reference_mt.dict:md5,9b0db3306084213d47d83aa994b219f6" + ] + ] + ], + [ + "16", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa.fai:md5,fa8117aab64eeceb3f0800d473bd2a2b" + ] + ] + ], + [ + "17", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa:md5,dcff3c6dd92e01b11edf7586ca4f5a78" + ] + ] + ], + [ + "18", + [ + [ + "reference_mt.intervals:md5,0930dafc5645246542112ae3d62573a3" + ] + ] + ], + [ + "19", + [ + [ + { + "id": "reference" + }, + [ + "reference.bck:md5,cb2ea69e38f2f48b0e9fd86511f00efa", + "reference.des:md5,d9189e49407ad59a8d15e527a5262d88", + "reference.prj:md5,afb6ee4759a4ccd9edb52fdb8e5a3a26", + "reference.sds:md5,503e83c0d24f5ea38d9d6c013d9777d1", + "reference.ssp:md5,5c62ddb0bd75481784efb7120045bf42", + "reference.suf:md5,b2180a9a2d85be97f896808c05b0e38c", + "reference.tis:md5,c4167c6aebb2139c3dc9b07a65830c3d" + ] + ] + ] + ], + [ + "2", + [ + [ + { + "id": "dbsnp_-138-" + }, + "dbsnp_-138-.vcf.gz.tbi:md5,6695b71d9819806d50cd908051cf4cc0" + ] + ] + ], + [ + "20", + [ + [ + { + "id": "reference" + }, + "reference_shift.back_chain:md5,25d682d73a9bae009f4a38b3ede5dbc8" + ] + ] + ], + [ + "21", + [ + [ + { + "id": "reference" + }, + [ + "reference_shift.amb:md5,ad1d6545efc080e69ad54ecdbcd0720c", + "reference_shift.ann:md5,4111990d7eae543ed95cb82a5e32b04a", + "reference_shift.bwt:md5,c13d3e8c5ac29b56b31e1882e2111491", + "reference_shift.pac:md5,0ead764b2f8fa112e3351ca517d2e125", + "reference_shift.sa:md5,9ef1b52de302c6957f4dc82ed2f21bd1" + ] + ] + ] + ], + [ + "22", + [ + + ] + ], + [ + "23", + [ + [ + { + "id": "reference" + }, + "reference_shift.dict:md5,a714408661d0f6403f417304342574fc" + ] + ] + ], + [ + "24", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta.fai:md5,fa8117aab64eeceb3f0800d473bd2a2b" + ] + ] + ], + [ + "25", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta:md5,3bb4de5911acad2dd87e8a183251d0dc" + ] + ] + ], + [ + "26", + [ + [ + "reference_mt.shifted.intervals:md5,083d8f782fd4228dd9f6948ddbc64fd0" + ] + ] + ], + [ + "27", + [ + + ] + ], + [ + "28", + [ + [ + { + "id": "target" + }, + "target_pad100.bed.gz:md5,7122d49f10e69c54d429a95cf4cf8fc9", + "target_pad100.bed.gz.tbi:md5,dc41277c9c9be1203643b9192260f9ac" + ] + ] + ], + [ + "29", + [ + [ + "target_target.interval_list:md5,2959b7b0e1b298fe84ad708f447d6703" + ] + ] + ], + [ + "3", + [ + [ + { + "id": "reference" + }, + [ + "reference.amb:md5,0a85644af00f9a856d874381d24e7803", + "reference.ann:md5,8fdb46970ca95a4ef54f5f1a02d233cd", + "reference.bwt:md5,0d1ba8d4e0229df6abb869a69f621dc8", + "reference.pac:md5,96b449e1316067fdfba91b1399687bc2", + "reference.sa:md5,c5c99cdc7a3cb6224841131b4b4285fe" + ] + ] + ] + ], + [ + "30", + [ + [ + [ + + ] + ] + ] + ], + [ + "31", + [ + [ + [ + "LoFtool_scores.txt:md5,d9abd640ef22c790583b4b15d144ea6f", + [ + "LoFtool.pm:md5,39fe102c44c6194fab9d1e42f6653ab5", + "MaxEntScan.pm:md5,88e141bb8e21f776112f6aa4c1d1b195", + "SpliceAI.pm:md5,860b0a5b8191ba6b2f85de2a76212355", + "dbNSFP.pm:md5,6149e9e4e28df8812b9a6e017eb08e12", + "pLI.pm:md5,3ab758b61b06ff5604a94f3f293ff918", + "plugin_config.txt:md5,c722057245a51e950cf1b10ca3188f7f" + ], + [ + "me2x5:md5,0e3daf92c0aed69a8c78d6668cb79431", + "score3.pl:md5,a50bbe208f226fa4df49a4a595898d4c", + "score5.pl:md5,3b0b3ff5e1af1fcae9385d3e1fd03ff8", + [ + "hashseq.m:md5,b193eef9bd40086691021a2d19c2c5de", + "hashseq.m~:md5,0277f5c7c97a3b6ff258f04980ab2299", + "me1s0acc1:md5,98e8f71ae37c12e445f3a21fcd8467a2", + "me1s0acc2:md5,ed976352b5f3de894b60fa2ea0213cc9", + "me1s0acc3:md5,93c94296500c37c70e74b295f6ff1578", + "me1s0acc4:md5,83b8104e0080210fd0a96cda88c4f62d", + "me1s0acc5:md5,6d26531c6720902a85cd30d13c165b37", + "me1s0acc6:md5,403edfcea636de389912605d2bdc93eb", + "me1s0acc7:md5,b0525d474309a2bc08b3216967d0a436", + "me1s0acc8:md5,3935b25a6f4f63e3e2fea6bfc5a0c65e", + "me1s0acc9:md5,0f3b8a65c043fb53cc8aece8cb5b1ef8", + "me2s0:md5,c13a0c34bc8247f323b523eec99e811d", + "me2s0acc1:md5,0a4dcd11bce05f9706f33505f223eeac", + "me2s0acc2:md5,8565b8edb7f9582b4a23a58dbd11477e", + "me2s0acc3:md5,057916e5bac481c3b36a652dcebe5838", + "me2s0acc4:md5,09ba0ad8055b7db2f84dcf418e3d68e1", + "me2s0acc5:md5,1675124a3e906b6eb7051923c42035cc", + "me2s0acc6:md5,26e468f9476bb5d25cc3fca948738535", + "me2s0acc7:md5,5f35e846137a18d4fcc63bc892d4153a", + "me2s0acc8:md5,bae0098c03adfdce1ff13a13eadd3897", + "me2s0acc9:md5,1d733af14d438dc9dcdcddf51d841457", + "me2x3acc1:md5,00d620b842d47e8348440f8936ff6143", + "me2x3acc2:md5,cf36592d00b1e69eab00e0cc1f3cecaf", + "me2x3acc3:md5,136b3eaf2b7f78d0da78d9d4be53368f", + "me2x3acc4:md5,3a19125ed5b0f4a5ace7d048f9e005fe", + "me2x3acc5:md5,4e234dd1e58b04b499499f3244502e74", + "me2x3acc6:md5,df85b498edd7d4692c04cab8c01ae917", + "me2x3acc7:md5,f139698d62743bc816b5d4281071c657", + "me2x3acc8:md5,1d2462179e567b1c7beb2f6797e53e07", + "me2x3acc9:md5,36f1e98760a6c3a3e31b4e4a3071ab68", + "me2x5:md5,0e3daf92c0aed69a8c78d6668cb79431", + "splice5sequences:md5,1a1518daba4e02f757811869cb4bcefd" + ], + "test3:md5,97bbfcf2fa23fe249a79e219b1c0e3c6", + "test5:md5,a7b00a84f65a525305a5fad91b4bbc61" + ], + [ + [ + [ + "1-1000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "1-1000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "10000001-11000000.gz:md5,3cc65ae9e19a9dbaa0175d573855b1c5", + "10000001-11000000_reg.gz:md5,bee170866e2339d8f294297c8d5d399d", + "1000001-2000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "1000001-2000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "11000001-12000000.gz:md5,d453356047147a676955c238a2b3502e", + "11000001-12000000_reg.gz:md5,872621db9595d97f014478e886da37ad", + "12000001-13000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "12000001-13000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "13000001-14000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "13000001-14000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "14000001-15000000.gz:md5,8f083b4db9509c63161c86d68373a004", + "14000001-15000000_reg.gz:md5,e7b5648e4e3bcb4253ba74edd401beba", + "15000001-16000000.gz:md5,d05a0116f9da34cd5657618c85d97181", + "15000001-16000000_reg.gz:md5,e41afae6cf10d1b025274c63907e9949", + "16000001-17000000.gz:md5,8250d7f851ec53acc6eb23e5973d780b", + "16000001-17000000_reg.gz:md5,e93e976e8316a646db6c58ac19a69e32", + "17000001-18000000.gz:md5,a70022d471c30e97052c7a640b91cc3a", + "17000001-18000000_reg.gz:md5,d1728b3ec1ec3bb9871e9aaa66a7a891", + "18000001-19000000.gz:md5,86cf339af4fbc2662c0fd97eb40192c3", + "18000001-19000000_reg.gz:md5,0fffcde9d99d05ae6f6ef1fab2d1af9d", + "19000001-20000000.gz:md5,87e20d3c192ca889a2b5f61bb1710466", + "19000001-20000000_reg.gz:md5,3860179bb94216dccca2d13bbbfa41c0", + "20000001-21000000.gz:md5,07e5c3464bdbaaead40d8d71799e0510", + "20000001-21000000_reg.gz:md5,298851c79adaa52be01f468fb3c3e70c", + "2000001-3000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "2000001-3000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "21000001-22000000.gz:md5,187079a822ed51bc9532e97f3c7109df", + "21000001-22000000_reg.gz:md5,65190153890d16157d25f386ec03346b", + "22000001-23000000.gz:md5,79969dbe6083b1c44825e347ea035f8d", + "22000001-23000000_reg.gz:md5,0774a40b5d3a4a80d943d883fd1bf011", + "23000001-24000000.gz:md5,0fc496a44d493fd74179824b1e9a98a4", + "23000001-24000000_reg.gz:md5,e27126e23dc446df0c9423596987f4bb", + "24000001-25000000.gz:md5,95b3d1d24d576cbbf489468097f2c213", + "24000001-25000000_reg.gz:md5,d384006e4c0e8bd38b89fd1b82e22506", + "25000001-26000000.gz:md5,77230b5177f6410f9324af8dde33e020", + "25000001-26000000_reg.gz:md5,667eecb6d3ffdb5613581591835c5e3d", + "26000001-27000000.gz:md5,fe6ad01b323d83ae376bdeb6cf047e3c", + "26000001-27000000_reg.gz:md5,aafd124971e6424e8db99b42b091bd99", + "27000001-28000000.gz:md5,27c790ae843453556c7b2242c36abd1a", + "27000001-28000000_reg.gz:md5,b510b713aa42bafb38351842821977c8", + "28000001-29000000.gz:md5,a6f366a37ad04cc773236be4dd09ddaf", + "28000001-29000000_reg.gz:md5,5f18facec28af19bfdd8a108a8f506d7", + "29000001-30000000.gz:md5,82fe6926eb7a292b9fc2e50d484c8c2f", + "29000001-30000000_reg.gz:md5,e3958033b25781baa21d90d183ec2a5e", + "30000001-31000000.gz:md5,1dcca9aea49227138ef3644d2821c647", + "30000001-31000000_reg.gz:md5,d5926ccaad9b9ad4edd0060e4a598438", + "3000001-4000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "3000001-4000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "31000001-32000000.gz:md5,f8fc56294a92150c19e315e99a83b4a5", + "31000001-32000000_reg.gz:md5,bc04a5e426609b7e15cfeed4d2e687b5", + "32000001-33000000.gz:md5,69ee3fa14cd1465ecaf00568359c4d09", + "32000001-33000000_reg.gz:md5,61b19ff1e07d2d9ec2d2fb9bb7946765", + "33000001-34000000.gz:md5,3a9067073eac98fb2f9f31b5cd07b146", + "33000001-34000000_reg.gz:md5,02ee515697fef7bb35c5e76720956241", + "34000001-35000000.gz:md5,1a5a50eaac5c4a0931a36559fcfff49b", + "34000001-35000000_reg.gz:md5,ee77f95bd990e73bb8945f8ddac3f27a", + "35000001-36000000.gz:md5,a31f574314f954fda8712d6aa356b0dd", + "35000001-36000000_reg.gz:md5,22f939323e6bbb5568f61dfdd4f6ba8b", + "36000001-37000000.gz:md5,9932081e83e182b21b93d4e86a2e6d30", + "36000001-37000000_reg.gz:md5,6aa882038538c82611978f3f700bd769", + "37000001-38000000.gz:md5,89196534aff56af350468ddb6a71e4a4", + "37000001-38000000_reg.gz:md5,bfaba7fc51688b715d10b579fc85b0c1", + "38000001-39000000.gz:md5,c7918ce6c4d44677df392c6a9d8b0bf6", + "38000001-39000000_reg.gz:md5,d0b5146d04d3827ea2c9744e69808bb7", + "39000001-40000000.gz:md5,244eaac70c773fef1a6d8cbc55570e5c", + "39000001-40000000_reg.gz:md5,bade6790bc37a658510307d91bc1d935", + "40000001-41000000.gz:md5,ed8e8285e0f0fed12f74415e7db1ca1c", + "40000001-41000000_reg.gz:md5,575f377254cd26f3b511d8739ede2657", + "4000001-5000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "4000001-5000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "41000001-42000000.gz:md5,bf269b45019dc1fdeae4b0ca3f07c31e", + "41000001-42000000_reg.gz:md5,dcae8fe4c21ca4b556310a2ed9f7db61", + "42000001-43000000.gz:md5,5884bb2c85e652aa312217ea42413ec3", + "42000001-43000000_reg.gz:md5,b70a294777a97b99f583a26e56ee24b6", + "43000001-44000000.gz:md5,f369e7eb0ca67b8c829a6c079c686482", + "43000001-44000000_reg.gz:md5,3ecaa382d73864f3fa5b1b20774b2dac", + "44000001-45000000.gz:md5,09fa55af78b28d1c6267c1c218be1852", + "44000001-45000000_reg.gz:md5,8bd3cc296bc92ed5c62e2f8249519076", + "45000001-46000000.gz:md5,bffba50564d697fa575d61553a94be0d", + "45000001-46000000_reg.gz:md5,9157f35b881bb7978f50f3c0eb122dc1", + "46000001-47000000.gz:md5,06610987a1a871c66cd7587275c580ad", + "46000001-47000000_reg.gz:md5,9261ebfa3f619083ba69b1431c8b1e57", + "47000001-48000000.gz:md5,a795a475d38eec771623db0435eaafd3", + "47000001-48000000_reg.gz:md5,595a4d4a2dc70a2ae1584b9369c45f50", + "48000001-49000000.gz:md5,84b0074dd00d2916aea645d4c5322f0d", + "48000001-49000000_reg.gz:md5,10b336ce80cd5e95f5d087a0b021658b", + "5000001-6000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "5000001-6000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "6000001-7000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "6000001-7000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "7000001-8000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "7000001-8000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "8000001-9000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "8000001-9000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "9000001-10000000.gz:md5,6484090af4453287309e7fc256b2a3ee", + "9000001-10000000_reg.gz:md5,eb88b4c6e52ee1b7f38742fc63a552b9", + "all_vars.gz:md5,cc58de49787b22b3b119e20dc1d9c813", + "all_vars.gz.csi:md5,efe6feefb4af3fa1cbb835f217160d79" + ], + [ + "1-1000000.gz:md5,cde70e0bc1908a02142c1ca22d4bb782", + "1-1000000_reg.gz:md5,65080eebbe9e956482406f08b8248ba9", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,5a949a8c013243a54487187b34dfafbd", + "1-1000000_reg.gz:md5,0808c8cb8633f74cf764fe4b0cfafbdf", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,533a20fead6e26e287951bf2842e48f7", + "1-1000000_reg.gz:md5,9aab0e39e0688b826e6e736458ad2d1c", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,efb8aaa6a3bc78eff17ed28a43099383", + "1-1000000_reg.gz:md5,1a27d4ab43920ef151e0089f3e9e4a4b", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,6cd5ac90da0873007ab74b8c64cdbe5d", + "1-1000000_reg.gz:md5,2f56086ea334b8bc196caf38f4712c24", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,37ecdcf6536f1c7cdd94048939c215c3", + "1-1000000_reg.gz:md5,607b20b49f8359be58de4adba7687fbc", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,6843883020c41262309eed07df3f3af4", + "1-1000000_reg.gz:md5,051b6db155fab6629ef30e80e8cb7cdd", + "1000001-2000000.gz:md5,17181e7730e8cd55e46c202568f818ad", + "1000001-2000000_reg.gz:md5,051b6db155fab6629ef30e80e8cb7cdd", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,b1e3e86cea70e7bee39139856afc038b", + "1-1000000_reg.gz:md5,68693c4e6a9ffe8ce4a018aa0ee4c95a", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,edd409f4bbe5e63910afb85d05dbdb7a", + "1-1000000_reg.gz:md5,68a25e6d83d8e15183496b5a97c3a670", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,09351a00fe7fa572e6b0e1c023f3da55", + "1-1000000_reg.gz:md5,a774233304f72832896de2e9227221b0", + "all_vars.gz:md5,ee9370e9bf063fb4f52fe1ab0b45f3d0", + "all_vars.gz.csi:md5,0397561c6d0b6c8ae9d0c083bb69e1e5" + ], + "chr_synonyms.txt:md5,ecc5ec48a5fb60f5f7198f641a123254", + "info.txt:md5,296e24b6257be06762c21f0066cf6718" + ] + ], + "pLI_values_107.txt:md5,8e35e21aa84b5976776deda972883130", + "spliceai_21_scores_raw_indel_-v1.3-.vcf.gz:md5,46d6b81b89f26fb807c4f73e53828754", + "spliceai_21_scores_raw_indel_-v1.3-.vcf.gz.tbi:md5,a213a9f3156b0f2f6331ff35bc01f591", + "spliceai_21_scores_raw_snv_-v1.3-.vcf.gz:md5,b16af27abef55deb104af19b2d289813", + "spliceai_21_scores_raw_snv_-v1.3-.vcf.gz.tbi:md5,3fab1357156412ca02b2bdf075e97382" + ] + ] + ] + ], + [ + "4", + [ + + ] + ], + [ + "5", + [ + [ + { + "id": "reference" + }, + [ + "reference.fasta.0123:md5,0f0ff4414949e6787a25a563f19e2a3b", + "reference.fasta.amb:md5,0a85644af00f9a856d874381d24e7803", + "reference.fasta.ann:md5,8fdb46970ca95a4ef54f5f1a02d233cd", + "reference.fasta.bwt.2bit.64:md5,3c0df9450afc5cb0ad5e85870829d9d0", + "reference.fasta.pac:md5,96b449e1316067fdfba91b1399687bc2" + ] + ] + ] + ], + [ + "6", + [ + + ] + ], + [ + "7", + [ + [ + "reference.fasta.sizes:md5,b7bb58fb4d5cb50796e722222a13a2e6" + ] + ] + ], + [ + "8", + [ + [ + { + "id": "reference" + }, + "reference.fasta.fai:md5,bf4047e05f95deb372eb8ffd601cbc29" + ] + ] + ], + [ + "9", + [ + [ + { + "id": "reference" + }, + "/nf-core/test-datasets/raredisease/reference/reference.fasta" + ] + ] + ], + [ + "bait_intervals", + [ + [ + "target_bait.intervals_list:md5,84cbdac15bdfcd14b8a810e35f7ccc54" + ] + ] + ], + [ + "dbsnp", + [ + [ + { + "id": "dbsnp_-138-" + }, + "/nf-core/test-datasets/raredisease/reference/dbsnp_-138-.vcf.gz" + ] + ] + ], + [ + "dbsnp_tbi", + [ + [ + { + "id": "dbsnp_-138-" + }, + "dbsnp_-138-.vcf.gz.tbi:md5,6695b71d9819806d50cd908051cf4cc0" + ] + ] + ], + [ + "genome_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.amb:md5,0a85644af00f9a856d874381d24e7803", + "reference.ann:md5,8fdb46970ca95a4ef54f5f1a02d233cd", + "reference.bwt:md5,0d1ba8d4e0229df6abb869a69f621dc8", + "reference.pac:md5,96b449e1316067fdfba91b1399687bc2", + "reference.sa:md5,c5c99cdc7a3cb6224841131b4b4285fe" + ] + ] + ] + ], + [ + "genome_bwafastalign_index", + [ + + ] + ], + [ + "genome_bwamem2_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.fasta.0123:md5,0f0ff4414949e6787a25a563f19e2a3b", + "reference.fasta.amb:md5,0a85644af00f9a856d874381d24e7803", + "reference.fasta.ann:md5,8fdb46970ca95a4ef54f5f1a02d233cd", + "reference.fasta.bwt.2bit.64:md5,3c0df9450afc5cb0ad5e85870829d9d0", + "reference.fasta.pac:md5,96b449e1316067fdfba91b1399687bc2" + ] + ] + ] + ], + [ + "genome_bwameme_index", + [ + + ] + ], + [ + "genome_chrom_sizes", + [ + [ + "reference.fasta.sizes:md5,b7bb58fb4d5cb50796e722222a13a2e6" + ] + ] + ], + [ + "genome_dict", + [ + [ + { + "id": "reference" + }, + "reference.dict:md5,81abd0fc051c084405024e0927f7b436" + ] + ] + ], + [ + "genome_fai", + [ + [ + { + "id": "reference" + }, + "reference.fasta.fai:md5,bf4047e05f95deb372eb8ffd601cbc29" + ] + ] + ], + [ + "genome_fasta", + [ + [ + { + "id": "reference" + }, + "/nf-core/test-datasets/raredisease/reference/reference.fasta" + ] + ] + ], + [ + "genome_hisat2_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.1.ht2:md5,f1f1779341ba9a0ab7078e358f6efdde", + "reference.2.ht2:md5,09f0021a3a29a0e4aee96083ea4d4020", + "reference.3.ht2:md5,3b641d6168aa70fe864844bb02ef39f2", + "reference.4.ht2:md5,2dd52cfb372404a3619c0f9367fc4012", + "reference.5.ht2:md5,999891dff8303f7c576f5a1ad4be5036", + "reference.6.ht2:md5,e1a25310dabfaeb7f0fa200785bad49f", + "reference.7.ht2:md5,9013eccd91ad614d7893c739275a394f", + "reference.8.ht2:md5,33cdeccccebe80329f1fdbee7f5874cb" + ] + ] + ] + ], + [ + "gnomad_af_idx", + [ + [ + "/nf-core/test-datasets/raredisease/reference/gnomad_reformated.tab.gz", + "gnomad_reformated.tab.gz.tbi:md5,854afcf42d656c3d00a39dd9b69f66f7" + ] + ] + ], + [ + "mt_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference_mt.amb:md5,6749f645487281112c254ab829ea048c", + "reference_mt.ann:md5,4111990d7eae543ed95cb82a5e32b04a", + "reference_mt.bwt:md5,96337a6d9dc0d7afc562fee8b1afb673", + "reference_mt.pac:md5,ecbea80d481b6e8e70da3f464b977d91", + "reference_mt.sa:md5,7c06a2c0b4f23e785e2f85383b9d1317" + ] + ] + ] + ], + [ + "mt_bwamem2_index", + [ + + ] + ], + [ + "mt_dict", + [ + [ + { + "id": "reference" + }, + "reference_mt.dict:md5,9b0db3306084213d47d83aa994b219f6" + ] + ] + ], + [ + "mt_fai", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa.fai:md5,fa8117aab64eeceb3f0800d473bd2a2b" + ] + ] + ], + [ + "mt_fasta", + [ + [ + { + "id": "reference" + }, + "reference_mt.fa:md5,dcff3c6dd92e01b11edf7586ca4f5a78" + ] + ] + ], + [ + "mt_intervals", + [ + [ + "reference_mt.intervals:md5,0930dafc5645246542112ae3d62573a3" + ] + ] + ], + [ + "mt_last_index", + [ + [ + { + "id": "reference" + }, + [ + "reference.bck:md5,cb2ea69e38f2f48b0e9fd86511f00efa", + "reference.des:md5,d9189e49407ad59a8d15e527a5262d88", + "reference.prj:md5,afb6ee4759a4ccd9edb52fdb8e5a3a26", + "reference.sds:md5,503e83c0d24f5ea38d9d6c013d9777d1", + "reference.ssp:md5,5c62ddb0bd75481784efb7120045bf42", + "reference.suf:md5,b2180a9a2d85be97f896808c05b0e38c", + "reference.tis:md5,c4167c6aebb2139c3dc9b07a65830c3d" + ] + ] + ] + ], + [ + "mtshift_backchain", + [ + [ + { + "id": "reference" + }, + "reference_shift.back_chain:md5,25d682d73a9bae009f4a38b3ede5dbc8" + ] + ] + ], + [ + "mtshift_bwa_index", + [ + [ + { + "id": "reference" + }, + [ + "reference_shift.amb:md5,ad1d6545efc080e69ad54ecdbcd0720c", + "reference_shift.ann:md5,4111990d7eae543ed95cb82a5e32b04a", + "reference_shift.bwt:md5,c13d3e8c5ac29b56b31e1882e2111491", + "reference_shift.pac:md5,0ead764b2f8fa112e3351ca517d2e125", + "reference_shift.sa:md5,9ef1b52de302c6957f4dc82ed2f21bd1" + ] + ] + ] + ], + [ + "mtshift_bwamem2_index", + [ + + ] + ], + [ + "mtshift_dict", + [ + [ + { + "id": "reference" + }, + "reference_shift.dict:md5,a714408661d0f6403f417304342574fc" + ] + ] + ], + [ + "mtshift_fai", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta.fai:md5,fa8117aab64eeceb3f0800d473bd2a2b" + ] + ] + ], + [ + "mtshift_fasta", + [ + [ + { + "id": "reference" + }, + "reference_shift.fasta:md5,3bb4de5911acad2dd87e8a183251d0dc" + ] + ] + ], + [ + "mtshift_intervals", + [ + [ + "reference_mt.shifted.intervals:md5,083d8f782fd4228dd9f6948ddbc64fd0" + ] + ] + ], + [ + "sdf", + [ + + ] + ], + [ + "target_bed", + [ + [ + { + "id": "target" + }, + "target_pad100.bed.gz:md5,7122d49f10e69c54d429a95cf4cf8fc9", + "target_pad100.bed.gz.tbi:md5,dc41277c9c9be1203643b9192260f9ac" + ] + ] + ], + [ + "target_intervals", + [ + [ + "target_target.interval_list:md5,2959b7b0e1b298fe84ad708f447d6703" + ] + ] + ], + [ + "vcfanno_extra", + [ + [ + [ + + ] + ] + ] + ], + [ + "vep_resources", + [ + [ + [ + "LoFtool_scores.txt:md5,d9abd640ef22c790583b4b15d144ea6f", + [ + "LoFtool.pm:md5,39fe102c44c6194fab9d1e42f6653ab5", + "MaxEntScan.pm:md5,88e141bb8e21f776112f6aa4c1d1b195", + "SpliceAI.pm:md5,860b0a5b8191ba6b2f85de2a76212355", + "dbNSFP.pm:md5,6149e9e4e28df8812b9a6e017eb08e12", + "pLI.pm:md5,3ab758b61b06ff5604a94f3f293ff918", + "plugin_config.txt:md5,c722057245a51e950cf1b10ca3188f7f" + ], + [ + "me2x5:md5,0e3daf92c0aed69a8c78d6668cb79431", + "score3.pl:md5,a50bbe208f226fa4df49a4a595898d4c", + "score5.pl:md5,3b0b3ff5e1af1fcae9385d3e1fd03ff8", + [ + "hashseq.m:md5,b193eef9bd40086691021a2d19c2c5de", + "hashseq.m~:md5,0277f5c7c97a3b6ff258f04980ab2299", + "me1s0acc1:md5,98e8f71ae37c12e445f3a21fcd8467a2", + "me1s0acc2:md5,ed976352b5f3de894b60fa2ea0213cc9", + "me1s0acc3:md5,93c94296500c37c70e74b295f6ff1578", + "me1s0acc4:md5,83b8104e0080210fd0a96cda88c4f62d", + "me1s0acc5:md5,6d26531c6720902a85cd30d13c165b37", + "me1s0acc6:md5,403edfcea636de389912605d2bdc93eb", + "me1s0acc7:md5,b0525d474309a2bc08b3216967d0a436", + "me1s0acc8:md5,3935b25a6f4f63e3e2fea6bfc5a0c65e", + "me1s0acc9:md5,0f3b8a65c043fb53cc8aece8cb5b1ef8", + "me2s0:md5,c13a0c34bc8247f323b523eec99e811d", + "me2s0acc1:md5,0a4dcd11bce05f9706f33505f223eeac", + "me2s0acc2:md5,8565b8edb7f9582b4a23a58dbd11477e", + "me2s0acc3:md5,057916e5bac481c3b36a652dcebe5838", + "me2s0acc4:md5,09ba0ad8055b7db2f84dcf418e3d68e1", + "me2s0acc5:md5,1675124a3e906b6eb7051923c42035cc", + "me2s0acc6:md5,26e468f9476bb5d25cc3fca948738535", + "me2s0acc7:md5,5f35e846137a18d4fcc63bc892d4153a", + "me2s0acc8:md5,bae0098c03adfdce1ff13a13eadd3897", + "me2s0acc9:md5,1d733af14d438dc9dcdcddf51d841457", + "me2x3acc1:md5,00d620b842d47e8348440f8936ff6143", + "me2x3acc2:md5,cf36592d00b1e69eab00e0cc1f3cecaf", + "me2x3acc3:md5,136b3eaf2b7f78d0da78d9d4be53368f", + "me2x3acc4:md5,3a19125ed5b0f4a5ace7d048f9e005fe", + "me2x3acc5:md5,4e234dd1e58b04b499499f3244502e74", + "me2x3acc6:md5,df85b498edd7d4692c04cab8c01ae917", + "me2x3acc7:md5,f139698d62743bc816b5d4281071c657", + "me2x3acc8:md5,1d2462179e567b1c7beb2f6797e53e07", + "me2x3acc9:md5,36f1e98760a6c3a3e31b4e4a3071ab68", + "me2x5:md5,0e3daf92c0aed69a8c78d6668cb79431", + "splice5sequences:md5,1a1518daba4e02f757811869cb4bcefd" + ], + "test3:md5,97bbfcf2fa23fe249a79e219b1c0e3c6", + "test5:md5,a7b00a84f65a525305a5fad91b4bbc61" + ], + [ + [ + [ + "1-1000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "1-1000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "10000001-11000000.gz:md5,3cc65ae9e19a9dbaa0175d573855b1c5", + "10000001-11000000_reg.gz:md5,bee170866e2339d8f294297c8d5d399d", + "1000001-2000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "1000001-2000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "11000001-12000000.gz:md5,d453356047147a676955c238a2b3502e", + "11000001-12000000_reg.gz:md5,872621db9595d97f014478e886da37ad", + "12000001-13000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "12000001-13000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "13000001-14000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "13000001-14000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "14000001-15000000.gz:md5,8f083b4db9509c63161c86d68373a004", + "14000001-15000000_reg.gz:md5,e7b5648e4e3bcb4253ba74edd401beba", + "15000001-16000000.gz:md5,d05a0116f9da34cd5657618c85d97181", + "15000001-16000000_reg.gz:md5,e41afae6cf10d1b025274c63907e9949", + "16000001-17000000.gz:md5,8250d7f851ec53acc6eb23e5973d780b", + "16000001-17000000_reg.gz:md5,e93e976e8316a646db6c58ac19a69e32", + "17000001-18000000.gz:md5,a70022d471c30e97052c7a640b91cc3a", + "17000001-18000000_reg.gz:md5,d1728b3ec1ec3bb9871e9aaa66a7a891", + "18000001-19000000.gz:md5,86cf339af4fbc2662c0fd97eb40192c3", + "18000001-19000000_reg.gz:md5,0fffcde9d99d05ae6f6ef1fab2d1af9d", + "19000001-20000000.gz:md5,87e20d3c192ca889a2b5f61bb1710466", + "19000001-20000000_reg.gz:md5,3860179bb94216dccca2d13bbbfa41c0", + "20000001-21000000.gz:md5,07e5c3464bdbaaead40d8d71799e0510", + "20000001-21000000_reg.gz:md5,298851c79adaa52be01f468fb3c3e70c", + "2000001-3000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "2000001-3000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "21000001-22000000.gz:md5,187079a822ed51bc9532e97f3c7109df", + "21000001-22000000_reg.gz:md5,65190153890d16157d25f386ec03346b", + "22000001-23000000.gz:md5,79969dbe6083b1c44825e347ea035f8d", + "22000001-23000000_reg.gz:md5,0774a40b5d3a4a80d943d883fd1bf011", + "23000001-24000000.gz:md5,0fc496a44d493fd74179824b1e9a98a4", + "23000001-24000000_reg.gz:md5,e27126e23dc446df0c9423596987f4bb", + "24000001-25000000.gz:md5,95b3d1d24d576cbbf489468097f2c213", + "24000001-25000000_reg.gz:md5,d384006e4c0e8bd38b89fd1b82e22506", + "25000001-26000000.gz:md5,77230b5177f6410f9324af8dde33e020", + "25000001-26000000_reg.gz:md5,667eecb6d3ffdb5613581591835c5e3d", + "26000001-27000000.gz:md5,fe6ad01b323d83ae376bdeb6cf047e3c", + "26000001-27000000_reg.gz:md5,aafd124971e6424e8db99b42b091bd99", + "27000001-28000000.gz:md5,27c790ae843453556c7b2242c36abd1a", + "27000001-28000000_reg.gz:md5,b510b713aa42bafb38351842821977c8", + "28000001-29000000.gz:md5,a6f366a37ad04cc773236be4dd09ddaf", + "28000001-29000000_reg.gz:md5,5f18facec28af19bfdd8a108a8f506d7", + "29000001-30000000.gz:md5,82fe6926eb7a292b9fc2e50d484c8c2f", + "29000001-30000000_reg.gz:md5,e3958033b25781baa21d90d183ec2a5e", + "30000001-31000000.gz:md5,1dcca9aea49227138ef3644d2821c647", + "30000001-31000000_reg.gz:md5,d5926ccaad9b9ad4edd0060e4a598438", + "3000001-4000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "3000001-4000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "31000001-32000000.gz:md5,f8fc56294a92150c19e315e99a83b4a5", + "31000001-32000000_reg.gz:md5,bc04a5e426609b7e15cfeed4d2e687b5", + "32000001-33000000.gz:md5,69ee3fa14cd1465ecaf00568359c4d09", + "32000001-33000000_reg.gz:md5,61b19ff1e07d2d9ec2d2fb9bb7946765", + "33000001-34000000.gz:md5,3a9067073eac98fb2f9f31b5cd07b146", + "33000001-34000000_reg.gz:md5,02ee515697fef7bb35c5e76720956241", + "34000001-35000000.gz:md5,1a5a50eaac5c4a0931a36559fcfff49b", + "34000001-35000000_reg.gz:md5,ee77f95bd990e73bb8945f8ddac3f27a", + "35000001-36000000.gz:md5,a31f574314f954fda8712d6aa356b0dd", + "35000001-36000000_reg.gz:md5,22f939323e6bbb5568f61dfdd4f6ba8b", + "36000001-37000000.gz:md5,9932081e83e182b21b93d4e86a2e6d30", + "36000001-37000000_reg.gz:md5,6aa882038538c82611978f3f700bd769", + "37000001-38000000.gz:md5,89196534aff56af350468ddb6a71e4a4", + "37000001-38000000_reg.gz:md5,bfaba7fc51688b715d10b579fc85b0c1", + "38000001-39000000.gz:md5,c7918ce6c4d44677df392c6a9d8b0bf6", + "38000001-39000000_reg.gz:md5,d0b5146d04d3827ea2c9744e69808bb7", + "39000001-40000000.gz:md5,244eaac70c773fef1a6d8cbc55570e5c", + "39000001-40000000_reg.gz:md5,bade6790bc37a658510307d91bc1d935", + "40000001-41000000.gz:md5,ed8e8285e0f0fed12f74415e7db1ca1c", + "40000001-41000000_reg.gz:md5,575f377254cd26f3b511d8739ede2657", + "4000001-5000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "4000001-5000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "41000001-42000000.gz:md5,bf269b45019dc1fdeae4b0ca3f07c31e", + "41000001-42000000_reg.gz:md5,dcae8fe4c21ca4b556310a2ed9f7db61", + "42000001-43000000.gz:md5,5884bb2c85e652aa312217ea42413ec3", + "42000001-43000000_reg.gz:md5,b70a294777a97b99f583a26e56ee24b6", + "43000001-44000000.gz:md5,f369e7eb0ca67b8c829a6c079c686482", + "43000001-44000000_reg.gz:md5,3ecaa382d73864f3fa5b1b20774b2dac", + "44000001-45000000.gz:md5,09fa55af78b28d1c6267c1c218be1852", + "44000001-45000000_reg.gz:md5,8bd3cc296bc92ed5c62e2f8249519076", + "45000001-46000000.gz:md5,bffba50564d697fa575d61553a94be0d", + "45000001-46000000_reg.gz:md5,9157f35b881bb7978f50f3c0eb122dc1", + "46000001-47000000.gz:md5,06610987a1a871c66cd7587275c580ad", + "46000001-47000000_reg.gz:md5,9261ebfa3f619083ba69b1431c8b1e57", + "47000001-48000000.gz:md5,a795a475d38eec771623db0435eaafd3", + "47000001-48000000_reg.gz:md5,595a4d4a2dc70a2ae1584b9369c45f50", + "48000001-49000000.gz:md5,84b0074dd00d2916aea645d4c5322f0d", + "48000001-49000000_reg.gz:md5,10b336ce80cd5e95f5d087a0b021658b", + "5000001-6000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "5000001-6000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "6000001-7000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "6000001-7000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "7000001-8000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "7000001-8000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "8000001-9000000.gz:md5,d849fbcad66db7914bc015e2e166c22c", + "8000001-9000000_reg.gz:md5,85dae2a4f36126d97dc94a25fe10b7bb", + "9000001-10000000.gz:md5,6484090af4453287309e7fc256b2a3ee", + "9000001-10000000_reg.gz:md5,eb88b4c6e52ee1b7f38742fc63a552b9", + "all_vars.gz:md5,cc58de49787b22b3b119e20dc1d9c813", + "all_vars.gz.csi:md5,efe6feefb4af3fa1cbb835f217160d79" + ], + [ + "1-1000000.gz:md5,cde70e0bc1908a02142c1ca22d4bb782", + "1-1000000_reg.gz:md5,65080eebbe9e956482406f08b8248ba9", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,5a949a8c013243a54487187b34dfafbd", + "1-1000000_reg.gz:md5,0808c8cb8633f74cf764fe4b0cfafbdf", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,533a20fead6e26e287951bf2842e48f7", + "1-1000000_reg.gz:md5,9aab0e39e0688b826e6e736458ad2d1c", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,efb8aaa6a3bc78eff17ed28a43099383", + "1-1000000_reg.gz:md5,1a27d4ab43920ef151e0089f3e9e4a4b", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,6cd5ac90da0873007ab74b8c64cdbe5d", + "1-1000000_reg.gz:md5,2f56086ea334b8bc196caf38f4712c24", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,37ecdcf6536f1c7cdd94048939c215c3", + "1-1000000_reg.gz:md5,607b20b49f8359be58de4adba7687fbc", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,6843883020c41262309eed07df3f3af4", + "1-1000000_reg.gz:md5,051b6db155fab6629ef30e80e8cb7cdd", + "1000001-2000000.gz:md5,17181e7730e8cd55e46c202568f818ad", + "1000001-2000000_reg.gz:md5,051b6db155fab6629ef30e80e8cb7cdd", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,b1e3e86cea70e7bee39139856afc038b", + "1-1000000_reg.gz:md5,68693c4e6a9ffe8ce4a018aa0ee4c95a", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,edd409f4bbe5e63910afb85d05dbdb7a", + "1-1000000_reg.gz:md5,68a25e6d83d8e15183496b5a97c3a670", + "all_vars.gz:md5,d41d8cd98f00b204e9800998ecf8427e", + "all_vars.gz.csi:md5,e56c94d2b47dd51557b553b568e7ffb8" + ], + [ + "1-1000000.gz:md5,09351a00fe7fa572e6b0e1c023f3da55", + "1-1000000_reg.gz:md5,a774233304f72832896de2e9227221b0", + "all_vars.gz:md5,ee9370e9bf063fb4f52fe1ab0b45f3d0", + "all_vars.gz.csi:md5,0397561c6d0b6c8ae9d0c083bb69e1e5" + ], + "chr_synonyms.txt:md5,ecc5ec48a5fb60f5f7198f641a123254", + "info.txt:md5,296e24b6257be06762c21f0066cf6718" + ] + ], + "pLI_values_107.txt:md5,8e35e21aa84b5976776deda972883130", + "spliceai_21_scores_raw_indel_-v1.3-.vcf.gz:md5,46d6b81b89f26fb807c4f73e53828754", + "spliceai_21_scores_raw_indel_-v1.3-.vcf.gz.tbi:md5,a213a9f3156b0f2f6331ff35bc01f591", + "spliceai_21_scores_raw_snv_-v1.3-.vcf.gz:md5,b16af27abef55deb104af19b2d289813", + "spliceai_21_scores_raw_snv_-v1.3-.vcf.gz.tbi:md5,3fab1357156412ca02b2bdf075e97382" + ] + ] + ] + ] + ] + ], + "timestamp": "2026-06-30T13:02:36.500390581", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/prepare_references/tests/nextflow.config b/subworkflows/local/prepare_references/tests/nextflow.config new file mode 100644 index 000000000..5f820e8b8 --- /dev/null +++ b/subworkflows/local/prepare_references/tests/nextflow.config @@ -0,0 +1,61 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for defining DSL2 per module options and publishing paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Available keys to override module options: + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. + ext.when = Conditional clause +---------------------------------------------------------------------------------------- +*/ + +// +// Genome and reference preparation options +// + +process { + + withName: '.*PREPARE_REFERENCES:BWAMEME_INDEX_GENOME' { + ext.args = '-a meme' + } + + withName: '.*PREPARE_REFERENCES:SAMTOOLS_EXTRACT_MT' { + ext.args = { " ${params.mito_name} -o ${meta.id}_mt.fa" } + } + + withName: '.*PREPARE_REFERENCES:GATK_SHIFTFASTA' { + ext.args = { "--interval-file-name ${meta.id}_mt" } + } + + withName: '.*PREPARE_REFERENCES:TABIX_GNOMAD_AF' { + ext.args = '-s 1 -b 2 -e 2' + } + + withName: '.*PREPARE_REFERENCES:TABIX_BGZIPINDEX_VCFANNOEXTRA' { + ext.args2 = '--csi' + } + + withName: '.*PREPARE_REFERENCES:BEDTOOLS_PAD_TARGET_BED' { + ext.prefix = { "${meta.id}_pad${params.bait_padding}" } + ext.args = { "-b ${params.bait_padding}" } + } + + withName: '.*PREPARE_REFERENCES:TABIX_BGZIPINDEX_PADDED_BED' { + ext.prefix = { "${meta.id}_pad${params.bait_padding}" } + } + + withName: '.*PREPARE_REFERENCES:GATK_BILT' { + ext.prefix = { "${meta.id}_target" } + } + + withName: '.*PREPARE_REFERENCES:GATK_ILT' { + ext.args = { "--PADDING ${params.bait_padding} -SUBDIVISION_MODE INTERVAL_SUBDIVISION --SCATTER_COUNT 2" } + } + + withName: '.*PREPARE_REFERENCES:CAT_CAT_BAIT' { + ext.prefix = { "${meta.id}" } + } + +} diff --git a/subworkflows/local/qc_bam.nf b/subworkflows/local/qc_bam.nf deleted file mode 100644 index b1750b88a..000000000 --- a/subworkflows/local/qc_bam.nf +++ /dev/null @@ -1,107 +0,0 @@ -// -// A quality check subworkflow for processed bams. -// - -include { PICARD_COLLECTMULTIPLEMETRICS } from '../../modules/nf-core/picard/collectmultiplemetrics/main' -include { PICARD_COLLECTHSMETRICS } from '../../modules/nf-core/picard/collecthsmetrics/main' -include { CHROMOGRAPH as CHROMOGRAPH_COV } from '../../modules/nf-core/chromograph/main' -include { QUALIMAP_BAMQC } from '../../modules/nf-core/qualimap/bamqc/main' -include { TIDDIT_COV } from '../../modules/nf-core/tiddit/cov/main' -include { MOSDEPTH } from '../../modules/nf-core/mosdepth/main' -include { UCSC_WIGTOBIGWIG } from '../../modules/nf-core/ucsc/wigtobigwig/main' -include { PICARD_COLLECTWGSMETRICS as PICARD_COLLECTWGSMETRICS_WG } from '../../modules/nf-core/picard/collectwgsmetrics/main' -include { PICARD_COLLECTWGSMETRICS as PICARD_COLLECTWGSMETRICS_Y } from '../../modules/nf-core/picard/collectwgsmetrics/main' -include { SENTIEON_WGSMETRICS as SENTIEON_WGSMETRICS_WG } from '../../modules/nf-core/sentieon/wgsmetrics/main' -include { SENTIEON_WGSMETRICS as SENTIEON_WGSMETRICS_Y } from '../../modules/nf-core/sentieon/wgsmetrics/main' -include { NGSBITS_SAMPLEGENDER } from '../../modules/nf-core/ngsbits/samplegender/main' -include { VERIFYBAMID_VERIFYBAMID2 } from '../../modules/nf-core/verifybamid/verifybamid2/main' - -workflow QC_BAM { - - take: - ch_bam // channel: [mandatory] [ val(meta), path(bam) ] - ch_bai // channel: [mandatory] [ val(meta), path(bai) ] - ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_bait_intervals // channel: [mandatory] [ path(intervals_list) ] - ch_target_intervals // channel: [mandatory] [ path(intervals_list) ] - ch_chrom_sizes // channel: [mandatory] [ path(sizes) ] - ch_intervals_wgs // channel: [mandatory] [ path(intervals) ] - ch_intervals_y // channel: [mandatory] [ path(intervals) ] - ch_svd_bed // channel: [optional] [ path(bed) ] - ch_svd_mu // channel: [optional] [ path(meanpath) ] - ch_svd_ud // channel: [optional] [ path(ud) ] - ngsbits_samplegender_method // channel: [val(method)] - - main: - ch_cov = Channel.empty() - ch_cov_y = Channel.empty() - ch_versions = Channel.empty() - ch_qualimap = Channel.empty() - ch_ngsbits = Channel.empty() - - PICARD_COLLECTMULTIPLEMETRICS (ch_bam_bai, ch_genome_fasta, ch_genome_fai) - - ch_bam_bai - .combine(ch_bait_intervals) - .combine(ch_target_intervals) - .set { ch_hsmetrics_in} - - PICARD_COLLECTHSMETRICS (ch_hsmetrics_in, ch_genome_fasta, ch_genome_fai, [[],[]]) - if (!(params.skip_tools && params.skip_tools.split(',').contains('qualimap'))) { - ch_qualimap = QUALIMAP_BAMQC (ch_bam, []).results - ch_versions = ch_versions.mix(QUALIMAP_BAMQC.out.versions.first()) - } - TIDDIT_COV (ch_bam, [[],[]]) // 2nd pos. arg is req. only for cram input - - UCSC_WIGTOBIGWIG (TIDDIT_COV.out.wig, ch_chrom_sizes) - - CHROMOGRAPH_COV([[:],[]], TIDDIT_COV.out.wig, [[:],[]], [[:],[]], [[:],[]], [[:],[]], [[:],[]]) - - ch_bam_bai.map{ meta, bam, bai -> [meta, bam, bai, []]}.set{ch_mosdepth_in} - MOSDEPTH (ch_mosdepth_in, ch_genome_fasta) - - // COLLECT WGS METRICS - if (!params.analysis_type.equals("wes")) { - PICARD_COLLECTWGSMETRICS_WG ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_wgs ) - PICARD_COLLECTWGSMETRICS_Y ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_y ) - SENTIEON_WGSMETRICS_WG ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_wgs.map{ interval -> [[:], interval]} ) - SENTIEON_WGSMETRICS_Y ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_y.map{ interval -> [[:], interval]} ) - ch_cov = Channel.empty().mix(PICARD_COLLECTWGSMETRICS_WG.out.metrics, SENTIEON_WGSMETRICS_WG.out.wgs_metrics) - ch_cov_y = Channel.empty().mix(PICARD_COLLECTWGSMETRICS_Y.out.metrics, SENTIEON_WGSMETRICS_Y.out.wgs_metrics) - ch_versions = ch_versions.mix(PICARD_COLLECTWGSMETRICS_WG.out.versions.first(), SENTIEON_WGSMETRICS_WG.out.versions.first()) - ch_versions = ch_versions.mix(PICARD_COLLECTWGSMETRICS_Y.out.versions.first(), SENTIEON_WGSMETRICS_Y.out.versions.first()) - } - // Check sex - if (!(params.skip_tools && params.skip_tools.split(',').contains('ngsbits'))) { - NGSBITS_SAMPLEGENDER(ch_bam_bai, ch_genome_fasta, ch_genome_fai, ngsbits_samplegender_method) - ch_ngsbits = NGSBITS_SAMPLEGENDER.out.tsv - ch_versions = ch_versions.mix(NGSBITS_SAMPLEGENDER.out.versions.first()) - } - // Check contamination - ch_svd_in = ch_svd_ud.combine(ch_svd_mu).combine(ch_svd_bed).collect() - VERIFYBAMID_VERIFYBAMID2(ch_bam_bai, ch_svd_in, [], ch_genome_fasta.map {it-> it[1]}) - - ch_versions = ch_versions.mix(CHROMOGRAPH_COV.out.versions.first()) - ch_versions = ch_versions.mix(PICARD_COLLECTMULTIPLEMETRICS.out.versions.first()) - ch_versions = ch_versions.mix(PICARD_COLLECTHSMETRICS.out.versions.first()) - ch_versions = ch_versions.mix(TIDDIT_COV.out.versions.first()) - ch_versions = ch_versions.mix(UCSC_WIGTOBIGWIG.out.versions.first()) - ch_versions = ch_versions.mix(MOSDEPTH.out.versions.first()) - ch_versions = ch_versions.mix(VERIFYBAMID_VERIFYBAMID2.out.versions.first()) - - emit: - multiple_metrics = PICARD_COLLECTMULTIPLEMETRICS.out.metrics // channel: [ val(meta), path(metrics) ] - hs_metrics = PICARD_COLLECTHSMETRICS.out.metrics // channel: [ val(meta), path(metrics) ] - qualimap_results = ch_qualimap // channel: [ val(meta), path(qualimap_dir) ] - tiddit_wig = TIDDIT_COV.out.wig // channel: [ val(meta), path(wig) ] - bigwig = UCSC_WIGTOBIGWIG.out.bw // channel: [ val(meta), path(bw) ] - d4 = MOSDEPTH.out.per_base_d4 // channel: [ val(meta), path(d4) ] - global_dist = MOSDEPTH.out.global_txt // channel: [ val(meta), path(txt) ] - sex_check = ch_ngsbits // channel: [ val(meta), path(tsv) ] - self_sm = VERIFYBAMID_VERIFYBAMID2.out.self_sm // channel: [ val(meta), path(selfSM) ] - cov = ch_cov // channel: [ val(meta), path(metrics) ] - cov_y = ch_cov_y // channel: [ val(meta), path(metrics) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/qc_bam/main.nf b/subworkflows/local/qc_bam/main.nf new file mode 100644 index 000000000..130a39bc6 --- /dev/null +++ b/subworkflows/local/qc_bam/main.nf @@ -0,0 +1,122 @@ +// +// A quality check subworkflow for processed bams. +// + +include { CHROMOGRAPH as CHROMOGRAPH_COV } from '../../../modules/nf-core/chromograph/main' +include { MOSDEPTH } from '../../../modules/nf-core/mosdepth/main' +include { NGSBITS_SAMPLEGENDER } from '../../../modules/nf-core/ngsbits/samplegender/main' +include { PICARD_COLLECTHSMETRICS } from '../../../modules/nf-core/picard/collecthsmetrics/main' +include { PICARD_COLLECTMULTIPLEMETRICS } from '../../../modules/nf-core/picard/collectmultiplemetrics/main' +include { PICARD_COLLECTWGSMETRICS as PICARD_COLLECTWGSMETRICS_WG } from '../../../modules/nf-core/picard/collectwgsmetrics/main' +include { PICARD_COLLECTWGSMETRICS as PICARD_COLLECTWGSMETRICS_Y } from '../../../modules/nf-core/picard/collectwgsmetrics/main' +include { SAMBAMBA_DEPTH } from '../../../modules/nf-core/sambamba/depth/main' +include { SENTIEON_WGSMETRICS as SENTIEON_WGSMETRICS_WG } from '../../../modules/nf-core/sentieon/wgsmetrics/main' +include { SENTIEON_WGSMETRICS as SENTIEON_WGSMETRICS_Y } from '../../../modules/nf-core/sentieon/wgsmetrics/main' +include { TIDDIT_COV } from '../../../modules/nf-core/tiddit/cov/main' +include { UCSC_WIGTOBIGWIG } from '../../../modules/nf-core/ucsc/wigtobigwig/main' +include { VERIFYBAMID_VERIFYBAMID2 } from '../../../modules/nf-core/verifybamid/verifybamid2/main' + +workflow QC_BAM { + + take: + ch_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + ch_bait_intervals // channel: [mandatory] [ path(intervals_list) ] + ch_genome_chrsizes // channel: [mandatory] [ path(sizes) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + ch_intervals_wgs // channel: [mandatory] [ path(intervals) ] + ch_intervals_y // channel: [mandatory] [ path(intervals) ] + ch_ngsbits_method // channel: [val(method)] + ch_svd_bed // channel: [optional] [ path(bed) ] + ch_svd_mu // channel: [optional] [ path(meanpath) ] + ch_svd_ud // channel: [optional] [ path(ud) ] + ch_sambamba_bed // channel: [optional] [ val(meta), path(bed) ] + ch_target_intervals // channel: [mandatory] [ path(intervals_list) ] + val_analysis_type // string: "wes", "wgs", or "mito" + val_aligner // string: "bwa", "bwamem2", "bwameme", or "sentieon" + val_target_bed // string: path to target bed file + skip_ngsbits // boolean + + main: + ch_cov = channel.empty() + ch_cov_y = channel.empty() + ch_hsmetrics = channel.empty() + ch_ngsbits = channel.empty() + + PICARD_COLLECTMULTIPLEMETRICS (ch_bam_bai, ch_genome_fasta, ch_genome_fai) + + ch_bam_bai + .combine(ch_bait_intervals) + .combine(ch_target_intervals) + .set { ch_hsmetrics_in} + + if (val_target_bed) { + ch_hsmetrics = PICARD_COLLECTHSMETRICS (ch_hsmetrics_in, ch_genome_fasta, ch_genome_fai, [[:],[]], [[:],[]]).metrics + } + + TIDDIT_COV (ch_bam_bai, [[],[]]) // 2nd pos. arg is req. only for cram input + + UCSC_WIGTOBIGWIG (TIDDIT_COV.out.wig, ch_genome_chrsizes) + + CHROMOGRAPH_COV([[:],[]], TIDDIT_COV.out.wig, [[:],[]], [[:],[]], [[:],[]], [[:],[]], [[:],[]]) + + ch_bam_bai.map{ meta, bam, bai -> [meta, bam, bai, []]}.set{ch_mosdepth_in} + MOSDEPTH (ch_mosdepth_in, ch_genome_fasta) + + + SAMBAMBA_DEPTH(ch_bam_bai, ch_sambamba_bed, 'region') + + // COLLECT WGS METRICS + if (!val_analysis_type.equals("wes")) { + if (val_aligner.matches("bwa|bwameme|bwamem2")) { + PICARD_COLLECTWGSMETRICS_WG ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_wgs ) + PICARD_COLLECTWGSMETRICS_Y ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_y ) + ch_cov = PICARD_COLLECTWGSMETRICS_WG.out.metrics + ch_cov_y = PICARD_COLLECTWGSMETRICS_Y.out.metrics + } else if (val_aligner.equals("sentieon")) { + SENTIEON_WGSMETRICS_WG ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_wgs.map{ interval -> [[:], interval]} ) + SENTIEON_WGSMETRICS_Y ( ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_intervals_y.map{ interval -> [[:], interval]} ) + ch_cov = SENTIEON_WGSMETRICS_WG.out.wgs_metrics + ch_cov_y = SENTIEON_WGSMETRICS_Y.out.wgs_metrics + } + } + // Check sex + if (!skip_ngsbits) { + NGSBITS_SAMPLEGENDER(ch_bam_bai, ch_genome_fasta, ch_genome_fai, ch_ngsbits_method) + ch_ngsbits = NGSBITS_SAMPLEGENDER.out.tsv + } + // Check contamination + ch_svd_in = ch_svd_ud.combine(ch_svd_mu).combine(ch_svd_bed).collect() + VERIFYBAMID_VERIFYBAMID2(ch_bam_bai, ch_svd_in, [], ch_genome_fasta.map {_meta, fasta-> fasta}) + + emit: + chromograph_cov_plots = CHROMOGRAPH_COV.out.plots // channel: [ val(meta), path(png) ] + mosdepth_global_txt = MOSDEPTH.out.global_txt // channel: [ val(meta), path(txt) ] + mosdepth_per_base_bed = MOSDEPTH.out.per_base_bed // channel: [ val(meta), path(bed.gz) ] + mosdepth_per_base_csi = MOSDEPTH.out.per_base_csi // channel: [ val(meta), path(csi) ] + mosdepth_per_base_d4 = MOSDEPTH.out.per_base_d4 // channel: [ val(meta), path(d4) ] + mosdepth_quantized_bed = MOSDEPTH.out.quantized_bed // channel: [ val(meta), path(bed.gz) ] + mosdepth_quantized_csi = MOSDEPTH.out.quantized_csi // channel: [ val(meta), path(csi) ] + mosdepth_regions_bed = MOSDEPTH.out.regions_bed // channel: [ val(meta), path(bed.gz) ] + mosdepth_regions_csi = MOSDEPTH.out.regions_csi // channel: [ val(meta), path(csi) ] + mosdepth_regions_txt = MOSDEPTH.out.regions_txt // channel: [ val(meta), path(txt) ] + mosdepth_summary_txt = MOSDEPTH.out.summary_txt // channel: [ val(meta), path(txt) ] + mosdepth_thresholds_bed = MOSDEPTH.out.thresholds_bed // channel: [ val(meta), path(bed.gz) ] + mosdepth_thresholds_csi = MOSDEPTH.out.thresholds_csi // channel: [ val(meta), path(csi) ] + ngsbits_samplegender_tsv = ch_ngsbits // channel: [ val(meta), path(tsv) ] + picard_collecthsmetrics_metrics = ch_hsmetrics // channel: [ val(meta), path(metrics) ] + picard_collectmultiplemetrics_metrics = PICARD_COLLECTMULTIPLEMETRICS.out.metrics // channel: [ val(meta), path(metrics) ] + picard_collectmultiplemetrics_pdf = PICARD_COLLECTMULTIPLEMETRICS.out.pdf // channel: [ val(meta), path(pdf) ] + sambamba_depth_bed = SAMBAMBA_DEPTH.out.bed // channel: [ val(meta), path(bed) ] + tiddit_cov_cov = TIDDIT_COV.out.cov // channel: [ val(meta), path(bed) ] + tiddit_cov_wig = TIDDIT_COV.out.wig // channel: [ val(meta), path(wig) ] + ucsc_wigtobigwig_bw = UCSC_WIGTOBIGWIG.out.bw // channel: [ val(meta), path(bw) ] + verifybamid_ancestry = VERIFYBAMID_VERIFYBAMID2.out.ancestry // channel: [ val(meta), path(ancestry) ] + verifybamid_bed = VERIFYBAMID_VERIFYBAMID2.out.bed // channel: [ val(meta), path(bed) ] + verifybamid_log = VERIFYBAMID_VERIFYBAMID2.out.log // channel: [ val(meta), path(log) ] + verifybamid_mu = VERIFYBAMID_VERIFYBAMID2.out.mu // channel: [ val(meta), path(mu) ] + verifybamid_self_sm = VERIFYBAMID_VERIFYBAMID2.out.self_sm // channel: [ val(meta), path(selfSM) ] + verifybamid_ud = VERIFYBAMID_VERIFYBAMID2.out.ud // channel: [ val(meta), path(ud) ] + wgsmetrics_wg = ch_cov // channel: [ val(meta), path(metrics) ] + wgsmetrics_y = ch_cov_y // channel: [ val(meta), path(metrics) ] +} diff --git a/subworkflows/local/qc_bam/tests/main.nf.test b/subworkflows/local/qc_bam/tests/main.nf.test new file mode 100644 index 000000000..3e50abfa6 --- /dev/null +++ b/subworkflows/local/qc_bam/tests/main.nf.test @@ -0,0 +1,349 @@ +nextflow_workflow { + + name "Test Workflow QC_BAM" + script "subworkflows/local/qc_bam/main.nf" + workflow "QC_BAM" + + tag "subworkflows" + tag "qc_bam" + + tag "picard/collectmultiplemetrics" + tag "picard/collecthsmetrics" + tag "chromograph" + tag "qualimap/bamqc" + tag "tiddit/cov" + tag "mosdepth" + tag "sambamba/depth" + tag "ucsc/wigtobigwig" + tag "picard/collectwgsmetrics" + tag "sentieon/wgsmetrics" + tag "ngsbits/samplegender" + tag "verifybamid/verifybamid2" + + config "./nextflow.config" + + test("QC_BAM - test, bwamem2") { + + when { + params { + skip_tools = null + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of(file(params.pipelines_testdata_base_path + 'reference/bait.interval_list', checkIfExists: true)).collect() + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)).collect() + input[6] = channel.empty() + input[7] = channel.of('xy') + input[8] = channel.empty() + input[9] = channel.empty() + input[10] = channel.empty() + input[11] = channel.empty() + input[12] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target.interval_list', checkIfExists: true)).collect() + input[13] = 'wgs' + input[14] = 'bwamem2' + input[15] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[16] = true + """ + } + } + + then { + assertAll ( + { assert workflow.success }, + { assert snapshot( + workflow.out.picard_collectmultiplemetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collectmultiplemetrics_pdf + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collecthsmetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.mosdepth_global_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_summary_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_bed + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_csi + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_d4 + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_wg + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_y + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_wig + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_cov + .collect { _meta, files -> file(files).name }, + workflow.out.ucsc_wigtobigwig_bw + .collect { _meta, files -> file(files).name }, + workflow.out.chromograph_cov_plots + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.sambamba_depth_bed + .collect { _meta, files -> file(files).name }, + workflow.out.verifybamid_self_sm + .collect { _meta, files -> file(files).name }, + workflow.out.ngsbits_samplegender_tsv + .collect { _meta, files -> file(files).name } + ).match() + } + ) + } + + } + + test("QC_BAM - test, bwamem2, stub") { + + options "-stub" + + when { + params { + skip_tools = null + outdir = "$outputDir" + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of(file(params.pipelines_testdata_base_path + 'reference/bait.interval_list', checkIfExists: true)).collect() + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)).collect() + input[6] = channel.empty() + input[7] = channel.of('xy') + input[8] = channel.empty() + input[9] = channel.empty() + input[10] = channel.empty() + input[11] = channel.empty() + input[12] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target.interval_list', checkIfExists: true)).collect() + input[13] = 'wgs' + input[14] = 'bwamem2' + input[15] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[16] = true + """ + } + } + + then { + assertAll( + { assert snapshot( + workflow.out.picard_collectmultiplemetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collectmultiplemetrics_pdf + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collecthsmetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.mosdepth_global_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_summary_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_bed + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_csi + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_d4 + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_wg + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_y + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_wig + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_cov + .collect { _meta, files -> file(files).name }, + workflow.out.ucsc_wigtobigwig_bw + .collect { _meta, files -> file(files).name }, + workflow.out.chromograph_cov_plots + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.sambamba_depth_bed + .collect { _meta, files -> file(files).name }, + workflow.out.verifybamid_self_sm + .collect { _meta, files -> file(files).name }, + workflow.out.ngsbits_samplegender_tsv + .collect { _meta, files -> file(files).name } + ).match() + } + ) + } + + } + + test("QC_BAM - test, sentieon") { + + when { + params { + outdir = "$outputDir" + skip_tools = null + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of(file(params.pipelines_testdata_base_path + 'reference/bait.interval_list', checkIfExists: true)).collect() + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)).collect() + input[6] = channel.empty() + input[7] = channel.of('xy') + input[8] = channel.empty() + input[9] = channel.empty() + input[10] = channel.empty() + input[11] = channel.empty() + input[12] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target.interval_list', checkIfExists: true)).collect() + input[13] = 'wgs' + input[14] = 'sentieon' + input[15] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[16] = true + """ + } + } + + then { + assertAll ( + { assert workflow.success }, + { assert snapshot( + workflow.out.picard_collectmultiplemetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collectmultiplemetrics_pdf + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collecthsmetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.mosdepth_global_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_summary_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_bed + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_csi + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_d4 + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_wg + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_y + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_wig + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_cov + .collect { _meta, files -> file(files).name }, + workflow.out.ucsc_wigtobigwig_bw + .collect { _meta, files -> file(files).name }, + workflow.out.chromograph_cov_plots + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.sambamba_depth_bed + .collect { _meta, files -> file(files).name }, + workflow.out.verifybamid_self_sm + .collect { _meta, files -> file(files).name }, + workflow.out.ngsbits_samplegender_tsv + .collect { _meta, files -> file(files).name } + ).match() + } + ) + } + } + + test("QC_BAM - test, sentieon, stub") { + + options "-stub" + + when { + params { + outdir = "$outputDir" + skip_tools = null + } + workflow { + """ + input[0] = channel.of( + [ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true)], + [file(params.pipelines_testdata_base_path + '/testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true)] + ] + ) + input[1] = channel.of(file(params.pipelines_testdata_base_path + 'reference/bait.interval_list', checkIfExists: true)).collect() + input[2] = channel.of(file(params.pipelines_testdata_base_path + 'reference/reference_chr.sizes', checkIfExists: true)).collect() + input[3] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta.fai', checkIfExists: true)).collect() + input[4] = channel.of([id:'genome'], file(params.pipelines_testdata_base_path + 'reference/reference.fasta', checkIfExists: true)).collect() + input[5] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target_wgs.interval_list', checkIfExists: true)).collect() + input[6] = channel.empty() + input[7] = channel.of('xy') + input[8] = channel.empty() + input[9] = channel.empty() + input[10] = channel.empty() + input[11] = channel.empty() + input[12] = channel.of(file(params.pipelines_testdata_base_path + 'reference/target.interval_list', checkIfExists: true)).collect() + input[13] = 'wgs' + input[14] = 'sentieon' + input[15] = params.pipelines_testdata_base_path + 'reference/target.bed' + input[16] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.picard_collectmultiplemetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collectmultiplemetrics_pdf + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.picard_collecthsmetrics_metrics + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.mosdepth_global_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_summary_txt + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_bed + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_csi + .collect { _meta, files -> file(files).name }, + workflow.out.mosdepth_per_base_d4 + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_wg + .collect { _meta, files -> file(files).name }, + workflow.out.wgsmetrics_y + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_wig + .collect { _meta, files -> file(files).name }, + workflow.out.tiddit_cov_cov + .collect { _meta, files -> file(files).name }, + workflow.out.ucsc_wigtobigwig_bw + .collect { _meta, files -> file(files).name }, + workflow.out.chromograph_cov_plots + .collect { _meta, files -> files instanceof List ? files.collect { file(it).name }.sort() : file(files).name }, + workflow.out.sambamba_depth_bed + .collect { _meta, files -> file(files).name }, + workflow.out.verifybamid_self_sm + .collect { _meta, files -> file(files).name }, + workflow.out.ngsbits_samplegender_tsv + .collect { _meta, files -> file(files).name } + ).match() + } + ) + } + } +} diff --git a/subworkflows/local/qc_bam/tests/main.nf.test.snap b/subworkflows/local/qc_bam/tests/main.nf.test.snap new file mode 100644 index 000000000..c3bab311a --- /dev/null +++ b/subworkflows/local/qc_bam/tests/main.nf.test.snap @@ -0,0 +1,394 @@ +{ + "QC_BAM - test, bwamem2, stub": { + "content": [ + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics" + ] + ], + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ], + [ + "earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics" + ], + [ + "earlycasualcaiman_mosdepth.global.dist.txt" + ], + [ + "earlycasualcaiman_mosdepth.summary.txt" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz.csi" + ], + [ + "earlycasualcaiman_mosdepth.per-base.d4" + ], + [ + "earlycasualcaiman_wgsmetrics.CollectWgsMetrics.coverage_metrics" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.wig" + ], + [ + "earlycasualcaiman_tidditcov.bed" + ], + [ + "earlycasualcaiman_tidditcov.bw" + ], + [ + [ + "earlycasualcaiman_tidditcov.wig_chr1.png", + "earlycasualcaiman_tidditcov.wig_chr10.png", + "earlycasualcaiman_tidditcov.wig_chr11.png", + "earlycasualcaiman_tidditcov.wig_chr12.png", + "earlycasualcaiman_tidditcov.wig_chr13.png", + "earlycasualcaiman_tidditcov.wig_chr14.png", + "earlycasualcaiman_tidditcov.wig_chr15.png", + "earlycasualcaiman_tidditcov.wig_chr16.png", + "earlycasualcaiman_tidditcov.wig_chr17.png", + "earlycasualcaiman_tidditcov.wig_chr18.png", + "earlycasualcaiman_tidditcov.wig_chr19.png", + "earlycasualcaiman_tidditcov.wig_chr2.png", + "earlycasualcaiman_tidditcov.wig_chr20.png", + "earlycasualcaiman_tidditcov.wig_chr21.png", + "earlycasualcaiman_tidditcov.wig_chr22.png", + "earlycasualcaiman_tidditcov.wig_chr3.png", + "earlycasualcaiman_tidditcov.wig_chr4.png", + "earlycasualcaiman_tidditcov.wig_chr5.png", + "earlycasualcaiman_tidditcov.wig_chr6.png", + "earlycasualcaiman_tidditcov.wig_chr7.png", + "earlycasualcaiman_tidditcov.wig_chr8.png", + "earlycasualcaiman_tidditcov.wig_chr9.png", + "earlycasualcaiman_tidditcov.wig_chrM.png", + "earlycasualcaiman_tidditcov.wig_chrX.png", + "earlycasualcaiman_tidditcov.wig_chrY.png" + ] + ], + [ + + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-15T14:03:53.405773659", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "QC_BAM - test, sentieon, stub": { + "content": [ + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics" + ] + ], + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ], + [ + "earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics" + ], + [ + "earlycasualcaiman_mosdepth.global.dist.txt" + ], + [ + "earlycasualcaiman_mosdepth.summary.txt" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz.csi" + ], + [ + "earlycasualcaiman_mosdepth.per-base.d4" + ], + [ + "earlycasualcaiman_wgsmetrics.txt" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.wig" + ], + [ + "earlycasualcaiman_tidditcov.bed" + ], + [ + "earlycasualcaiman_tidditcov.bw" + ], + [ + [ + "earlycasualcaiman_tidditcov.wig_chr1.png", + "earlycasualcaiman_tidditcov.wig_chr10.png", + "earlycasualcaiman_tidditcov.wig_chr11.png", + "earlycasualcaiman_tidditcov.wig_chr12.png", + "earlycasualcaiman_tidditcov.wig_chr13.png", + "earlycasualcaiman_tidditcov.wig_chr14.png", + "earlycasualcaiman_tidditcov.wig_chr15.png", + "earlycasualcaiman_tidditcov.wig_chr16.png", + "earlycasualcaiman_tidditcov.wig_chr17.png", + "earlycasualcaiman_tidditcov.wig_chr18.png", + "earlycasualcaiman_tidditcov.wig_chr19.png", + "earlycasualcaiman_tidditcov.wig_chr2.png", + "earlycasualcaiman_tidditcov.wig_chr20.png", + "earlycasualcaiman_tidditcov.wig_chr21.png", + "earlycasualcaiman_tidditcov.wig_chr22.png", + "earlycasualcaiman_tidditcov.wig_chr3.png", + "earlycasualcaiman_tidditcov.wig_chr4.png", + "earlycasualcaiman_tidditcov.wig_chr5.png", + "earlycasualcaiman_tidditcov.wig_chr6.png", + "earlycasualcaiman_tidditcov.wig_chr7.png", + "earlycasualcaiman_tidditcov.wig_chr8.png", + "earlycasualcaiman_tidditcov.wig_chr9.png", + "earlycasualcaiman_tidditcov.wig_chrM.png", + "earlycasualcaiman_tidditcov.wig_chrX.png", + "earlycasualcaiman_tidditcov.wig_chrY.png" + ] + ], + [ + + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-15T14:05:39.811825004", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "QC_BAM - test, bwamem2": { + "content": [ + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics" + ] + ], + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ], + [ + "earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics" + ], + [ + "earlycasualcaiman_mosdepth.mosdepth.global.dist.txt" + ], + [ + "earlycasualcaiman_mosdepth.mosdepth.summary.txt" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz.csi" + ], + [ + + ], + [ + "earlycasualcaiman_wgsmetrics.CollectWgsMetrics.coverage_metrics" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.wig" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.bw" + ], + [ + [ + "earlycasualcaiman_tidditcov_1.png", + "earlycasualcaiman_tidditcov_10.png", + "earlycasualcaiman_tidditcov_11.png", + "earlycasualcaiman_tidditcov_12.png", + "earlycasualcaiman_tidditcov_13.png", + "earlycasualcaiman_tidditcov_14.png", + "earlycasualcaiman_tidditcov_15.png", + "earlycasualcaiman_tidditcov_16.png", + "earlycasualcaiman_tidditcov_17.png", + "earlycasualcaiman_tidditcov_18.png", + "earlycasualcaiman_tidditcov_19.png", + "earlycasualcaiman_tidditcov_2.png", + "earlycasualcaiman_tidditcov_20.png", + "earlycasualcaiman_tidditcov_21.png", + "earlycasualcaiman_tidditcov_22.png", + "earlycasualcaiman_tidditcov_3.png", + "earlycasualcaiman_tidditcov_4.png", + "earlycasualcaiman_tidditcov_5.png", + "earlycasualcaiman_tidditcov_6.png", + "earlycasualcaiman_tidditcov_7.png", + "earlycasualcaiman_tidditcov_8.png", + "earlycasualcaiman_tidditcov_9.png", + "earlycasualcaiman_tidditcov_M.png", + "earlycasualcaiman_tidditcov_X.png", + "earlycasualcaiman_tidditcov_Y.png" + ] + ], + [ + + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-15T14:02:21.833990928", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "QC_BAM - test, sentieon": { + "content": [ + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics" + ] + ], + [ + [ + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ], + [ + "earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics" + ], + [ + "earlycasualcaiman_mosdepth.mosdepth.global.dist.txt" + ], + [ + "earlycasualcaiman_mosdepth.mosdepth.summary.txt" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz" + ], + [ + "earlycasualcaiman_mosdepth.per-base.bed.gz.csi" + ], + [ + + ], + [ + "earlycasualcaiman_wgsmetrics.txt" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.wig" + ], + [ + + ], + [ + "earlycasualcaiman_tidditcov.bw" + ], + [ + [ + "earlycasualcaiman_tidditcov_1.png", + "earlycasualcaiman_tidditcov_10.png", + "earlycasualcaiman_tidditcov_11.png", + "earlycasualcaiman_tidditcov_12.png", + "earlycasualcaiman_tidditcov_13.png", + "earlycasualcaiman_tidditcov_14.png", + "earlycasualcaiman_tidditcov_15.png", + "earlycasualcaiman_tidditcov_16.png", + "earlycasualcaiman_tidditcov_17.png", + "earlycasualcaiman_tidditcov_18.png", + "earlycasualcaiman_tidditcov_19.png", + "earlycasualcaiman_tidditcov_2.png", + "earlycasualcaiman_tidditcov_20.png", + "earlycasualcaiman_tidditcov_21.png", + "earlycasualcaiman_tidditcov_22.png", + "earlycasualcaiman_tidditcov_3.png", + "earlycasualcaiman_tidditcov_4.png", + "earlycasualcaiman_tidditcov_5.png", + "earlycasualcaiman_tidditcov_6.png", + "earlycasualcaiman_tidditcov_7.png", + "earlycasualcaiman_tidditcov_8.png", + "earlycasualcaiman_tidditcov_9.png", + "earlycasualcaiman_tidditcov_M.png", + "earlycasualcaiman_tidditcov_X.png", + "earlycasualcaiman_tidditcov_Y.png" + ] + ], + [ + + ], + [ + + ], + [ + + ] + ], + "timestamp": "2026-06-15T14:17:24.028920433", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/qc_bam/tests/nextflow.config b/subworkflows/local/qc_bam/tests/nextflow.config new file mode 100644 index 000000000..f33ab2dc8 --- /dev/null +++ b/subworkflows/local/qc_bam/tests/nextflow.config @@ -0,0 +1,55 @@ +process { + + withName: '.*QC_BAM:PICARD_COLLECTMULTIPLEMETRICS' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_multiplemetrics" } + } + + withName: '.*QC_BAM:PICARD_COLLECTHSMETRICS' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_hsmetrics" } + } + + withName: '.*QC_BAM:TIDDIT_COV' { + ext.args = '-z 500 -w' + ext.prefix = { "${meta.id}_tidditcov" } + } + + withName: '.*QC_BAM:UCSC_WIGTOBIGWIG' { + ext.args = '-clip' + ext.prefix = { "${meta.id}_tidditcov" } + } + + withName: '.*QC_BAM:CHROMOGRAPH_COV' { + ext.args = '--euploid --step 500' + ext.prefix = { "${meta2.id}_chromographcov" } + } + + withName: '.*QC_BAM:MOSDEPTH' { + ext.prefix = { "${meta.id}_mosdepth" } + } + + withName: '.*QC_BAM:NGSBITS_SAMPLEGENDER' { + // NGSBITS_SAMPLEGENDER needs a chrX and chrY in order to run so we skip it for the two test profiles + ext.when = { !(workflow.profile.tokenize(',').intersect(['test', 'test_singleton', 'test_sentieon', 'test_full']).size() >= 1) } + ext.prefix = { "${meta.id}_ngsbits_sex" } + } + + withName: '.*QC_BAM:PICARD_COLLECTWGSMETRICS_WG' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_wgsmetrics" } + } + + withName: '.*QC_BAM:PICARD_COLLECTWGSMETRICS_Y' { + ext.args = "--TMP_DIR ." + ext.prefix = { "${meta.id}_wgsmetrics_y" } + } + + withName: '.*QC_BAM:SENTIEON_WGSMETRICS_WG' { + ext.prefix = { "${meta.id}_wgsmetrics" } + } + + withName: '.*QC_BAM:SENTIEON_WGSMETRICS_Y' { + ext.prefix = { "${meta.id}_wgsmetrics_y" } + } +} diff --git a/subworkflows/local/rank_variants.nf b/subworkflows/local/rank_variants.nf deleted file mode 100644 index 29399d4f3..000000000 --- a/subworkflows/local/rank_variants.nf +++ /dev/null @@ -1,55 +0,0 @@ -// -// A subworkflow to score and rank variants. -// - -include { GENMOD_ANNOTATE } from '../../modules/nf-core/genmod/annotate/main' -include { GENMOD_MODELS } from '../../modules/nf-core/genmod/models/main' -include { GENMOD_SCORE } from '../../modules/nf-core/genmod/score/main' -include { GENMOD_COMPOUND } from '../../modules/nf-core/genmod/compound/main' -include { BCFTOOLS_SORT } from '../../modules/nf-core/bcftools/sort/main' -include { TABIX_BGZIP } from '../../modules/nf-core/tabix/bgzip/main' -include { TABIX_TABIX } from '../../modules/nf-core/tabix/tabix/main' - -workflow RANK_VARIANTS { - - take: - ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] - ch_pedfile // channel: [mandatory] [ path(ped) ] - ch_reduced_penetrance // channel: [mandatory] [ path(pentrance) ] - ch_score_config // channel: [mandatory] [ path(ini) ] - - main: - ch_versions = Channel.empty() - - GENMOD_ANNOTATE(ch_vcf) - - ch_models_in = GENMOD_ANNOTATE.out.vcf.combine(ch_pedfile) - - GENMOD_MODELS(ch_models_in, ch_reduced_penetrance) - - ch_score_in = GENMOD_MODELS.out.vcf.combine(ch_pedfile) - - GENMOD_SCORE(ch_score_in, ch_score_config) - - GENMOD_COMPOUND(GENMOD_SCORE.out.vcf) - - BCFTOOLS_SORT(GENMOD_COMPOUND.out.vcf) // SV file needs to be sorted before indexing - - TABIX_BGZIP(GENMOD_COMPOUND.out.vcf) //run only for SNVs - - ch_vcf = TABIX_BGZIP.out.output.mix(BCFTOOLS_SORT.out.vcf) - - TABIX_TABIX (ch_vcf) - - ch_versions = ch_versions.mix(GENMOD_ANNOTATE.out.versions) - ch_versions = ch_versions.mix(GENMOD_MODELS.out.versions) - ch_versions = ch_versions.mix(GENMOD_SCORE.out.versions) - ch_versions = ch_versions.mix(GENMOD_COMPOUND.out.versions) - ch_versions = ch_versions.mix(BCFTOOLS_SORT.out.versions) - ch_versions = ch_versions.mix(TABIX_BGZIP.out.versions) - ch_versions = ch_versions.mix(TABIX_TABIX.out.versions) - - emit: - vcf = ch_vcf // channel: [ val(meta), path(vcf) ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/rank_variants/main.nf b/subworkflows/local/rank_variants/main.nf new file mode 100644 index 000000000..aaf7b3dbb --- /dev/null +++ b/subworkflows/local/rank_variants/main.nf @@ -0,0 +1,47 @@ +// +// A subworkflow to score and rank variants. +// + +include { BCFTOOLS_SORT } from '../../../modules/nf-core/bcftools/sort/main' +include { GENMOD_ANNOTATE } from '../../../modules/nf-core/genmod/annotate/main' +include { GENMOD_COMPOUND } from '../../../modules/nf-core/genmod/compound/main' +include { GENMOD_MODELS } from '../../../modules/nf-core/genmod/models/main' +include { GENMOD_SCORE } from '../../../modules/nf-core/genmod/score/main' +include { TABIX_BGZIPTABIX } from '../../../modules/nf-core/tabix/bgziptabix/main' + +workflow RANK_VARIANTS { + + take: + ch_pedfile // channel: [mandatory] [ path(ped) ] + ch_reduced_penetrance // channel: [mandatory] [ path(pentrance) ] + ch_score_config // channel: [mandatory] [ path(ini) ] + ch_vcf // channel: [mandatory] [ val(meta), path(vcf) ] + process_with_sort // Boolean + + main: + GENMOD_ANNOTATE(ch_vcf) + + ch_models_in = GENMOD_ANNOTATE.out.vcf.combine(ch_pedfile) + + GENMOD_MODELS(ch_models_in, ch_reduced_penetrance) + + ch_score_in = GENMOD_MODELS.out.vcf.combine(ch_pedfile) + + GENMOD_SCORE(ch_score_in, ch_score_config) + + GENMOD_COMPOUND(GENMOD_SCORE.out.vcf) + + ch_tbi = channel.empty() + + if (process_with_sort) { + ch_vcf = BCFTOOLS_SORT(GENMOD_COMPOUND.out.vcf).vcf // SV file needs to be sorted before indexing + ch_tbi = BCFTOOLS_SORT.out.tbi + } else { + ch_vcf = TABIX_BGZIPTABIX(GENMOD_COMPOUND.out.vcf).gz_index.map { meta, vcf, _tbi -> [meta, vcf] } //run only for SNVs + ch_tbi = TABIX_BGZIPTABIX.out.gz_index.map { meta, _gz, tbi -> [meta, tbi] } + } + + emit: + tbi = ch_tbi // channel: [ val(meta), path(tbi) ] + vcf = ch_vcf // channel: [ val(meta), path(vcf) ] +} diff --git a/subworkflows/local/rank_variants/tests/main.nf.test b/subworkflows/local/rank_variants/tests/main.nf.test new file mode 100644 index 000000000..1d76f92dc --- /dev/null +++ b/subworkflows/local/rank_variants/tests/main.nf.test @@ -0,0 +1,72 @@ +nextflow_workflow { + + name "Test Workflow RANK_VARIANTS" + script "subworkflows/local/rank_variants/main.nf" + workflow "RANK_VARIANTS" + + tag "subworkflows" + tag "rank_variants" + + tag "genmod/annotate" + tag "genmod/models" + tag "genmod/score" + tag "genmod/compound" + tag "bcftools/sort" + tag "tabix/bgziptabix" + + test("RANK_VARIANTS - SNV (process_with_sort = false), stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.value(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/ped/justhusky.ped', checkIfExists: true)) + input[1] = channel.value(file(params.pipelines_testdata_base_path + 'reference/reduced_penetrance.tsv', checkIfExists: true)) + input[2] = channel.value(file(params.pipelines_testdata_base_path + 'reference/rank_model_snv.ini', checkIfExists: true)) + input[3] = channel.of([ + [id:'justhusky', single_end: false], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz', checkIfExists: true) + ]) + input[4] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("RANK_VARIANTS - SV (process_with_sort = true), stub") { + + options "-stub" + + config "./nextflow.config" + when { + workflow { + """ + input[0] = channel.value(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/ped/justhusky.ped', checkIfExists: true)) + input[1] = channel.value(file(params.pipelines_testdata_base_path + 'reference/reduced_penetrance.tsv', checkIfExists: true)) + input[2] = channel.value(file(params.pipelines_testdata_base_path + 'reference/rank_model_sv.ini', checkIfExists: true)) + input[3] = channel.of([ + [id:'justhusky', single_end: false], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz', checkIfExists: true) + ]) + input[4] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + +} diff --git a/subworkflows/local/rank_variants/tests/main.nf.test.snap b/subworkflows/local/rank_variants/tests/main.nf.test.snap new file mode 100644 index 000000000..91291db97 --- /dev/null +++ b/subworkflows/local/rank_variants/tests/main.nf.test.snap @@ -0,0 +1,96 @@ +{ + "RANK_VARIANTS - SV (process_with_sort = true), stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-29T15:43:51.267701775", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "RANK_VARIANTS - SNV (process_with_sort = false), stub": { + "content": [ + { + "0": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "tbi": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "justhusky", + "single_end": false + }, + "justhusky.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-06-29T15:39:16.158216602", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/rank_variants/tests/nextflow.config b/subworkflows/local/rank_variants/tests/nextflow.config new file mode 100644 index 000000000..6770a0c79 --- /dev/null +++ b/subworkflows/local/rank_variants/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'RANK_VARIANTS:BCFTOOLS_SORT' { + ext.args = "--output-type z --write-index=tbi" + } +} diff --git a/subworkflows/local/scatter_genome.nf b/subworkflows/local/scatter_genome.nf deleted file mode 100644 index db95dfb23..000000000 --- a/subworkflows/local/scatter_genome.nf +++ /dev/null @@ -1,29 +0,0 @@ -// -// A subworkflow to create genome interval files necessary for bam/vcf scatter operations. -// - -include { BUILD_BED } from '../../modules/local/create_bed_from_fai' -include { GATK4_SPLITINTERVALS } from '../../modules/nf-core/gatk4/splitintervals/main' - -workflow SCATTER_GENOME { - - take: - ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] - - main: - ch_versions = Channel.empty() - - BUILD_BED (ch_genome_fai) - - GATK4_SPLITINTERVALS(BUILD_BED.out.bed, ch_genome_fasta, ch_genome_fai, ch_genome_dictionary) - - ch_versions = ch_versions.mix(BUILD_BED.out.versions) - ch_versions = ch_versions.mix(GATK4_SPLITINTERVALS.out.versions) - - emit: - bed = BUILD_BED.out.bed.collect() // channel: [ val(meta), path(bed) ] - split_intervals = GATK4_SPLITINTERVALS.out.split_intervals.map { meta, it -> it }.flatten().collate(1) // channel: [ val(meta), [ path(interval_lists) ] ] - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/scatter_genome/main.nf b/subworkflows/local/scatter_genome/main.nf new file mode 100644 index 000000000..6c898ba12 --- /dev/null +++ b/subworkflows/local/scatter_genome/main.nf @@ -0,0 +1,24 @@ +// +// A subworkflow to create genome interval files necessary for bam/vcf scatter operations. +// + +include { GATK4_SPLITINTERVALS } from '../../../modules/nf-core/gatk4/splitintervals/main' +include { GAWK as GENOME_FAI_TO_BED } from '../../../modules/nf-core/gawk' + +workflow SCATTER_GENOME { + + take: + ch_genome_dictionary // channel: [mandatory] [ val(meta), path(dict) ] + ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] + ch_genome_fasta // channel: [mandatory] [ val(meta), path(fasta) ] + + main: + + GENOME_FAI_TO_BED (ch_genome_fai, [], false) + + GATK4_SPLITINTERVALS(GENOME_FAI_TO_BED.out.output, ch_genome_fasta, ch_genome_fai, ch_genome_dictionary) + + emit: + gatk4_splitintervals_split_intervals = GATK4_SPLITINTERVALS.out.split_intervals // channel: [ val(meta), path(interval_list) ] + genome_fai_to_bed_output = GENOME_FAI_TO_BED.out.output.collect() // channel: [ val(meta), path(bed) ] +} diff --git a/subworkflows/local/scatter_genome/tests/main.nf.test b/subworkflows/local/scatter_genome/tests/main.nf.test new file mode 100644 index 000000000..b110bed7d --- /dev/null +++ b/subworkflows/local/scatter_genome/tests/main.nf.test @@ -0,0 +1,69 @@ +nextflow_workflow { + + name "Test Workflow SCATTER_GENOME" + script "subworkflows/local/scatter_genome/main.nf" + workflow "SCATTER_GENOME" + + tag "subworkflows" + tag "scatter_genome" + + tag "gawk" + tag "gatk4_splitintervals" + + config "./nextflow.config" + + test("Should run without failures") { + + when { + params { + pipelines_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + fasta = params.pipelines_testdata_base_path + 'reference/reference.fasta' + fai = params.pipelines_testdata_base_path + 'reference/reference.fasta.fai' + dict = params.pipelines_testdata_base_path + 'reference/reference.dict' + scatter_count = 20 + } + workflow { + """ + input[0] = channel.of(params.dict).map {it -> [[id:'genome'], it]}.collect() + input[1] = channel.of(params.fai).map {it -> [[id:'genome'], it]}.collect() + input[2] = channel.of(params.fasta).map {it -> [[id:'genome'], it]}.collect() + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + + test("Should run without failures, stub") { + + options "-stub" + + when { + params { + pipelines_testdata_base_path= 'https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/' + fasta = params.pipelines_testdata_base_path + 'reference/reference.fasta' + fai = params.pipelines_testdata_base_path + 'reference/reference.fasta.fai' + dict = params.pipelines_testdata_base_path + 'reference/reference.dict' + scatter_count = 20 + } + workflow { + """ + input[0] = channel.of(params.dict).map {it -> [[id:'genome'], it]}.collect() + input[1] = channel.of(params.fai).map {it -> [[id:'genome'], it]}.collect() + input[2] = channel.of(params.fasta).map {it -> [[id:'genome'], it]}.collect() + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + +} diff --git a/subworkflows/local/scatter_genome/tests/main.nf.test.snap b/subworkflows/local/scatter_genome/tests/main.nf.test.snap new file mode 100644 index 000000000..b7b366817 --- /dev/null +++ b/subworkflows/local/scatter_genome/tests/main.nf.test.snap @@ -0,0 +1,136 @@ +{ + "Should run without failures, stub": { + "content": [ + { + "0": [ + [ + { + "id": "genome" + }, + [ + "0000-scattered.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e", + "0001-scattered.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + { + "id": "genome" + }, + "genome.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gatk4_splitintervals_split_intervals": [ + [ + { + "id": "genome" + }, + [ + "0000-scattered.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e", + "0001-scattered.interval_list:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "genome_fai_to_bed_output": [ + [ + { + "id": "genome" + }, + "genome.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-05-25T23:14:53.489816823", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "Should run without failures": { + "content": [ + { + "0": [ + [ + { + "id": "genome" + }, + [ + "0000-scattered.interval_list:md5,91c71c99e1a0777d96ed2ed35977fe68", + "0001-scattered.interval_list:md5,8084a75ace330aaa6b5baedcbc408e73", + "0002-scattered.interval_list:md5,61a7e1852764653287dfcca76b177646", + "0003-scattered.interval_list:md5,9f817fda35d09c8d449d7d91bc57d5a2", + "0004-scattered.interval_list:md5,6f023cded659d4cfc8edb96706c3b319", + "0005-scattered.interval_list:md5,91c3bca4311e2cc9bf55d4ef22281dd4", + "0006-scattered.interval_list:md5,8f2a2f98ac6994859350580a8161cd91", + "0007-scattered.interval_list:md5,5541b78eee72200b98be6af5e4544ed0", + "0008-scattered.interval_list:md5,9f7f7b6f58ec47a73317e3fd64f53bac", + "0009-scattered.interval_list:md5,0bd63474d5fb5284cb8bbb0a202f2e1e", + "0010-scattered.interval_list:md5,c2ff40fe4d17059d38cf40b9b031cb88", + "0011-scattered.interval_list:md5,dd86a813319aa10ca2694505799b8fbe", + "0012-scattered.interval_list:md5,b9424bc405dac67b220e212a749844e0", + "0013-scattered.interval_list:md5,60eee5b05fa8e3d4ff7f026071c4d0e4", + "0014-scattered.interval_list:md5,8c35fb4f332a8bfe56a5d12269def003", + "0015-scattered.interval_list:md5,3fff10ccee5d170b92804ed116f41760", + "0016-scattered.interval_list:md5,c36e542cad7d5b534bde590ce26f356e", + "0017-scattered.interval_list:md5,40c5de97da683709819f0c7404ea6411", + "0018-scattered.interval_list:md5,81820b1a9b029868c58e1abc41c3dc03", + "0019-scattered.interval_list:md5,c4e27e8be0b085a4fa4980d756e21c7f" + ] + ] + ], + "1": [ + [ + { + "id": "genome" + }, + "genome.bed:md5,77b5bd8a06d9f25356c233413bf0318d" + ] + ], + "gatk4_splitintervals_split_intervals": [ + [ + { + "id": "genome" + }, + [ + "0000-scattered.interval_list:md5,91c71c99e1a0777d96ed2ed35977fe68", + "0001-scattered.interval_list:md5,8084a75ace330aaa6b5baedcbc408e73", + "0002-scattered.interval_list:md5,61a7e1852764653287dfcca76b177646", + "0003-scattered.interval_list:md5,9f817fda35d09c8d449d7d91bc57d5a2", + "0004-scattered.interval_list:md5,6f023cded659d4cfc8edb96706c3b319", + "0005-scattered.interval_list:md5,91c3bca4311e2cc9bf55d4ef22281dd4", + "0006-scattered.interval_list:md5,8f2a2f98ac6994859350580a8161cd91", + "0007-scattered.interval_list:md5,5541b78eee72200b98be6af5e4544ed0", + "0008-scattered.interval_list:md5,9f7f7b6f58ec47a73317e3fd64f53bac", + "0009-scattered.interval_list:md5,0bd63474d5fb5284cb8bbb0a202f2e1e", + "0010-scattered.interval_list:md5,c2ff40fe4d17059d38cf40b9b031cb88", + "0011-scattered.interval_list:md5,dd86a813319aa10ca2694505799b8fbe", + "0012-scattered.interval_list:md5,b9424bc405dac67b220e212a749844e0", + "0013-scattered.interval_list:md5,60eee5b05fa8e3d4ff7f026071c4d0e4", + "0014-scattered.interval_list:md5,8c35fb4f332a8bfe56a5d12269def003", + "0015-scattered.interval_list:md5,3fff10ccee5d170b92804ed116f41760", + "0016-scattered.interval_list:md5,c36e542cad7d5b534bde590ce26f356e", + "0017-scattered.interval_list:md5,40c5de97da683709819f0c7404ea6411", + "0018-scattered.interval_list:md5,81820b1a9b029868c58e1abc41c3dc03", + "0019-scattered.interval_list:md5,c4e27e8be0b085a4fa4980d756e21c7f" + ] + ] + ], + "genome_fai_to_bed_output": [ + [ + { + "id": "genome" + }, + "genome.bed:md5,77b5bd8a06d9f25356c233413bf0318d" + ] + ] + } + ], + "timestamp": "2026-05-25T23:14:30.264088588", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/scatter_genome/tests/nextflow.config b/subworkflows/local/scatter_genome/tests/nextflow.config new file mode 100644 index 000000000..5d85dbbfb --- /dev/null +++ b/subworkflows/local/scatter_genome/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: '.*SCATTER_GENOME:GATK4_SPLITINTERVALS' { + ext.args = { "--scatter-count ${params.scatter_count}" } + ext.prefix = { "${meta.id}_intervals" } + } +} diff --git a/subworkflows/local/subsample_mt.nf b/subworkflows/local/subsample_mt.nf deleted file mode 100644 index 180748e54..000000000 --- a/subworkflows/local/subsample_mt.nf +++ /dev/null @@ -1,47 +0,0 @@ -// -// A subworkflow to subsample MT alignments -// - -include { BEDTOOLS_GENOMECOV } from '../../modules/nf-core/bedtools/genomecov/main' -include { CALCULATE_SEED_FRACTION } from '../../modules/local/calculate_seed_fraction' -include { SAMTOOLS_VIEW } from '../../modules/nf-core/samtools/view/main' -include { SAMTOOLS_INDEX } from '../../modules/nf-core/samtools/index/main' - -workflow SUBSAMPLE_MT { - - take: - ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] - val_mt_subsample_rd // channel: [mandatory] [ val(read_dept) ] - val_mt_subsample_seed // channel: [mandatory] [ val(seed) ] - - main: - ch_versions = Channel.empty() - - ch_mt_bam_bai.map {meta, bam, bai -> return [meta, bam, -1]}.set {ch_genomecov_in} - - BEDTOOLS_GENOMECOV (ch_genomecov_in, [], "genomecov", false) - - CALCULATE_SEED_FRACTION ( - BEDTOOLS_GENOMECOV.out.genomecov, - val_mt_subsample_rd, - val_mt_subsample_seed - ) - .csv - .join(ch_mt_bam_bai, failOnMismatch:true) - .map{meta, seedfrac, bam, bai -> - return [meta + [seedfrac: file(seedfrac).text.readLines()[0]], bam, bai] - } - .set { ch_subsample_in } - - SAMTOOLS_VIEW(ch_subsample_in, [[:],[]], []) - - SAMTOOLS_INDEX(SAMTOOLS_VIEW.out.bam) - - ch_versions = ch_versions.mix(BEDTOOLS_GENOMECOV.out.versions.first()) - ch_versions = ch_versions.mix(CALCULATE_SEED_FRACTION.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW.out.versions.first()) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first()) - - emit: - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/subsample_mt_frac/main.nf b/subworkflows/local/subsample_mt_frac/main.nf new file mode 100644 index 000000000..6d07e689b --- /dev/null +++ b/subworkflows/local/subsample_mt_frac/main.nf @@ -0,0 +1,38 @@ +// +// A subworkflow to subsample MT alignments +// + +include { BEDTOOLS_GENOMECOV } from '../../../modules/nf-core/bedtools/genomecov/main' +include { CALCULATE_SEED_FRACTION } from '../../../modules/local/calculate_seed_fraction' +include { SAMTOOLS_VIEW } from '../../../modules/nf-core/samtools/view/main' + +workflow SUBSAMPLE_MT_FRAC { + + take: + ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + val_mt_subsample_rd // channel: [mandatory] [ val(read_dept) ] + val_mt_subsample_seed // channel: [mandatory] [ val(seed) ] + + main: + ch_mt_bam_bai.map {meta, bam, _bai -> return [meta, bam, -1]}.set {ch_genomecov_in} + + BEDTOOLS_GENOMECOV (ch_genomecov_in, [], "genomecov", false) + + CALCULATE_SEED_FRACTION ( + BEDTOOLS_GENOMECOV.out.genomecov, + val_mt_subsample_rd, + val_mt_subsample_seed + ) + .csv + .join(ch_mt_bam_bai, failOnMismatch:true) + .map{meta, seedfrac, bam, bai -> + return [meta + [seedfrac: file(seedfrac).text.readLines()[0]], bam, bai] + } + .set { ch_subsample_in } + + SAMTOOLS_VIEW(ch_subsample_in, [[:],[],[]], [], 'bai') + + emit: + bam = SAMTOOLS_VIEW.out.bam // channel: [ val(meta), path(bam) ] + bai = SAMTOOLS_VIEW.out.bai // channel: [ val(meta), path(bai) ] +} diff --git a/subworkflows/local/subsample_mt_frac/tests/main.nf.test b/subworkflows/local/subsample_mt_frac/tests/main.nf.test new file mode 100644 index 000000000..2c6ebe899 --- /dev/null +++ b/subworkflows/local/subsample_mt_frac/tests/main.nf.test @@ -0,0 +1,68 @@ +nextflow_workflow { + + name "Test Workflow SUBSAMPLE_MT_FRAC" + script "subworkflows/local/subsample_mt_frac/main.nf" + workflow "SUBSAMPLE_MT_FRAC" + tag "subworkflows" + tag "subsample_mt_frac" + + tag "bedtools/genomecov" + tag "calculate_seed_fraction" + tag "samtools/view" + + config "./nextflow.config" + + test("SUBSAMPLE_MT_FRAC") { + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', seedfrac: 0.1, sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = 150 + input[2] = 30 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] }, + workflow.out.bai.collect { meta, baifile -> [ meta, file(baifile).name ] } + ).match() + } + ) + } + } + + test("SUBSAMPLE_MT_FRAC -stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', seedfrac: 0.1, sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + input[1] = 150 + input[2] = 30 + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/subsample_mt_frac/tests/main.nf.test.snap b/subworkflows/local/subsample_mt_frac/tests/main.nf.test.snap new file mode 100644 index 000000000..585a5abf5 --- /dev/null +++ b/subworkflows/local/subsample_mt_frac/tests/main.nf.test.snap @@ -0,0 +1,136 @@ +{ + "SUBSAMPLE_MT_FRAC": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": "31.339226", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "3738567deb98475ea48267fc25568a6a" + ] + ], + [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": "31.339226", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai" + ] + ] + ], + "timestamp": "2026-05-20T00:15:22.219541427", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "SUBSAMPLE_MT_FRAC -stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": null, + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": null, + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bai": [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": null, + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "earlycasualcaiman", + "seedfrac": null, + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-05-20T00:15:41.615447408", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/subsample_mt_frac/tests/nextflow.config b/subworkflows/local/subsample_mt_frac/tests/nextflow.config new file mode 100644 index 000000000..1f4c04be9 --- /dev/null +++ b/subworkflows/local/subsample_mt_frac/tests/nextflow.config @@ -0,0 +1,12 @@ +process { + + withName: '.*SUBSAMPLE_MT_FRAC:BEDTOOLS_GENOMECOV' { + ext.args = { "-dz" } + ext.prefix = { "${meta.id}" } + } + + withName: '.*SUBSAMPLE_MT_FRAC:SAMTOOLS_VIEW' { + ext.args = { "--output-fmt BAM -h -F 4 -s ${meta.seedfrac}" } + ext.prefix = { "${meta.id}_mt_subsample" } + } +} diff --git a/subworkflows/local/subsample_mt_reads/main.nf b/subworkflows/local/subsample_mt_reads/main.nf new file mode 100644 index 000000000..d6fc4f0b4 --- /dev/null +++ b/subworkflows/local/subsample_mt_reads/main.nf @@ -0,0 +1,32 @@ +// +// A subworkflow to subsample MT alignments +// + +include { GAWK } from '../../../modules/nf-core/gawk/main' +include { SAMTOOLS_COLLATE } from '../../../modules/nf-core/samtools/collate/main' +include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_VIEW } from '../../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as SAM_TO_BAM } from '../../../modules/nf-core/samtools/view/main' + +workflow SUBSAMPLE_MT_READS { + + take: + ch_mt_bam_bai // channel: [mandatory] [ val(meta), path(bam), path(bai) ] + + main: + SAMTOOLS_VIEW(ch_mt_bam_bai, [[:],[],[]], [], '') + + SAMTOOLS_COLLATE(SAMTOOLS_VIEW.out.bam, [[:],[],[]]) + + GAWK(SAMTOOLS_COLLATE.out.sam, [], false) + + GAWK.out.output.map {meta, sam -> return [meta, sam, []] }.set {ch_convert_to_bam} + + SAM_TO_BAM(ch_convert_to_bam, [[:],[],[]], [], '') + + SAMTOOLS_SORT(SAM_TO_BAM.out.bam, [[:],[]], 'bai') + + emit: + bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), path(bam) ] + bai = SAMTOOLS_SORT.out.bai // channel: [ val(meta), path(bai) ] +} diff --git a/subworkflows/local/subsample_mt_reads/tests/main.nf.test b/subworkflows/local/subsample_mt_reads/tests/main.nf.test new file mode 100644 index 000000000..f4f747ada --- /dev/null +++ b/subworkflows/local/subsample_mt_reads/tests/main.nf.test @@ -0,0 +1,71 @@ +nextflow_workflow { + + name "Test Workflow SUBSAMPLE_MT_READS" + script "subworkflows/local/subsample_mt_reads/main.nf" + workflow "SUBSAMPLE_MT_READS" + tag "subworkflows" + tag "subsample_mt_reads" + + tag "samtools/view" + tag "samtools/collate" + tag "samtools/sort" + tag "gawk" + + config "./nextflow.config" + + test("SUBSAMPLE_MT_READS") { + + when { + params { + mt_subsample_reads = 18000 + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.bam.collect { meta, bamfile -> [ meta, bam(bamfile).getReadsMD5() ] }, + workflow.out.bai.collect { meta, baifile -> [ meta, file(baifile).name ] } + ).match() + } + ) + } + } + + test("SUBSAMPLE_MT_READS -stub") { + + options "-stub" + + when { + params { + mt_subsample_reads = 18000 + } + workflow { + """ + input[0] = channel.of([ + [id:'earlycasualcaiman', sample:'earlycasualcaiman', single_end:false, num_lanes:1, read_group: "'@RG\\\\tID:earlycasualcaiman\\\\tPL:illumina\\\\tSM:earlycasualcaiman'", lane:1, sex:1, phenotype:1, paternal:0, maternal:0, case_id:'justhusky'], + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam', checkIfExists: true), + file(params.pipelines_testdata_base_path + 'testdata/earlycasualcaiman_sorted_md.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/subsample_mt_reads/tests/main.nf.test.snap b/subworkflows/local/subsample_mt_reads/tests/main.nf.test.snap new file mode 100644 index 000000000..d06a6d7c3 --- /dev/null +++ b/subworkflows/local/subsample_mt_reads/tests/main.nf.test.snap @@ -0,0 +1,130 @@ +{ + "SUBSAMPLE_MT_READS": { + "content": [ + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "39e02db7f5cdce7a716cbd0de5352c63" + ] + ], + [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai" + ] + ] + ], + "timestamp": "2026-05-20T00:16:23.836648543", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "SUBSAMPLE_MT_READS -stub": { + "content": [ + { + "0": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bai": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "earlycasualcaiman", + "sample": "earlycasualcaiman", + "single_end": false, + "num_lanes": 1, + "read_group": "'@RG\\tID:earlycasualcaiman\\tPL:illumina\\tSM:earlycasualcaiman'", + "lane": 1, + "sex": 1, + "phenotype": 1, + "paternal": 0, + "maternal": 0, + "case_id": "justhusky" + }, + "earlycasualcaiman_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "timestamp": "2026-05-20T00:16:46.901941587", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/subsample_mt_reads/tests/nextflow.config b/subworkflows/local/subsample_mt_reads/tests/nextflow.config new file mode 100644 index 000000000..7a3393855 --- /dev/null +++ b/subworkflows/local/subsample_mt_reads/tests/nextflow.config @@ -0,0 +1,27 @@ +process { + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_VIEW' { + ext.args = { "--output-fmt bam -F 0x400" } + ext.prefix = { "${meta.id}_mt_nodups" } + } + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_COLLATE' { + ext.args = { "--output-fmt sam" } + ext.prefix = { "${meta.id}_mt_nodups_collate" } + } + + withName: '.*SUBSAMPLE_MT_READS:GAWK' { + ext.args2 = { "'/^@/ { print; next } count < ${params.mt_subsample_reads} || last == \$1 { print; last = \$1; count++ }'" } + ext.prefix = { "${meta.id}_mt_nodups_collate_awk" } + ext.suffix = "sam" + } + + withName: '.*SUBSAMPLE_MT_READS:SAM_TO_BAM' { + ext.args = { "--output-fmt bam" } + ext.prefix = { "${meta.id}_mt_nodups_collate_awk" } + } + + withName: '.*SUBSAMPLE_MT_READS:SAMTOOLS_SORT' { + ext.prefix = { "${meta.id}_mt_subsample" } + } +} diff --git a/subworkflows/local/utils_nfcore_raredisease_pipeline/main.nf b/subworkflows/local/utils_nfcore_raredisease_pipeline/main.nf index f3e924c8b..83f7de8a9 100644 --- a/subworkflows/local/utils_nfcore_raredisease_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_raredisease_pipeline/main.nf @@ -11,9 +11,9 @@ 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' @@ -28,14 +28,17 @@ workflow PIPELINE_INITIALISATION { take: version // boolean: Display version and exit validate_params // boolean: Boolean whether to validate parameters against the schema at runtime - monochrome_logs // boolean: Do not use coloured log outputs nextflow_cli_args // array: List of positional nextflow CLI args outdir // string: The output directory where the results will be saved input // string: Path to input samplesheet + help // boolean: Display help message and exit + help_full // boolean: Show the full help message + monochrome_logs // boolean: Disable ANSI colour codes in log output + show_hidden // boolean: Show hidden parameters in the help message main: - ch_versions = Channel.empty() + ch_versions = channel.empty() // // Print version and exit if required and dump pipeline parameters to JSON file @@ -50,10 +53,42 @@ 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 +\033[0;34m ___ __ __ __ ___ \033[0;32m/,-._.--~\'\033[0m +\033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m +\033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m + \033[0;32m`._,._,\'\033[0m +\033[0;35m nf-core/raredisease ${workflow.manifest.version}\033[0m +-\033[2m----------------------------------------------------\033[0m- +""" + after_text = """${workflow.manifest.doi ? "\n* The pipeline\n" : ""}${workflow.manifest.doi.tokenize(",").collect { doi -> " https://doi.org/${doi.trim().replace('https://doi.org/','')}"}.join("\n")}${workflow.manifest.doi ? "\n" : ""} +* The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + +* Software dependencies + https://github.com/nf-core/raredisease/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 ( workflow, validate_params, - null + null, + help, + help_full, + show_hidden, + before_text, + after_text, + command ) // @@ -72,10 +107,10 @@ workflow PIPELINE_INITIALISATION { // // Create channel from input file provided through params.input // - Channel - .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + channel + .fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) .tap { ch_original_input } - .map { meta, fastq1, fastq2, spring1, spring2, bam, bai -> meta.id } + .map { meta, _fastq1, _fastq2, _spring1, _spring2, _bam, _bai -> meta.id } .reduce([:]) { counts, sample -> //get counts of each sample in the samplesheet - for groupTuple counts[sample] = (counts[sample] ?: 0) + 1 counts @@ -101,7 +136,7 @@ workflow PIPELINE_INITIALISATION { } } .tap{ ch_input_counts } - .map { meta, files -> files } + .map { _meta, files -> files } .reduce([:]) { counts, files -> //get line number for each row to construct unique sample ids counts[files] = counts.size() + 1 return counts @@ -120,13 +155,13 @@ workflow PIPELINE_INITIALISATION { } .set {ch_samplesheet_by_type} - ch_samples = ch_samplesheet.map { meta, files -> + ch_samples = ch_samplesheet.map { meta, _files -> def new_id = meta.sample def new_meta = meta - meta.subMap('lane', 'read_group') + [id:new_id] return new_meta }.unique() - ch_case_info = ch_samples.toList().map { createCaseChannel(it) } + ch_case_info = ch_samples.toList().map { it -> createCaseChannel(it) } emit: reads = ch_samplesheet_by_type.fastq @@ -150,7 +185,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 multiqc_report // string: Path to MultiQC report main: @@ -174,13 +208,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" } } @@ -189,6 +221,56 @@ workflow PIPELINE_COMPLETION { FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/** + * Creates a channel from a file path if provided, otherwise returns a fallback channel + * @param filePath The path to the file (can be null) + * @param valueFallback If true, returns channel.value([]) when filePath is null; otherwise returns channel.empty() (default: false) + * @return Channel with collected file path or fallback channel + */ +def channelFromPath(filePath, valueFallback = false) { + if (!filePath) { + return valueFallback ? channel.value([]) : channel.empty() + } + return channel.fromPath(filePath).collect() +} + +/** + * Creates a channel from a file path, maps it to [id, file] format, and collects + * @param filePath The path to the file (can be null) + * @param doubleEmpty If true, returns channel.value([[:], []]) when filePath is null; otherwise returns channel.empty() (default: false) + * @param customId The custom ID to be used in meta.id (default: null) + * @return Channel with [[id:name], file] format and collected, or fallback channel + */ +def channelFromPathWithMeta(filePath, doubleEmpty = false, customId = null) { + if (!filePath) { + return doubleEmpty ? channel.value([[:], []]) : channel.empty() + } + return channel.fromPath(filePath).map { file -> + def meta_id = customId ?: file.simpleName + return [[id: meta_id], file] + }.collect() +} + +/** + * Creates a channel from a samplesheet file using samplesheetToList, or returns a fallback channel + * @param samplesheetPath The path to the samplesheet file (can be null) + * @param schemaPath The path to the JSON schema file for validation + * @param collect If true, calls .collect() on the channel (default: true) + * @return Channel from samplesheet list or channel.empty() + */ +def channelFromSamplesheet(samplesheetPath, schemaPath, collect = true) { + if (!samplesheetPath) { + return channel.empty() + } + def ch_out = channel.fromList(samplesheetToList(samplesheetPath, schemaPath)) + return collect ? ch_out.collect() : ch_out +} + +def boolean hasSpringInput() { + return file(params.input).readLines().any { line -> line.contains('.spring') } +} + def generateReadGroupLine(file, meta, params) { return "\'@RG\\tID:" + file.simpleName + "_" + meta.lane + "\\tPL:" + params.platform.toUpperCase() + "\\tSM:" + meta.id + "\'" } @@ -237,6 +319,14 @@ def validateInputParameters() { genomeExistsError() } + +// +// Initialize skip parameters +// +def parseSkipList(paramValue, toolName) { + return paramValue ? paramValue.split(',').contains(toolName) : false +} + // // Validate parameters // @@ -285,7 +375,7 @@ def checkRequiredParameters(params) { } } - all_skips = params.skip_subworkflows+","+params.skip_tools + def all_skips = params.skip_subworkflows+","+params.skip_tools dynamicRequirements.each { condition, paramsList -> if (!all_skips.split(',').contains(condition)) { mandatoryParams += paramsList @@ -415,8 +505,7 @@ def toolCitationText() { sv_calls_text = [ params.analysis_type.equals("wgs") ? "CNVnator (Abyzov et al., 2011)," : "", params.analysis_type.equals("wgs") ? "TIDDIT (Eisfeldt et al., 2017)," : "", - "Manta (Chen et al., 2016),", - params.analysis_type.equals("wgs") ? "eKLIPse (Goudenge et al., 2019)," : "" + "Manta (Chen et al., 2016)," ] } if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('mt_annotation')) && (params.analysis_type.equals("wgs") || params.run_mt_for_wes)) { @@ -424,15 +513,8 @@ def toolCitationText() { "CADD (Rentzsch et al., 2019, 2021),", "VEP (McLaren et al., 2016),", "Vcfanno (Pedersen et al., 2016),", - "Hmtnote (Preste et al., 2019),", "Genmod (Magnusson et al., 2018)," ] - if (!(params.skip_tools && params.skip_tools.split(',').contains('haplogrep3'))) { - mt_annotation_text += [ - "HaploGrep3 (Schönherr et al., 2023)," - ] - - } } if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('me_annotation')) && params.analysis_type.equals("wgs")) { me_annotation_text = [ @@ -448,7 +530,7 @@ def toolCitationText() { } qc_bam_text = [ "Picard (Broad Institute, 2023)", - "Qualimap (Okonechnikov et al., 2016),", + "Sambamba (Tarasov et al., 2015),", "TIDDIT (Eisfeldt et al., 2017),", "UCSC Bigwig and Bigbed (Kent et al., 2010),", (params.verifybamid_svd_bed && params.verifybamid_svd_mu && params.verifybamid_svd_ud) ? "VerifyBamID2 (Zhang et al., 2020)," : "", @@ -456,7 +538,8 @@ def toolCitationText() { ] preprocessing_text = [ "FastQC (Andrews 2010),", - (params.skip_tools && params.skip_tools.split(',').contains('fastp')) ? "" : "Fastp (Chen, 2023)," + (params.skip_tools && params.skip_tools.split(',').contains('fastp')) ? "" : "Fastp (Chen, 2023),", + hasSpringInput() ? "Spring (Chandak et al., 2019)," : "" ] other_citation_text = [ "BCFtools (Danecek et al., 2021),", @@ -543,8 +626,7 @@ def toolBibliographyText() { sv_calls_text = [ params.analysis_type.equals("wgs") ? "
  • Abyzov, A., Urban, A. E., Snyder, M., & Gerstein, M. (2011). CNVnator: An approach to discover, genotype, and characterize typical and atypical CNVs from family and population genome sequencing. Genome Research, 21(6), 974–984. https://doi.org/10.1101/gr.114876.110
  • " : "", params.analysis_type.equals("wgs") ? "
  • Eisfeldt, J., Vezzi, F., Olason, P., Nilsson, D., & Lindstrand, A. (2017). TIDDIT, an efficient and comprehensive structural variant caller for massive parallel sequencing data. F1000Research, 6, 664. https://doi.org/10.12688/f1000research.11168.2
  • " : "", - "
  • Chen, X., Schulz-Trieglaff, O., Shaw, R., Barnes, B., Schlesinger, F., Källberg, M., Cox, A. J., Kruglyak, S., & Saunders, C. T. (2016). Manta: Rapid detection of structural variants and indels for germline and cancer sequencing applications. Bioinformatics, 32(8), 1220–1222. https://doi.org/10.1093/bioinformatics/btv710
  • ", - "
  • Goudenège, D., Bris, C., Hoffmann, V., Desquiret-Dumas, V., Jardel, C., Rucheton, B., Bannwarth, S., Paquis-Flucklinger, V., Lebre, A. S., Colin, E., Amati-Bonneau, P., Bonneau, D., Reynier, P., Lenaers, G., & Procaccio, V. (2019). eKLIPse: A sensitive tool for the detection and quantification of mitochondrial DNA deletions from next-generation sequencing data. Genetics in Medicine, 21(6), 1407–1416. https://doi.org/10.1038/s41436-018-0350-8
  • " + "
  • Chen, X., Schulz-Trieglaff, O., Shaw, R., Barnes, B., Schlesinger, F., Källberg, M., Cox, A. J., Kruglyak, S., & Saunders, C. T. (2016). Manta: Rapid detection of structural variants and indels for germline and cancer sequencing applications. Bioinformatics, 32(8), 1220–1222. https://doi.org/10.1093/bioinformatics/btv710
  • " ] } @@ -554,14 +636,8 @@ def toolBibliographyText() { "
  • Rentzsch, P., Witten, D., Cooper, G. M., Shendure, J., & Kircher, M. (2019). CADD: Predicting the deleteriousness of variants throughout the human genome. Nucleic Acids Research, 47(D1), D886–D894. https://doi.org/10.1093/nar/gky1016
  • ", "
  • Pedersen, B. S., Layer, R. M., & Quinlan, A. R. (2016). Vcfanno: Fast, flexible annotation of genetic variants. Genome Biology, 17(1), 118. https://doi.org/10.1186/s13059-016-0973-5
  • ", "
  • McLaren, W., Gil, L., Hunt, S. E., Riat, H. S., Ritchie, G. R. S., Thormann, A., Flicek, P., & Cunningham, F. (2016). The Ensembl Variant Effect Predictor. Genome Biology, 17(1), 122. https://doi.org/10.1186/s13059-016-0974-4
  • ", - "
  • Preste, R., Clima, R., & Attimonelli, M. (2019). Human mitochondrial variant annotation with HmtNote [Preprint]. Bioinformatics. https://doi.org/10.1101/600619
  • ", "
  • Magnusson, M., Hughes, T., Glabilloy, & Bitdeli Chef. (2018). genmod: Version 3.7.3 (3.7.3) [Computer software]. Zenodo. https://doi.org/10.5281/ZENODO.3841142
  • " ] - if (!(params.skip_tools && params.skip_tools.split(',').contains('haplogrep3'))) { - mt_annotation_text += [ - "
  • Schönherr, S., Weissensteiner, H., Kronenberg, F., & Forer, L. (2023). Haplogrep 3 an interactive haplogroup classification and analysis platform. Nucleic Acids Research, 51(W1), W263-W268. https://doi.org/10.1093/nar/gkad284
  • " - ] - } } if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('me_annotation')) && params.analysis_type.equals("wgs")) { me_annotation_text = [ @@ -577,7 +653,7 @@ def toolBibliographyText() { } qc_bam_text = [ "
  • Broad Institute. (2023). Picard Tools. In Broad Institute, GitHub repository. http://broadinstitute.github.io/picard/
  • ", - "
  • Okonechnikov, K., Conesa, A., & García-Alcalde, F. (2016). Qualimap 2: Advanced multi-sample quality control for high-throughput sequencing data. Bioinformatics, 32(2), 292–294. https://doi.org/10.1093/bioinformatics/btv566
  • ", + "
  • Tarasov, A., Vilella, A. J., Cuppen, E., Nijman, I. J., & Prins, P. (2015). Sambamba: Fast processing of NGS alignment formats. Bioinformatics, 31(12), 2032–2034. https://doi.org/10.1093/bioinformatics/btv098
  • ", "
  • Eisfeldt, J., Vezzi, F., Olason, P., Nilsson, D., & Lindstrand, A. (2017). TIDDIT, an efficient and comprehensive structural variant caller for massive parallel sequencing data. F1000Research, 6, 664. https://doi.org/10.12688/f1000research.11168.2
  • ", "
  • Kent, W. J., Zweig, A. S., Barber, G., Hinrichs, A. S., & Karolchik, D. (2010). BigWig and BigBed: Enabling browsing of large distributed datasets. Bioinformatics, 26(17), 2204–2207. https://doi.org/10.1093/bioinformatics/btq351
  • ", (params.verifybamid_svd_bed && params.verifybamid_svd_mu && params.verifybamid_svd_ud) ? "
  • Zhang, F., Flickinger, M., Taliun, S. A. G., Consortium, I. P. G., Abecasis, G. R., Scott, L. J., McCaroll, S. A., Pato, C. N., Boehnke, M., & Kang, H. M. (2020). Ancestry-agnostic estimation of DNA sample contamination from sequence reads. Genome Research, 30(2), 185–194. https://doi.org/10.1101/gr.246934.118
  • " : "", @@ -585,7 +661,8 @@ def toolBibliographyText() { ] preprocessing_text = [ "
  • Andrews S, (2010) FastQC, URL: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/
  • ", - (params.skip_tools && params.skip_tools.split(',').contains('fastp')) ? "" : "
  • Chen, S. (2023). Ultrafast one-pass FASTQ data preprocessing, quality control, and deduplication using fastp. iMeta, 2(2), e107. https://doi.org/10.1002/imt2.107
  • " + (params.skip_tools && params.skip_tools.split(',').contains('fastp')) ? "" : "
  • Chen, S. (2023). Ultrafast one-pass FASTQ data preprocessing, quality control, and deduplication using fastp. iMeta, 2(2), e107. https://doi.org/10.1002/imt2.107
  • ", + hasSpringInput() ? "
  • Chandak, S., Tatwawadi, K., Ochoa, I., Hernaez, M., & Weissman, T. (2019). SPRING: A next-generation compressor for FASTQ data. Bioinformatics, 35(15), 2674–2676. https://doi.org/10.1093/bioinformatics/bty1015
  • " : "" ] other_citation_text = [ diff --git a/subworkflows/local/variant_evaluation.nf b/subworkflows/local/variant_evaluation.nf deleted file mode 100644 index c9bce679a..000000000 --- a/subworkflows/local/variant_evaluation.nf +++ /dev/null @@ -1,52 +0,0 @@ -// -// A subworkflow to evaluate variants using truth vcfs. -// - -include { RTGTOOLS_VCFEVAL } from '../../modules/nf-core/rtgtools/vcfeval/main' -include { BCFTOOLS_REHEADER } from '../../modules/nf-core/bcftools/reheader/main' -include { TABIX_TABIX as TABIX_TRUTHVCF } from '../../modules/nf-core/tabix/tabix/main' - -workflow VARIANT_EVALUATION { - - take: - ch_snv_vcf_tbi // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] - ch_genome_fai // channel: [mandatory] [ val(meta), path(fai) ] - ch_rtg_truthvcfs // channel: [mandatory] [ val(meta), path(dbs) ] - ch_sdf // channel: [mandatory] [ val(meta), path(sdf) ] - - main: - ch_versions = Channel.empty() - - ch_rtg_truthvcfs - .splitCsv ( header:true ) - .map { row -> - def evregions = row.evaluationregions[0].isEmpty() ? [] : row.evaluationregions[0] - def bedregions = row.bedregions[0].isEmpty() ? [] : row.bedregions[0] - return [[samplename:row.samplename[0], bedregions:bedregions, evaluationregions:evregions], row.vcf[0], [], []] - } - .set { ch_rtgvcfs_dbs } - - BCFTOOLS_REHEADER (ch_rtgvcfs_dbs, [[:],[]]) - - TABIX_TRUTHVCF (BCFTOOLS_REHEADER.out.vcf) - - BCFTOOLS_REHEADER.out.vcf - .join(TABIX_TRUTHVCF.out.tbi) - .set { ch_truthvcf_tbi } - - ch_snv_vcf_tbi - .combine(ch_truthvcf_tbi) - .map { meta, query, qidx, meta2, truth, tidx -> - return [meta + [samplename: meta2.samplename] , query, qidx, truth, tidx, meta2.evaluationregions, meta2.bedregions] - } - .set { ch_vcfeval_in } - - RTGTOOLS_VCFEVAL ( ch_vcfeval_in, ch_sdf ) - - ch_versions = ch_versions.mix(BCFTOOLS_REHEADER.out.versions) - ch_versions = ch_versions.mix(TABIX_TRUTHVCF.out.versions) - ch_versions = ch_versions.mix(RTGTOOLS_VCFEVAL.out.versions) - - emit: - versions = ch_versions // channel: [ path(versions.yml) ] -} diff --git a/subworkflows/local/variant_evaluation/main.nf b/subworkflows/local/variant_evaluation/main.nf new file mode 100644 index 000000000..052c98b05 --- /dev/null +++ b/subworkflows/local/variant_evaluation/main.nf @@ -0,0 +1,57 @@ +// +// A subworkflow to evaluate variants using truth vcfs. +// + +include { BCFTOOLS_REHEADER } from '../../../modules/nf-core/bcftools/reheader/main' +include { RTGTOOLS_VCFEVAL } from '../../../modules/nf-core/rtgtools/vcfeval/main' +include { TABIX_TABIX as TABIX_TRUTHVCF } from '../../../modules/nf-core/tabix/tabix/main' + +workflow VARIANT_EVALUATION { + + take: + ch_rtg_truthvcfs // channel: [mandatory] [ val(meta), path(dbs) ] + ch_sdf // channel: [mandatory] [ val(meta), path(sdf) ] + ch_snv_vcf_tbi // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] + + main: + ch_rtg_truthvcfs + .splitCsv ( header:true ) + .map { row -> + def evregions = row.evaluationregions[0].isEmpty() ? [] : row.evaluationregions[0] + def bedregions = row.bedregions[0].isEmpty() ? [] : row.bedregions[0] + return [[samplename:row.samplename[0], bedregions:bedregions, evaluationregions:evregions], row.vcf[0], [], []] + } + .set { ch_rtgvcfs_dbs } + + BCFTOOLS_REHEADER (ch_rtgvcfs_dbs, [[:],[]]) + + TABIX_TRUTHVCF (BCFTOOLS_REHEADER.out.vcf) + + BCFTOOLS_REHEADER.out.vcf + .join(TABIX_TRUTHVCF.out.index) + .set { ch_truthvcf_tbi } + + ch_snv_vcf_tbi + .combine(ch_truthvcf_tbi) + .map { meta, query, qidx, meta2, truth, tidx -> + return [meta + [samplename: meta2.samplename] , query, qidx, truth, tidx, meta2.evaluationregions, meta2.bedregions] + } + .set { ch_vcfeval_in } + + RTGTOOLS_VCFEVAL ( ch_vcfeval_in, ch_sdf ) + + emit: + baseline_tbi = RTGTOOLS_VCFEVAL.out.baseline_tbi // channel: [ val(meta), path(tbi) ] + baseline_vcf = RTGTOOLS_VCFEVAL.out.baseline_vcf // channel: [ val(meta), path(vcf) ] + false_negatives_tbi = RTGTOOLS_VCFEVAL.out.fn_tbi // channel: [ val(meta), path(tbi) ] + false_negatives_vcf = RTGTOOLS_VCFEVAL.out.fn_vcf // channel: [ val(meta), path(vcf) ] + false_positives_tbi = RTGTOOLS_VCFEVAL.out.fp_tbi // channel: [ val(meta), path(tbi) ] + false_positives_vcf = RTGTOOLS_VCFEVAL.out.fp_vcf // channel: [ val(meta), path(vcf) ] + non_snp_roc = RTGTOOLS_VCFEVAL.out.non_snp_roc // channel: [ val(meta), path(tsv) ] + phasing = RTGTOOLS_VCFEVAL.out.phasing // channel: [ val(meta), path(txt) ] + snp_roc = RTGTOOLS_VCFEVAL.out.snp_roc // channel: [ val(meta), path(tsv) ] + summary = RTGTOOLS_VCFEVAL.out.summary // channel: [ val(meta), path(txt) ] + true_positives_tbi = RTGTOOLS_VCFEVAL.out.tp_tbi // channel: [ val(meta), path(tbi) ] + true_positives_vcf = RTGTOOLS_VCFEVAL.out.tp_vcf // channel: [ val(meta), path(vcf) ] + weighted_roc = RTGTOOLS_VCFEVAL.out.weighted_roc // channel: [ val(meta), path(tsv) ] +} diff --git a/subworkflows/local/variant_evaluation/tests/main.nf.test b/subworkflows/local/variant_evaluation/tests/main.nf.test new file mode 100644 index 000000000..76ab3e7d3 --- /dev/null +++ b/subworkflows/local/variant_evaluation/tests/main.nf.test @@ -0,0 +1,37 @@ +nextflow_workflow { + + name "Test Workflow VARIANT_EVALUATION" + script "subworkflows/local/variant_evaluation/main.nf" + workflow "VARIANT_EVALUATION" + + tag "subworkflows" + tag "variant_evaluation" + + tag "rtgtools/vcfeval" + tag "bcftools/reheader" + tag "tabix/tabix" + + + test("VARIANT_EVALUATION - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = channel.of(file("${projectDir}/subworkflows/local/variant_evaluation/tests/rtg_truthvcfs.csv", checkIfExists: true)).collect() + input[1] = channel.value([[id:'genome'], file("${projectDir}/subworkflows/local/variant_evaluation/tests")]) + input[2] = channel.of([ + [id:'earlycasualcaiman', case_id:'justhusky'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test2_haplotc.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gatk/haplotypecaller_calls/test2_haplotc.vcf.gz.tbi', checkIfExists: true) + ]) + """ + } + } + + then { + assert workflow.success + } + } +} diff --git a/subworkflows/local/variant_evaluation/tests/rtg_truthvcfs.csv b/subworkflows/local/variant_evaluation/tests/rtg_truthvcfs.csv new file mode 100644 index 000000000..3bfa9483e --- /dev/null +++ b/subworkflows/local/variant_evaluation/tests/rtg_truthvcfs.csv @@ -0,0 +1,2 @@ +samplename,vcf,bedregions,evaluationregions +earlycasualcaiman,https://raw.githubusercontent.com/nf-core/test-datasets/raredisease/reference/vcfanno_gnomad_mt.vcf.gz,, diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/main.nf b/subworkflows/local/vcf_filter_bcftools_filtervep/main.nf new file mode 100644 index 000000000..b355fb026 --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/main.nf @@ -0,0 +1,49 @@ +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view' +include { FILTERVEP } from '../../../modules/local/filtervep' +include { TABIX_BGZIPTABIX } from '../../../modules/nf-core/tabix/bgziptabix' + +// Please note this subworkflow requires the options for bcftools_view that are included in the nextflow.config +workflow VCF_FILTER_BCFTOOLS_FILTERVEP { + take: + ch_vcf // channel: [ val(meta), path(vcf) ] + ch_filter_vep_feature_file // channel: [ val(meta), path(txt) ] + filter_with_bcftools // bool: should bcftools view be run + filter_with_filter_vep // bool: should filtervep be run + + main: + ch_tbi = channel.empty() + + // Since bcftools is likely much faster than filtervep, + // we run it first to reduce the number of variants that filtervep has to process. + if (filter_with_bcftools) { + + BCFTOOLS_VIEW( + ch_vcf.map { meta, vcf -> [meta, vcf, []] }, + [], + [], + [], + ) + + ch_vcf = BCFTOOLS_VIEW.out.vcf + ch_tbi = BCFTOOLS_VIEW.out.tbi + } + + if (filter_with_filter_vep) { + + FILTERVEP( + ch_vcf, + ch_filter_vep_feature_file.map { _meta, file -> file }, + ) + + TABIX_BGZIPTABIX( + FILTERVEP.out.output + ) + + ch_vcf = TABIX_BGZIPTABIX.out.gz_index.map { meta, vcf, _tbi -> [meta, vcf] } + ch_tbi = TABIX_BGZIPTABIX.out.gz_index.map { meta, _vcf, tbi -> [meta, tbi] } + } + + emit: + vcf = ch_vcf // channel: [ val(meta), path(vcf) ] + tbi = ch_tbi // channel: [ val(meta), path(tbi) ] +} diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/meta.yml b/subworkflows/local/vcf_filter_bcftools_filtervep/meta.yml new file mode 100644 index 000000000..b9d3d7c40 --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/meta.yml @@ -0,0 +1,56 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "vcf_filter_bcftools_ensemblvep" +description: Filter VCF file with bcftools and filter_vep +keywords: + - filter + - vcf + - bcftools + - filter_vep +components: + - bcftools/view + - ensemblvep/filtervep + - tabix/bgziptabix +input: + - ch_vcf: + type: file + description: | + The input channel containing the VCF files + Structure: [ val(meta), path(vcf) ] + pattern: "*.{vcf/vcf.gz}" + - ch_filter_vep_file: + type: file + description: | + File to pass to filter_vep, containing e.g. HGNC IDs to filter on + Structure: [ val(meta), path(txt) ] + - filter_with_bcftools: + type: boolean + description: | + Whether to filter the VCF file with bcftools before passing it to filter_vep + - filter_with_filter_vep: + type: boolean + description: | + Whether to filter the VCF file with filter_vep +output: + - vcf: + type: file + description: | + Channel containing VCF files + Structure: [ val(meta), path(bam) ] + pattern: "*.vcf.gz" + - bai: + type: file + description: | + Channel containing indexed VCF (TBI) files + Structure: [ val(meta), path(bai) ] + pattern: "*.tbi" + - versions: + type: file + description: | + File containing software versions + Structure: [ path(versions.yml) ] + pattern: "versions.yml" +authors: + - "@fellen31" +maintainers: + - "@fellen31" + - "@ramprasadn" diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/nextflow.config b/subworkflows/local/vcf_filter_bcftools_filtervep/nextflow.config new file mode 100644 index 000000000..3c9c895a2 --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/nextflow.config @@ -0,0 +1,9 @@ +// IMPORTANT: This config file should be included to ensure that the subworkflow works properly. +process { + withName: '.*VCF_FILTER_BCFTOOLS_FILTERVEP:BCFTOOLS_VIEW' { + ext.args = { [ + '--output-type z', + '--write-index=tbi', + ].join(" ") } + } +} diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test new file mode 100644 index 000000000..622d385d8 --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test @@ -0,0 +1,136 @@ +nextflow_workflow { + + name "Test Subworkflow VCF_FILTER_BCFTOOLS_FILTERVEP" + script "../main.nf" + workflow "VCF_FILTER_BCFTOOLS_FILTERVEP" + config "./nextflow.config" + + tag "subworkflows" + tag "subworkflows_local" + tag "subworkflows/vcf_filter_bcftools_filtervep" + tag "bcftools/view" + tag "filtervep" + tag "tabix/bgziptabix" + + test("vcf, hgnc_ids - filter on expression") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz') + ]) + input[1] = Channel.of('3084') + .collectFile(name: 'hgnc_ids.txt') + .map { file -> [ [ id: 'hgnc_ids' ], file ] } + input[2] = true + input[3] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.versions.collect { it instanceof String ? path(it).yaml : it }, + file(workflow.out.tbi[0][1]).name, + path(workflow.out.vcf[0][1]).vcf.variantsMD5, + path(workflow.out.vcf[0][1]).vcf.summary, + ).match() } + ) + } + } + + test("vcf, hgnc_ids - filter on hgnc ids") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz') + ]) + input[1] = Channel.of('3084') + .collectFile(name: 'hgnc_ids.txt') + .map { file -> [ [ id: 'hgnc_ids' ], file ] } + input[2] = false + input[3] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.versions.collect { it instanceof String ? path(it).yaml : it }, + file(workflow.out.tbi[0][1]).name, + path(workflow.out.vcf[0][1]).vcf.variantsMD5, + path(workflow.out.vcf[0][1]).vcf.summary, + ).match() } + ) + } + } + + test("vcf, hgnc_ids - filter on hgnc ids and expression") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz') + ]) + input[1] = Channel.of('3084') + .collectFile(name: 'hgnc_ids.txt') + .map { file -> [ [ id: 'hgnc_ids' ], file ] } + input[2] = true + input[3] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.versions.collect { it instanceof String ? path(it).yaml : it }, + file(workflow.out.tbi[0][1]).name, + path(workflow.out.vcf[0][1]).vcf.variantsMD5, + path(workflow.out.vcf[0][1]).vcf.summary, + ).match() } + ) + } + } + + test("vcf, hgnc_ids - filter on hgnc ids and expression - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/genmod.vcf.gz') + ]) + input[1] = Channel.of('3084') + .collectFile(name: 'hgnc_ids.txt') + .map { file -> [ [ id: 'hgnc_ids' ], file ] } + input[2] = true + input[3] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + +} diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test.snap b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test.snap new file mode 100644 index 000000000..9954d80cf --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/main.nf.test.snap @@ -0,0 +1,90 @@ +{ + "vcf, hgnc_ids - filter on hgnc ids": { + "content": [ + [ + + ], + "test.vcf.gz.tbi", + "18e010447bd23a05a202d44daf66bcd2", + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=1, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-01-27T19:43:16.754963", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } + }, + "vcf, hgnc_ids - filter on hgnc ids and expression": { + "content": [ + [ + + ], + "test.vcf.gz.tbi", + "18e010447bd23a05a202d44daf66bcd2", + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=1, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-01-27T19:43:25.968654", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } + }, + "vcf, hgnc_ids - filter on expression": { + "content": [ + [ + + ], + "test_filtered.vcf.gz.tbi", + "9236236d782191442193a20355604927", + "VcfFile [chromosomes=[1], sampleCount=3, variantCount=37, phased=false, phasedAutodetect=false]" + ], + "timestamp": "2026-01-20T12:44:40.698598144", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "vcf, hgnc_ids - filter on hgnc ids and expression - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + } + ], + "timestamp": "2026-01-27T19:43:35.16804", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/vcf_filter_bcftools_filtervep/tests/nextflow.config b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/nextflow.config new file mode 100644 index 000000000..670e5d97e --- /dev/null +++ b/subworkflows/local/vcf_filter_bcftools_filtervep/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: 'FILTERVEP' { + ext.args = { "--filter \"HGNC_ID in ${feature_file}\"" } + } + + withName: 'BCFTOOLS_VIEW' { + ext.prefix = { "${meta.id}_filtered" } + ext.args = '-e "swegenAF>0.1" --no-version --output-type z --write-index=tbi' + } +} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml deleted file mode 100644 index f84761125..000000000 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nextflow_pipeline: - - subworkflows/nf-core/utils_nextflow_pipeline/** diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index bfd258760..afca54390 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 } /* @@ -98,7 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) } // @@ -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 000000000..8940d32d1 --- /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 000000000..859d1030f --- /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_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml deleted file mode 100644 index ac8523c9a..000000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nfcore_pipeline: - - subworkflows/nf-core/utils_nfcore_pipeline/** diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf index 4994303ea..1df8b76fb 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -4,6 +4,7 @@ include { paramsSummaryLog } from 'plugin/nf-schema' include { validateParameters } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' workflow UTILS_NFSCHEMA_PLUGIN { @@ -15,32 +16,58 @@ workflow UTILS_NFSCHEMA_PLUGIN { // when this input is empty it will automatically use the configured schema or // "${projectDir}/nextflow_schema.json" as default. This input should not be empty // for meta pipelines + help // boolean: show help message + help_full // boolean: show full help message + show_hidden // boolean: show hidden parameters in help message + before_text // string: text to show before the help message and parameters summary + after_text // string: text to show after the help message and parameters summary + command // string: an example command of the pipeline main: + if(help || help_full) { + help_options = [ + beforeText: before_text, + afterText: after_text, + command: command, + showHidden: show_hidden, + fullHelp: help_full, + ] + if(parameters_schema) { + help_options << [parametersSchema: parameters_schema] + } + log.info paramsHelp( + help_options, + (params.help instanceof String && params.help != "true") ? params.help : "", + ) + exit 0 + } + // // Print parameter summary to stdout. This will display the parameters // that differ from the default given in the JSON schema // + + summary_options = [:] if(parameters_schema) { - log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema) - } else { - log.info paramsSummaryLog(input_workflow) + summary_options << [parametersSchema: parameters_schema] } + log.info before_text + log.info paramsSummaryLog(summary_options, input_workflow) + log.info after_text // // Validate the parameters using nextflow_schema.json or the schema // given via the validation.parametersSchema configuration option // if(validate_params) { + validateOptions = [:] if(parameters_schema) { - validateParameters(parameters_schema:parameters_schema) - } else { - validateParameters() + validateOptions << [parametersSchema: parameters_schema] } + validateParameters(validateOptions) } emit: dummy_emit = true } - diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test index 8fb301648..c977917aa 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -25,6 +25,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -51,6 +57,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -77,6 +89,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -103,6 +121,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -114,4 +138,36 @@ nextflow_workflow { ) } } + + test("Should create a help message") { + + when { + + params { + test_data = '' + outdir = null + } + + workflow { + """ + validate_params = true + input[0] = workflow + input[1] = validate_params + input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = true + input[4] = false + input[5] = false + input[6] = "Before" + input[7] = "After" + input[8] = "nextflow run test/test" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index 0907ac58f..f6537cc33 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -1,8 +1,8 @@ plugins { - id "nf-schema@2.1.0" + id "nf-schema@2.6.1" } validation { parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" monochromeLogs = true -} \ No newline at end of file +} diff --git a/tests/.nftignore b/tests/.nftignore index c10bc1f11..e128a1284 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -1,9 +1,11 @@ .DS_Store multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt +multiqc/multiqc_data/multiqc.parquet multiqc/multiqc_data/multiqc.log multiqc/multiqc_data/multiqc_data.json multiqc/multiqc_data/multiqc_sources.txt multiqc/multiqc_data/multiqc_software_versions.txt +multiqc/multiqc_data/llms-full.txt multiqc/multiqc_plots/{svg,pdf,png}/*.{svg,pdf,png} multiqc/multiqc_report.html fastqc/*_fastqc.{html,zip} diff --git a/tests/default.nf.test b/tests/default.nf.test index 91432b200..0de01a314 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -10,24 +10,25 @@ nextflow_pipeline { when { params { - outdir = "$outputDir" + outdir = "$outputDir" + skip_tools = "germlinecnvcaller,gens" } } 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 in ${params.outdir}/ with stable content - def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // stable_path: All files + folders in ${params.outdir}/ with a stable path (including file 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, ignoreFile: 'tests/.nftignore') + assert workflow.success 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 test pipelines on multiple Nextflow versions removeNextflowVersion("$outputDir/pipeline_info/nf_core_raredisease_software_mqc_versions.yml"), // All stable path name, with a relative path - stable_name + stable_path, + // All files with stable contents + stable_content ).match() } ) } diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index a849006bc..998a99106 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,51 +1,58 @@ { "-profile test": { "content": [ - 298, { - "ADD_MOST_SEVERE_CSQ": { - "add_most_severe_consequence": "v1.1", - "python": "3.8.3" - }, - "ADD_MOST_SEVERE_PLI": { - "add_most_severe_pli": "v1.1", - "python": "3.8.3" - }, "ADD_VARCALLER_TO_BED": { - "tabix": 1.12 + "bgzip": 1.21, + "tabix": 1.21 }, "BCFTOOLS_ANNOTATE": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_CONCAT": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_CONCAT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_MERGE_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_REHEADER_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_REHEADER_ME": { + "bcftools": 1.22 }, "BCFTOOLS_ROH": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_SORT": { + "bcftools": 1.22 + }, + "BCFTOOLS_SORT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_CNVNATOR": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_VIEW_FILTER": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW_MANTA": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_RHOCALL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_TIDDIT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_UNCOMPRESS": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BEDTOOLS_PAD_TARGET_BED": { "bedtools": "2.31.1" @@ -61,17 +68,20 @@ }, "BWAMEM2_MEM": { "bwamem2": "2.2.1", - "samtools": "1.19.2" + "samtools": "1.22.1" }, "BWAMEM2_MEM_MT": { "bwamem2": "2.2.1", - "samtools": "1.19.2" + "samtools": "1.22.1" }, "BWA_INDEX_GENOME": { - "bwa": "0.7.18-r1243-dirty" + "bwa": "0.7.19-r1273" }, "CAT_CAT_BAIT": { - "pigz": "2.3.4" + "pigz": 2.8 + }, + "CAT_FASTQ": { + "cat": 9.5 }, "CHROMOGRAPH_AUTOZYG": { "chromograph": "1.3.1" @@ -86,159 +96,226 @@ "chromograph": "1.3.1" }, "CNVNATOR_CALL": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_CONVERT2VCF": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_HIST": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_PARTITION": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_RD": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_STAT": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" + }, + "CREATE_HGNCIDS_FILE": { + "create_hgncids_file": 1.0, + "python": "3.14.3" }, "CREATE_PEDIGREE_FILE": { - "create_pedigree_file": "v1.0", - "python": "3.8.3" + "coreutils": 9.5 + }, + "CUSTOM_ADDMOSTSEVERECONSEQUENCE": { + "addmostsevereconsequence": "1.2.0", + "bgzip": 1.21 + }, + "CUSTOM_ADDMOSTSEVEREPLI": { + "addmostseverepli": "1.2.0", + "bgzip": 1.21 }, "DEEPVARIANT": { - "deepvariant": "1.8.0" + "deepvariant": "1.9.0" }, - "ENSEMBLVEP_FILTERVEP": { - "ensemblvep": 110.0 + "ENSEMBLVEP_ME": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 + }, + "ENSEMBLVEP_MT": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "ENSEMBLVEP_SNV": { - "ensemblvep": 110.0 + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 + }, + "ENSEMBLVEP_SV": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "EXPANSIONHUNTER": { - "expansionhunter": "5.0.0", - "bgzip": 1.18 + "bgzip": "1.22.1", + "expansionhunter": "5.0.0" + }, + "FASTP": { + "fastp": "1.0.1" }, "FASTQC": { "fastqc": "0.12.1" }, + "FILTERVEP": { + "filtervep": "1.0.0" + }, "GATK4_FILTERMUTECTCALLS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEBAMALIGNMENT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEVCFS_LIFT_UNLIFT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MUTECT2_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_PRINTREADS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_REVERTSAM_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SAMTOFASTQ_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SELECTVARIANTS": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GATK4_SPLITINTERVALS": { + "gatk4": "4.6.2.0" }, "GATK4_VARIANTFILTRATION_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_BILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_ILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SHIFTFASTA": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GAWK": { + "gawk": "5.3.1" }, "GENMOD_ANNOTATE": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_COMPOUND": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_MODELS": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_SCORE": { - "genmod": 3.9 + "genmod": "3.10.2" + }, + "GENOME_FAI_TO_BED": { + "gawk": "5.3.1" }, "GET_CHROM_SIZES": { - "coreutils": 8.31 + "coreutils": 9.5 }, "GLNEXUS": { - "glnexus": "1.4.1-0-g68e25e5" + "glnexus": "1.4.1" }, - "HAPLOCHECK_MT": { - "haplocheck": "1.3.3" + "HISAT2_INDEX_GENOME": { + "hisat2": "2.2.1" }, "INDEX_CNVNATOR": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "INDEX_TIDDIT": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 + }, + "LAST_INDEX_MT": { + "last": 1611 }, "MANTA": { "manta": "1.6.0" }, "MARKDUPLICATES": { - "picard": "3.3.0" + "picard": "3.4.0" + }, + "ME_SPLIT_ALIGNMENT": { + "samtools": "1.22.1" + }, + "MITOSALT": { + "mitosalt": "1.1.1" }, "MOSDEPTH": { - "mosdepth": "0.3.8" + "mosdepth": "0.3.11" }, "MT_DELETION": { - "samtools": "1.19.2" + "mitodel": 1.0, + "samtools": 1.23 + }, + "NGSBITS_SAMPLEGENDER": { + "ngsbits": 202512 + }, + "PEDDY": { + "peddy": "0.4.8" }, "PICARD_ADDORREPLACEREADGROUPS_MT": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTHSMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTMULTIPLEMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_WG": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_Y": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_LIFTOVERVCF": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_MARKDUPLICATES_MT": { - "picard": "3.3.0" + "picard": "3.4.0" + }, + "PICARD_SORTVCF": { + "picard": "3.4.0" }, "REMOVE_DUPLICATES_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "REMOVE_DUPLICATES_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "RENAMESAMPLE_EXP": { - "picard": "3.3.0" + "picard": "3.4.0" }, "RENAME_BAI": { - "coreutils": 8.31 + "coreutils": 9.5 }, "RENAME_BAM": { - "coreutils": 8.31 + "coreutils": 9.5 + }, + "RETROSEQ_CALL": { + "retroseq": 1.5 + }, + "RETROSEQ_DISCOVER": { + "retroseq": 1.5 }, "RHOCALL_ANNOTATE": { "rhocall": "0.5.1" @@ -246,121 +323,151 @@ "RHOCALL_VIZ": { "rhocall": "0.5.1" }, + "SALTSHAKER_CALL": { + "saltshaker": "1.1.1" + }, + "SALTSHAKER_CLASSIFY": { + "saltshaker": "1.1.1" + }, + "SALTSHAKER_PLOT": { + "saltshaker": "1.1.1" + }, + "SAMTOOLS_COLLATE": { + "samtools": "1.22.1" + }, "SAMTOOLS_EXTRACT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_FAIDX_MT": { - "samtools": 1.21 - }, - "SAMTOOLS_INDEX": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_ALIGN": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_MARKDUP": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_STATS": { - "samtools": 1.21 + "samtools": "1.22.1" + }, + "SAMTOOLS_VIEW": { + "samtools": "1.22.1" + }, + "SAM_TO_BAM": { + "samtools": "1.22.1" + }, + "SEQTK_SAMPLE": { + "seqtk": "1.4-r122" }, "SMNCOPYNUMBERCALLER": { - "SMNCopyNumberCaller": "1.1.2" + "smncopynumbercaller": "1.1.2" + }, + "SPLIT_AND_FILTER_SV_VCF": { + "bcftools": 1.22 + }, + "SPLIT_CHR": { + "bioawk": 1.0 }, "SPLIT_MULTIALLELICS_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_MT": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "SPLIT_MULTIALLELICS_POSTMERGE_MT": { + "bcftools": 1.22 }, "SPRING_DECOMPRESS_TO_FQ_PAIR": { "spring": "1.1.1" }, "STRANGER": { - "stranger": "0.9.4", - "tabix": 1.21 + "stranger": "0.10.0", + "tabix": 1.23 }, "SVDB_MERGE": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_CNVNATOR": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" + }, + "SVDB_MERGE_ME": { + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_REPEATS": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_TIDDIT": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, - "TABIX_ANNOTATE": { - "tabix": 1.2 + "SVDB_QUERY_DB": { + "svdb": "2.8.4" }, - "TABIX_BCFTOOLS_CONCAT": { - "tabix": 1.2 - }, - "TABIX_BGZIP": { - "tabix": 1.2 + "TABIX_ANNOTATE": { + "tabix": 1.21 }, "TABIX_BGZIPINDEX_PADDED_BED": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_BGZIPTABIX": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_DBSNP": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_EXP_RENAME": { - "tabix": 1.2 - }, - "TABIX_GL": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_GNOMAD_AF": { - "tabix": 1.2 + "tabix": 1.21 }, - "TABIX_PBT": { - "tabix": 1.2 + "TABIX_ME": { + "tabix": 1.21 + }, + "TABIX_ME_SPLIT": { + "tabix": 1.21 }, "TABIX_TABIX": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MERGE": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT2": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT": { - "tabix": 1.2 - }, - "TABIX_VEP": { - "tabix": 1.2 + "tabix": 1.21 }, "TIDDIT_COV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" + }, + "TIDDIT_COV_VCF2CYTOSURE": { + "tiddit": "3.9.5" }, "TIDDIT_SV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" }, "UCSC_WIGTOBIGWIG": { - "ucsc": 447 + "ucsc": 482 }, "UNTAR_VEP_CACHE": { "untar": 1.34 @@ -371,69 +478,213 @@ "UPD_SITES": { "upd": 0.1 }, + "VCF2CYTOSURE": { + "vcf2cytosure": "0.9.3" + }, "VCFANNO": { - "vcfanno": "0.3.5" + "vcfanno": "0.3.7" + }, + "VCFANNO_MT": { + "vcfanno": "0.3.7" }, "Workflow": { - "nf-core/raredisease": "v2.6.0" + "nf-core/raredisease": "v3.2.0dev" }, "ZIP_TABIX_ROHCALL": { - "tabix": 1.2 - }, - "ZIP_TABIX_VCFANNO": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 } }, [ "alignment", - "alignment/earlycasualcaiman_sorted_md.MarkDuplicates.metrics.txt", + "alignment/earlycasualcaiman_mt_subsample.bam", + "alignment/earlycasualcaiman_mt_subsample.bam.bai", "alignment/earlycasualcaiman_sorted_md.bam", "alignment/earlycasualcaiman_sorted_md.bam.bai", - "alignment/hugelymodelbat_sorted_md.MarkDuplicates.metrics.txt", + "alignment/earlycasualcaiman_sorted_md.metrics.txt", + "alignment/hugelymodelbat_mt_subsample.bam", + "alignment/hugelymodelbat_mt_subsample.bam.bai", "alignment/hugelymodelbat_sorted_md.bam", "alignment/hugelymodelbat_sorted_md.bam.bai", - "alignment/slowlycivilbuck_sorted_md.MarkDuplicates.metrics.txt", + "alignment/hugelymodelbat_sorted_md.metrics.txt", + "alignment/slowlycivilbuck_mt_subsample.bam", + "alignment/slowlycivilbuck_mt_subsample.bam.bai", "alignment/slowlycivilbuck_sorted_md.bam", "alignment/slowlycivilbuck_sorted_md.bam.bai", + "alignment/slowlycivilbuck_sorted_md.metrics.txt", + "annotate_mobile_elements", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz.tbi", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz.tbi", "annotate_snv", "annotate_snv/genome", "annotate_snv/genome/earlycasualcaiman_rhocallviz", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr1.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr10.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr11.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr12.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr13.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr14.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr15.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr16.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr17.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr18.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr19.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr2.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr20.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr21.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr22.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr3.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr4.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr5.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr6.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr7.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr8.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr9.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrM.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrX.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrY.png", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.bed", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.bw", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.wig", - "annotate_snv/genome/earlycasualcaiman_rhocallviz_autozyg_chromograph", - "annotate_snv/genome/hugelymodelbat_chromograph_regions", - "annotate_snv/genome/hugelymodelbat_chromograph_sites", "annotate_snv/genome/hugelymodelbat_rhocallviz", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrY.png", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bed", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bw", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.wig", - "annotate_snv/genome/hugelymodelbat_rhocallviz_autozyg_chromograph", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrY.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrY.png", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz", - "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.csi", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.tbi", "annotate_snv/genome/slowlycivilbuck_rhocallviz", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr1.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr10.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr11.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr12.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr13.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr14.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr15.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr16.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr17.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr18.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr19.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr2.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr20.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr21.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr22.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr3.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr4.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr5.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr6.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr7.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr8.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr9.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrM.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrX.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrY.png", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.bed", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.bw", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.wig", - "annotate_snv/genome/slowlycivilbuck_rhocallviz_autozyg_chromograph", + "annotate_snv/mitochondria", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz.tbi", + "annotate_sv", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz.tbi", + "annotate_sv/justhusky_svdbquery_vep_summary.html", + "call_mobile_elements", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz.tbi", "call_snv", "call_snv/genome", "call_snv/genome/justhusky_snv.vcf.gz", "call_snv/genome/justhusky_snv.vcf.gz.tbi", "call_snv/mitochondria", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz", - "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.csi", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.tbi", "call_sv", - "call_sv/genome", - "call_sv/genome/justhusky_sv.vcf.gz", - "call_sv/genome/justhusky_sv.vcf.gz.csi", - "call_sv/genome/justhusky_sv.vcf.gz.tbi", - "call_sv/mitochondria", - "call_sv/mitochondria/earlycasualcaiman_mitochondria_deletions.txt", - "call_sv/mitochondria/hugelymodelbat_mitochondria_deletions.txt", - "call_sv/mitochondria/slowlycivilbuck_mitochondria_deletions.txt", + "call_sv/earlycasualcaiman.saltshaker.png", + "call_sv/earlycasualcaiman_mitochondria_deletions.txt", + "call_sv/hugelymodelbat.saltshaker.png", + "call_sv/hugelymodelbat_mitochondria_deletions.txt", + "call_sv/justhusky.saltshaker_classify.html", + "call_sv/justhusky_sv.vcf.gz", + "call_sv/justhusky_sv.vcf.gz.tbi", + "call_sv/slowlycivilbuck.saltshaker.png", + "call_sv/slowlycivilbuck_mitochondria_deletions.txt", "fastqc", "fastqc/earlycasualcaiman_LNUMBER1", "fastqc/earlycasualcaiman_LNUMBER1/earlycasualcaiman_LNUMBER1.html", @@ -444,20 +695,32 @@ "fastqc/slowlycivilbuck_LNUMBER2", "fastqc/slowlycivilbuck_LNUMBER2/slowlycivilbuck_LNUMBER2.html", "fastqc/slowlycivilbuck_LNUMBER2/slowlycivilbuck_LNUMBER2.zip", - "haplocheck", - "haplocheck/earlycasualcaiman.raw.txt", - "haplocheck/hugelymodelbat.raw.txt", - "haplocheck/slowlycivilbuck.raw.txt", "multiqc", "multiqc/multiqc_data", + "multiqc/multiqc_data/.stub", "multiqc/multiqc_plots", + "multiqc/multiqc_plots/.stub", "multiqc/multiqc_report.html", + "ngsbits_samplegender", + "ngsbits_samplegender/earlycasualcaiman_ngsbits_sex.tsv", + "ngsbits_samplegender/hugelymodelbat_ngsbits_sex.tsv", + "ngsbits_samplegender/slowlycivilbuck_ngsbits_sex.tsv", + "peddy", + "peddy/justhusky.het_check.csv", + "peddy/justhusky.het_check.png", + "peddy/justhusky.html", + "peddy/justhusky.ped_check.csv", + "peddy/justhusky.ped_check.png", + "peddy/justhusky.ped_check.rel-difference.csv", + "peddy/justhusky.peddy.ped", + "peddy/justhusky.sex_check.csv", + "peddy/justhusky.sex_check.png", + "peddy/justhusky.vs.html", "pedigree", "pedigree/justhusky.ped", "pipeline_info", "pipeline_info/nf_core_raredisease_software_mqc_versions.yml", "qc_bam", - "qc_bam/earlycasualcaiman_chromographcov", "qc_bam/earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/earlycasualcaiman_mosdepth.global.dist.txt", "qc_bam/earlycasualcaiman_mosdepth.per-base.bed.gz", @@ -484,9 +747,33 @@ "qc_bam/earlycasualcaiman_tidditcov.bed", "qc_bam/earlycasualcaiman_tidditcov.bw", "qc_bam/earlycasualcaiman_tidditcov.wig", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr1.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr10.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr11.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr12.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr13.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr14.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr15.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr16.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr17.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr18.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr19.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr2.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr20.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr21.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr22.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr3.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr4.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr5.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr6.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr7.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr8.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr9.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrM.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrX.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrY.png", "qc_bam/earlycasualcaiman_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/earlycasualcaiman_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", - "qc_bam/hugelymodelbat_chromographcov", "qc_bam/hugelymodelbat_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_mosdepth.global.dist.txt", "qc_bam/hugelymodelbat_mosdepth.per-base.bed.gz", @@ -513,9 +800,33 @@ "qc_bam/hugelymodelbat_tidditcov.bed", "qc_bam/hugelymodelbat_tidditcov.bw", "qc_bam/hugelymodelbat_tidditcov.wig", + "qc_bam/hugelymodelbat_tidditcov.wig_chr1.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr10.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr11.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr12.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr13.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr14.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr15.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr16.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr17.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr18.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr19.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr2.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr20.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr21.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr22.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr3.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr4.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr5.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr6.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr7.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr8.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr9.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrM.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrX.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrY.png", "qc_bam/hugelymodelbat_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", - "qc_bam/slowlycivilbuck_chromographcov", "qc_bam/slowlycivilbuck_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/slowlycivilbuck_mosdepth.global.dist.txt", "qc_bam/slowlycivilbuck_mosdepth.per-base.bed.gz", @@ -542,42 +853,489 @@ "qc_bam/slowlycivilbuck_tidditcov.bed", "qc_bam/slowlycivilbuck_tidditcov.bw", "qc_bam/slowlycivilbuck_tidditcov.wig", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr1.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr10.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr11.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr12.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr13.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr14.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr15.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr16.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr17.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr18.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr19.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr2.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr20.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr21.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr22.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr3.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr4.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr5.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr6.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr7.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr8.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr9.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrM.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrX.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrY.png", "qc_bam/slowlycivilbuck_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/slowlycivilbuck_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", "rank_and_filter", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz.tbi", "repeat_expansions", "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam", "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam.bai", - "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam.csi", "repeat_expansions/earlycasualcaiman_repeat_expansion.vcf", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.bai", - "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.csi", "repeat_expansions/hugelymodelbat_repeat_expansion.vcf", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz.tbi", "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam", "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam.bai", - "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam.csi", "repeat_expansions/slowlycivilbuck_repeat_expansion.vcf", "smncopynumbercaller", "smncopynumbercaller/out", "smncopynumbercaller/out/justhusky_smncopynumbercaller.json", - "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv" + "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv", + "trimming", + "trimming/earlycasualcaiman_LNUMBER1.fastp.html", + "trimming/earlycasualcaiman_LNUMBER1.fastp.json", + "trimming/earlycasualcaiman_LNUMBER1.fastp.log", + "trimming/earlycasualcaiman_LNUMBER1_R1.fastp.fastq.gz", + "trimming/earlycasualcaiman_LNUMBER1_R2.fastp.fastq.gz", + "trimming/hugelymodelbat_LNUMBER3.fastp.html", + "trimming/hugelymodelbat_LNUMBER3.fastp.json", + "trimming/hugelymodelbat_LNUMBER3.fastp.log", + "trimming/hugelymodelbat_LNUMBER3_R1.fastp.fastq.gz", + "trimming/hugelymodelbat_LNUMBER3_R2.fastp.fastq.gz", + "trimming/slowlycivilbuck_LNUMBER2.fastp.html", + "trimming/slowlycivilbuck_LNUMBER2.fastp.json", + "trimming/slowlycivilbuck_LNUMBER2.fastp.log", + "trimming/slowlycivilbuck_LNUMBER2_R1.fastp.fastq.gz", + "trimming/slowlycivilbuck_LNUMBER2_R2.fastp.fastq.gz", + "vcf2cytosure", + "vcf2cytosure/earlycasualcaiman.cgh", + "vcf2cytosure/hugelymodelbat.cgh", + "vcf2cytosure/slowlycivilbuck.cgh" + ], + [ + "earlycasualcaiman_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mt_subsample.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mt_subsample.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_sorted_md.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_sorted_md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_sorted_md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_me_pli_clinical.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_me_pli_clinical.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_me_pli_research.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_me_pli_research.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_regions.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_upd_sites.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_rhocall_filter_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_rhocall_filter_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_rhocallviz.wig:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_mitochondria_vcfanno_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mitochondria_vcfanno_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_svdbquery_vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_svdbquery_vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_svdbquery_vep_summary.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_mobile_elements.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mobile_elements.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_snv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_snv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_mitochondria.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mitochondria.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.saltshaker_classify.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_sv.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_sv.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck.saltshaker.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mitochondria_deletions.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1.zip:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_LNUMBER3.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_LNUMBER3.zip:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_LNUMBER2.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_LNUMBER2.zip:md5,d41d8cd98f00b204e9800998ecf8427e", + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e", + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_ngsbits_sex.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_ngsbits_sex.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_ngsbits_sex.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.het_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.het_check.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.ped_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.ped_check.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.ped_check.rel-difference.csv:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.peddy.ped:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.sex_check.csv:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.sex_check.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.vs.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky.ped:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.global.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.per-base.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_mosdepth.per-base.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.per-base.d4:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.quantized.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_mosdepth.quantized.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.region.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.regions.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_mosdepth.regions.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_mosdepth.thresholds.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_mosdepth.thresholds.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.bed:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_tidditcov.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_tidditcov.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_tidditcov.wig_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_wgsmetrics.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_wgsmetrics_y.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_hsmetrics.CollectHsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.global.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.per-base.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_mosdepth.per-base.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.per-base.d4:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.quantized.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_mosdepth.quantized.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.region.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.regions.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_mosdepth.regions.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_mosdepth.thresholds.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_mosdepth.thresholds.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.bed:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_tidditcov.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_tidditcov.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_tidditcov.wig_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_wgsmetrics.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_wgsmetrics_y.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_hsmetrics.CollectHsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.global.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.per-base.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_mosdepth.per-base.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.per-base.d4:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.quantized.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_mosdepth.quantized.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.region.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.regions.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_mosdepth.regions.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_mosdepth.thresholds.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_mosdepth.thresholds.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_multiplemetrics.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.bed:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_tidditcov.bw:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_tidditcov.wig_chr1.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr10.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr11.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr12.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr13.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr14.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr15.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr16.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr17.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr18.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr19.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr2.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr20.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr21.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr22.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr3.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr4.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr5.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr6.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr7.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr8.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chr9.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chrM.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chrX.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_tidditcov.wig_chrY.png:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_wgsmetrics.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_wgsmetrics_y.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_mt_ranked_clinical.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mt_ranked_clinical.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_mt_ranked_research.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_mt_ranked_research.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_snv_ranked_clinical.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_snv_ranked_clinical.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_snv_ranked_research.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_snv_ranked_research.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_sv_ranked_clinical.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_sv_ranked_clinical.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_sv_ranked_research.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_sv_ranked_research.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_exphunter_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_exphunter_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_repeat_expansion.vcf:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_exphunter_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_exphunter_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_repeat_expansion.vcf:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_repeat_expansion_stranger.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "justhusky_repeat_expansion_stranger.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_exphunter_sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_exphunter_sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_repeat_expansion.vcf:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_smncopynumbercaller.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "justhusky_smncopynumbercaller.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "earlycasualcaiman_LNUMBER1_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman_LNUMBER1_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_LNUMBER3.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_LNUMBER3.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_LNUMBER3.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat_LNUMBER3_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "hugelymodelbat_LNUMBER3_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_LNUMBER2.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_LNUMBER2.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_LNUMBER2.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck_LNUMBER2_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "slowlycivilbuck_LNUMBER2_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "earlycasualcaiman.cgh:md5,d41d8cd98f00b204e9800998ecf8427e", + "hugelymodelbat.cgh:md5,d41d8cd98f00b204e9800998ecf8427e", + "slowlycivilbuck.cgh:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "timestamp": "2026-06-26T14:16:17.160260766", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" - }, - "timestamp": "2025-06-16T15:08:20.089341908" + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } } } \ No newline at end of file diff --git a/tests/nextflow.config b/tests/nextflow.config index 8a838141a..1caf522fb 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -4,9 +4,25 @@ ======================================================================================== */ -// TODO nf-core: Specify any additional parameters here -// Or any resources requirements -params.modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' -params.pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/raredisease' +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '2.h' + ] +} + +params { + 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/raredisease/' + sarscov_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' +} aws.client.anonymous = true // fixes S3 access issues on self-hosted runners + +// NOTE This is how pipeline users will use Sentieon in real world use +env.SENTIEON_LICENSE = env('SENTIEON_LICSRVR_IP') + +// NOTE This should only happen in GitHub actions or nf-core MegaTests +env.SENTIEON_AUTH_MECH = env('SENTIEON_AUTH_MECH') +env.SENTIEON_AUTH_DATA = secrets.SENTIEON_AUTH_DATA diff --git a/tests/test_bam.nf.test b/tests/test_bam.nf.test index 82487c3eb..20c314c84 100644 --- a/tests/test_bam.nf.test +++ b/tests/test_bam.nf.test @@ -11,7 +11,8 @@ nextflow_pipeline { when { params { - outdir = "$outputDir" + outdir = "$outputDir" + skip_tools = "germlinecnvcaller,gens" } } diff --git a/tests/test_bam.nf.test.snap b/tests/test_bam.nf.test.snap index 5f568670b..99e8993b0 100644 --- a/tests/test_bam.nf.test.snap +++ b/tests/test_bam.nf.test.snap @@ -1,51 +1,59 @@ { "-profile test_bam": { "content": [ - 282, + 774, { - "ADD_MOST_SEVERE_CSQ": { - "add_most_severe_consequence": "v1.1", - "python": "3.8.3" - }, - "ADD_MOST_SEVERE_PLI": { - "add_most_severe_pli": "v1.1", - "python": "3.8.3" - }, "ADD_VARCALLER_TO_BED": { - "tabix": 1.12 + "bgzip": 1.21, + "tabix": 1.21 }, "BCFTOOLS_ANNOTATE": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_CONCAT": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_CONCAT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_MERGE_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_REHEADER_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_REHEADER_ME": { + "bcftools": 1.22 }, "BCFTOOLS_ROH": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_SORT": { + "bcftools": 1.22 + }, + "BCFTOOLS_SORT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_CNVNATOR": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_VIEW_FILTER": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW_MANTA": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_RHOCALL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_TIDDIT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_UNCOMPRESS": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BEDTOOLS_PAD_TARGET_BED": { "bedtools": "2.31.1" @@ -61,13 +69,13 @@ }, "BWAMEM2_MEM_MT": { "bwamem2": "2.2.1", - "samtools": "1.19.2" + "samtools": "1.22.1" }, "BWA_INDEX_GENOME": { - "bwa": "0.7.18-r1243-dirty" + "bwa": "0.7.19-r1273" }, "CAT_CAT_BAIT": { - "pigz": "2.3.4" + "pigz": 2.8 }, "CHROMOGRAPH_AUTOZYG": { "chromograph": "1.3.1" @@ -82,156 +90,214 @@ "chromograph": "1.3.1" }, "CNVNATOR_CALL": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_CONVERT2VCF": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_HIST": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_PARTITION": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_RD": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_STAT": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" + }, + "CREATE_HGNCIDS_FILE": { + "create_hgncids_file": 1.0, + "python": "3.14.3" }, "CREATE_PEDIGREE_FILE": { - "create_pedigree_file": "v1.0", - "python": "3.8.3" + "coreutils": 9.5 + }, + "CUSTOM_ADDMOSTSEVERECONSEQUENCE": { + "addmostsevereconsequence": "1.2.0", + "bgzip": 1.21 + }, + "CUSTOM_ADDMOSTSEVEREPLI": { + "addmostseverepli": "1.2.0", + "bgzip": 1.21 }, "DEEPVARIANT": { - "deepvariant": "1.8.0" + "deepvariant": "1.9.0" + }, + "ENSEMBLVEP_ME": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, - "ENSEMBLVEP_FILTERVEP": { - "ensemblvep": 110.0 + "ENSEMBLVEP_MT": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "ENSEMBLVEP_SNV": { - "ensemblvep": 110.0 + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 + }, + "ENSEMBLVEP_SV": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "EXPANSIONHUNTER": { - "expansionhunter": "5.0.0", - "bgzip": 1.18 + "bgzip": "1.22.1", + "expansionhunter": "5.0.0" + }, + "FILTERVEP": { + "filtervep": "1.0.0" }, "GATK4_FILTERMUTECTCALLS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEBAMALIGNMENT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEVCFS_LIFT_UNLIFT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MUTECT2_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_PRINTREADS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_REVERTSAM_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SAMTOFASTQ_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SELECTVARIANTS": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GATK4_SPLITINTERVALS": { + "gatk4": "4.6.2.0" }, "GATK4_VARIANTFILTRATION_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_BILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_ILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SHIFTFASTA": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GAWK": { + "gawk": "5.3.1" }, "GENMOD_ANNOTATE": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_COMPOUND": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_MODELS": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_SCORE": { - "genmod": 3.9 + "genmod": "3.10.2" + }, + "GENOME_FAI_TO_BED": { + "gawk": "5.3.1" }, "GET_CHROM_SIZES": { - "coreutils": 8.31 + "coreutils": 9.5 }, "GLNEXUS": { - "glnexus": "1.4.1-0-g68e25e5" + "glnexus": "1.4.1" }, - "HAPLOCHECK_MT": { - "haplocheck": "1.3.3" + "HISAT2_INDEX_GENOME": { + "hisat2": "2.2.1" }, "INDEX_CNVNATOR": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "INDEX_TIDDIT": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 + }, + "LAST_INDEX_MT": { + "last": 1611 }, "MANTA": { "manta": "1.6.0" }, + "ME_SPLIT_ALIGNMENT": { + "samtools": "1.22.1" + }, "MOSDEPTH": { - "mosdepth": "0.3.8" + "mosdepth": "0.3.11" }, "MT_DELETION": { - "samtools": "1.19.2" + "mitodel": 1.0, + "samtools": 1.23 }, "NGSBITS_SAMPLEGENDER": { - "ngs-bits": 202302 + "ngsbits": 202512 + }, + "PEDDY": { + "peddy": "0.4.8" }, "PICARD_ADDORREPLACEREADGROUPS_MT": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTHSMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTMULTIPLEMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_WG": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_Y": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_LIFTOVERVCF": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_MARKDUPLICATES_MT": { - "picard": "3.3.0" + "picard": "3.4.0" + }, + "PICARD_SORTVCF": { + "picard": "3.4.0" }, "REMOVE_DUPLICATES_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "REMOVE_DUPLICATES_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "RENAMESAMPLE_EXP": { - "picard": "3.3.0" + "picard": "3.4.0" }, "RENAME_BAI": { - "coreutils": 8.31 + "coreutils": 9.5 }, "RENAME_BAM": { - "coreutils": 8.31 + "coreutils": 9.5 + }, + "RETROSEQ_CALL": { + "retroseq": 1.5 + }, + "RETROSEQ_DISCOVER": { + "retroseq": 1.5 }, "RHOCALL_ANNOTATE": { "rhocall": "0.5.1" @@ -239,109 +305,127 @@ "RHOCALL_VIZ": { "rhocall": "0.5.1" }, + "SAMTOOLS_COLLATE": { + "samtools": "1.22.1" + }, "SAMTOOLS_EXTRACT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_FAIDX_MT": { - "samtools": 1.21 - }, - "SAMTOOLS_INDEX": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" + }, + "SAMTOOLS_VIEW": { + "samtools": "1.22.1" + }, + "SAM_TO_BAM": { + "samtools": "1.22.1" }, "SMNCOPYNUMBERCALLER": { - "SMNCopyNumberCaller": "1.1.2" + "smncopynumbercaller": "1.1.2" + }, + "SPLIT_AND_FILTER_SV_VCF": { + "bcftools": 1.22 + }, + "SPLIT_CHR": { + "bioawk": 1.0 }, "SPLIT_MULTIALLELICS_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_MT": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "SPLIT_MULTIALLELICS_POSTMERGE_MT": { + "bcftools": 1.22 }, "STRANGER": { - "stranger": "0.9.4", - "tabix": 1.21 + "stranger": "0.10.0", + "tabix": 1.23 }, "SVDB_MERGE": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_CNVNATOR": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" + }, + "SVDB_MERGE_ME": { + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_REPEATS": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_TIDDIT": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, - "TABIX_ANNOTATE": { - "tabix": 1.2 + "SVDB_QUERY_DB": { + "svdb": "2.8.4" }, - "TABIX_BCFTOOLS_CONCAT": { - "tabix": 1.2 - }, - "TABIX_BGZIP": { - "tabix": 1.2 + "TABIX_ANNOTATE": { + "tabix": 1.21 }, "TABIX_BGZIPINDEX_PADDED_BED": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_BGZIPTABIX": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_DBSNP": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_EXP_RENAME": { - "tabix": 1.2 - }, - "TABIX_GL": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_GNOMAD_AF": { - "tabix": 1.2 + "tabix": 1.21 + }, + "TABIX_ME": { + "tabix": 1.21 }, - "TABIX_PBT": { - "tabix": 1.2 + "TABIX_ME_SPLIT": { + "tabix": 1.21 }, "TABIX_TABIX": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MERGE": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT2": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT": { - "tabix": 1.2 - }, - "TABIX_VEP": { - "tabix": 1.2 + "tabix": 1.21 }, "TIDDIT_COV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" + }, + "TIDDIT_COV_VCF2CYTOSURE": { + "tiddit": "3.9.5" }, "TIDDIT_SV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" }, "UCSC_WIGTOBIGWIG": { - "ucsc": 447 + "ucsc": 482 }, "UNTAR_VEP_CACHE": { "untar": 1.34 @@ -352,77 +436,226 @@ "UPD_SITES": { "upd": 0.1 }, + "VCF2CYTOSURE": { + "vcf2cytosure": "0.9.3" + }, "VCFANNO": { - "vcfanno": "0.3.5" + "vcfanno": "0.3.7" + }, + "VCFANNO_MT": { + "vcfanno": "0.3.7" }, "Workflow": { - "nf-core/raredisease": "v2.6.0" + "nf-core/raredisease": "v3.2.0dev" }, "ZIP_TABIX_ROHCALL": { - "tabix": 1.2 - }, - "ZIP_TABIX_VCFANNO": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 } }, [ + "alignment", + "alignment/earlycasualcaiman_mt_subsample.bam", + "alignment/earlycasualcaiman_mt_subsample.bam.bai", + "alignment/hugelymodelbat_mt_subsample.bam", + "alignment/hugelymodelbat_mt_subsample.bam.bai", + "alignment/slowlycivilbuck_mt_subsample.bam", + "alignment/slowlycivilbuck_mt_subsample.bam.bai", + "annotate_mobile_elements", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz.tbi", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz.tbi", "annotate_snv", "annotate_snv/genome", "annotate_snv/genome/earlycasualcaiman_rhocallviz", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr1.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr10.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr11.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr12.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr13.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr14.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr15.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr16.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr17.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr18.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr19.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr2.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr20.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr21.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr22.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr3.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr4.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr5.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr6.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr7.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr8.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chr9.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrM.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrX.png", + "annotate_snv/genome/earlycasualcaiman_rhocallviz.bed_chrY.png", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.bed", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.bw", "annotate_snv/genome/earlycasualcaiman_rhocallviz/earlycasualcaiman_rhocallviz.wig", - "annotate_snv/genome/earlycasualcaiman_rhocallviz_autozyg_chromograph", - "annotate_snv/genome/hugelymodelbat_chromograph_regions", - "annotate_snv/genome/hugelymodelbat_chromograph_sites", "annotate_snv/genome/hugelymodelbat_rhocallviz", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrY.png", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bed", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bw", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.wig", - "annotate_snv/genome/hugelymodelbat_rhocallviz_autozyg_chromograph", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_upd_regions.bed_chrY.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_upd_sites.bed_chrY.png", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz", - "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.csi", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.tbi", "annotate_snv/genome/slowlycivilbuck_rhocallviz", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr1.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr10.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr11.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr12.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr13.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr14.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr15.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr16.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr17.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr18.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr19.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr2.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr20.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr21.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr22.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr3.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr4.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr5.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr6.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr7.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr8.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chr9.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrM.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrX.png", + "annotate_snv/genome/slowlycivilbuck_rhocallviz.bed_chrY.png", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.bed", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.bw", "annotate_snv/genome/slowlycivilbuck_rhocallviz/slowlycivilbuck_rhocallviz.wig", - "annotate_snv/genome/slowlycivilbuck_rhocallviz_autozyg_chromograph", + "annotate_snv/mitochondria", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz.tbi", + "annotate_sv", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz.tbi", + "annotate_sv/justhusky_svdbquery_vep_summary.html", + "call_mobile_elements", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz.tbi", "call_snv", "call_snv/genome", "call_snv/genome/justhusky_snv.vcf.gz", "call_snv/genome/justhusky_snv.vcf.gz.tbi", "call_snv/mitochondria", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz", - "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.csi", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.tbi", "call_sv", - "call_sv/genome", - "call_sv/genome/justhusky_sv.vcf.gz", - "call_sv/genome/justhusky_sv.vcf.gz.csi", - "call_sv/genome/justhusky_sv.vcf.gz.tbi", - "call_sv/mitochondria", - "call_sv/mitochondria/earlycasualcaiman_mitochondria_deletions.txt", - "call_sv/mitochondria/hugelymodelbat_mitochondria_deletions.txt", - "call_sv/mitochondria/slowlycivilbuck_mitochondria_deletions.txt", - "haplocheck", - "haplocheck/earlycasualcaiman.raw.txt", - "haplocheck/hugelymodelbat.raw.txt", - "haplocheck/slowlycivilbuck.raw.txt", + "call_sv/earlycasualcaiman_mitochondria_deletions.txt", + "call_sv/hugelymodelbat_mitochondria_deletions.txt", + "call_sv/justhusky_sv.vcf.gz", + "call_sv/justhusky_sv.vcf.gz.tbi", + "call_sv/slowlycivilbuck_mitochondria_deletions.txt", "multiqc", "multiqc/multiqc_data", + "multiqc/multiqc_data/.stub", "multiqc/multiqc_plots", + "multiqc/multiqc_plots/.stub", "multiqc/multiqc_report.html", "ngsbits_samplegender", "ngsbits_samplegender/earlycasualcaiman_ngsbits_sex.tsv", "ngsbits_samplegender/hugelymodelbat_ngsbits_sex.tsv", "ngsbits_samplegender/slowlycivilbuck_ngsbits_sex.tsv", + "peddy", + "peddy/justhusky.het_check.csv", + "peddy/justhusky.het_check.png", + "peddy/justhusky.html", + "peddy/justhusky.ped_check.csv", + "peddy/justhusky.ped_check.png", + "peddy/justhusky.ped_check.rel-difference.csv", + "peddy/justhusky.peddy.ped", + "peddy/justhusky.sex_check.csv", + "peddy/justhusky.sex_check.png", + "peddy/justhusky.vs.html", "pedigree", "pedigree/justhusky.ped", "pipeline_info", "pipeline_info/nf_core_raredisease_software_mqc_versions.yml", "qc_bam", - "qc_bam/earlycasualcaiman_chromographcov", "qc_bam/earlycasualcaiman_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/earlycasualcaiman_mosdepth.global.dist.txt", "qc_bam/earlycasualcaiman_mosdepth.per-base.bed.gz", @@ -449,9 +682,33 @@ "qc_bam/earlycasualcaiman_tidditcov.bed", "qc_bam/earlycasualcaiman_tidditcov.bw", "qc_bam/earlycasualcaiman_tidditcov.wig", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr1.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr10.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr11.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr12.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr13.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr14.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr15.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr16.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr17.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr18.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr19.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr2.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr20.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr21.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr22.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr3.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr4.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr5.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr6.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr7.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr8.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chr9.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrM.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrX.png", + "qc_bam/earlycasualcaiman_tidditcov.wig_chrY.png", "qc_bam/earlycasualcaiman_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/earlycasualcaiman_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", - "qc_bam/hugelymodelbat_chromographcov", "qc_bam/hugelymodelbat_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_mosdepth.global.dist.txt", "qc_bam/hugelymodelbat_mosdepth.per-base.bed.gz", @@ -478,9 +735,33 @@ "qc_bam/hugelymodelbat_tidditcov.bed", "qc_bam/hugelymodelbat_tidditcov.bw", "qc_bam/hugelymodelbat_tidditcov.wig", + "qc_bam/hugelymodelbat_tidditcov.wig_chr1.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr10.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr11.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr12.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr13.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr14.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr15.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr16.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr17.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr18.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr19.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr2.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr20.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr21.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr22.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr3.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr4.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr5.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr6.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr7.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr8.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr9.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrM.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrX.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrY.png", "qc_bam/hugelymodelbat_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", - "qc_bam/slowlycivilbuck_chromographcov", "qc_bam/slowlycivilbuck_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/slowlycivilbuck_mosdepth.global.dist.txt", "qc_bam/slowlycivilbuck_mosdepth.per-base.bed.gz", @@ -507,42 +788,72 @@ "qc_bam/slowlycivilbuck_tidditcov.bed", "qc_bam/slowlycivilbuck_tidditcov.bw", "qc_bam/slowlycivilbuck_tidditcov.wig", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr1.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr10.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr11.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr12.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr13.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr14.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr15.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr16.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr17.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr18.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr19.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr2.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr20.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr21.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr22.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr3.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr4.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr5.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr6.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr7.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr8.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chr9.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrM.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrX.png", + "qc_bam/slowlycivilbuck_tidditcov.wig_chrY.png", "qc_bam/slowlycivilbuck_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/slowlycivilbuck_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", "rank_and_filter", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz.tbi", "repeat_expansions", "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam", "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam.bai", - "repeat_expansions/earlycasualcaiman_exphunter_sorted.bam.csi", "repeat_expansions/earlycasualcaiman_repeat_expansion.vcf", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.bai", - "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.csi", "repeat_expansions/hugelymodelbat_repeat_expansion.vcf", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz.tbi", "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam", "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam.bai", - "repeat_expansions/slowlycivilbuck_exphunter_sorted.bam.csi", "repeat_expansions/slowlycivilbuck_repeat_expansion.vcf", "smncopynumbercaller", "smncopynumbercaller/out", "smncopynumbercaller/out/justhusky_smncopynumbercaller.json", - "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv" + "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv", + "vcf2cytosure", + "vcf2cytosure/earlycasualcaiman.cgh", + "vcf2cytosure/hugelymodelbat.cgh", + "vcf2cytosure/slowlycivilbuck.cgh" ] ], + "timestamp": "2026-06-25T10:12:33.084372846", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" - }, - "timestamp": "2025-06-16T15:11:10.063786271" + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/tests/test_singleton.nf.test b/tests/test_singleton.nf.test index 235365090..245921098 100644 --- a/tests/test_singleton.nf.test +++ b/tests/test_singleton.nf.test @@ -11,7 +11,8 @@ nextflow_pipeline { when { params { - outdir = "$outputDir" + outdir = "$outputDir" + skip_tools = "germlinecnvcaller,gens" } } diff --git a/tests/test_singleton.nf.test.snap b/tests/test_singleton.nf.test.snap index 13693ae0e..8e5a6c186 100644 --- a/tests/test_singleton.nf.test.snap +++ b/tests/test_singleton.nf.test.snap @@ -1,48 +1,56 @@ { "-profile test_singleton": { "content": [ - 152, + 355, { - "ADD_MOST_SEVERE_CSQ": { - "add_most_severe_consequence": "v1.1", - "python": "3.8.3" - }, - "ADD_MOST_SEVERE_PLI": { - "add_most_severe_pli": "v1.1", - "python": "3.8.3" - }, "ADD_VARCALLER_TO_BED": { - "tabix": 1.12 + "bgzip": 1.21, + "tabix": 1.21 }, "BCFTOOLS_ANNOTATE": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_CONCAT": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_CONCAT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_REHEADER_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_REHEADER_ME": { + "bcftools": 1.22 }, "BCFTOOLS_ROH": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_SORT": { + "bcftools": 1.22 + }, + "BCFTOOLS_SORT_ME": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_CNVNATOR": { - "bcftools": 1.2 + "bcftools": 1.22 + }, + "BCFTOOLS_VIEW_FILTER": { + "bcftools": 1.22 }, "BCFTOOLS_VIEW_MANTA": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_RHOCALL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_TIDDIT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BCFTOOLS_VIEW_UNCOMPRESS": { - "bcftools": 1.2 + "bcftools": 1.22 }, "BEDTOOLS_PAD_TARGET_BED": { "bedtools": "2.31.1" @@ -58,17 +66,20 @@ }, "BWAMEM2_MEM": { "bwamem2": "2.2.1", - "samtools": "1.19.2" + "samtools": "1.22.1" }, "BWAMEM2_MEM_MT": { "bwamem2": "2.2.1", - "samtools": "1.19.2" + "samtools": "1.22.1" }, "BWA_INDEX_GENOME": { - "bwa": "0.7.18-r1243-dirty" + "bwa": "0.7.19-r1273" }, "CAT_CAT_BAIT": { - "pigz": "2.3.4" + "pigz": 2.8 + }, + "CAT_FASTQ": { + "cat": 9.5 }, "CHROMOGRAPH_AUTOZYG": { "chromograph": "1.3.1" @@ -77,159 +88,226 @@ "chromograph": "1.3.1" }, "CNVNATOR_CALL": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_CONVERT2VCF": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_HIST": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_PARTITION": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_RD": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" }, "CNVNATOR_STAT": { - "CNVnator": "0.4.1" + "cnvnator": "0.4.1" + }, + "CREATE_HGNCIDS_FILE": { + "create_hgncids_file": 1.0, + "python": "3.14.3" }, "CREATE_PEDIGREE_FILE": { - "create_pedigree_file": "v1.0", - "python": "3.8.3" + "coreutils": 9.5 + }, + "CUSTOM_ADDMOSTSEVERECONSEQUENCE": { + "addmostsevereconsequence": "1.2.0", + "bgzip": 1.21 + }, + "CUSTOM_ADDMOSTSEVEREPLI": { + "addmostseverepli": "1.2.0", + "bgzip": 1.21 }, "DEEPVARIANT": { - "deepvariant": "1.8.0" + "deepvariant": "1.9.0" + }, + "ENSEMBLVEP_ME": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, - "ENSEMBLVEP_FILTERVEP": { - "ensemblvep": 110.0 + "ENSEMBLVEP_MT": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "ENSEMBLVEP_SNV": { - "ensemblvep": 110.0 + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 + }, + "ENSEMBLVEP_SV": { + "ensemblvep": 110.1, + "perl-math-cdf": 0.1, + "tabix": 1.21 }, "EXPANSIONHUNTER": { - "expansionhunter": "5.0.0", - "bgzip": 1.18 + "bgzip": "1.22.1", + "expansionhunter": "5.0.0" + }, + "FASTP": { + "fastp": "1.0.1" }, "FASTQC": { "fastqc": "0.12.1" }, + "FILTERVEP": { + "filtervep": "1.0.0" + }, "GATK4_FILTERMUTECTCALLS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEBAMALIGNMENT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MERGEVCFS_LIFT_UNLIFT_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_MUTECT2_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_PRINTREADS_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_REVERTSAM_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SAMTOFASTQ_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK4_SELECTVARIANTS": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GATK4_SPLITINTERVALS": { + "gatk4": "4.6.2.0" }, "GATK4_VARIANTFILTRATION_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_BILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_ILT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SD_MT": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" }, "GATK_SHIFTFASTA": { - "gatk4": "4.5.0.0" + "gatk4": "4.6.2.0" + }, + "GAWK": { + "gawk": "5.3.1" }, "GENMOD_ANNOTATE": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_COMPOUND": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_MODELS": { - "genmod": 3.9 + "genmod": "3.10.2" }, "GENMOD_SCORE": { - "genmod": 3.9 + "genmod": "3.10.2" + }, + "GENOME_FAI_TO_BED": { + "gawk": "5.3.1" }, "GET_CHROM_SIZES": { - "coreutils": 8.31 + "coreutils": 9.5 }, "GLNEXUS": { - "glnexus": "1.4.1-0-g68e25e5" + "glnexus": "1.4.1" }, - "HAPLOCHECK_MT": { - "haplocheck": "1.3.3" + "HISAT2_INDEX_GENOME": { + "hisat2": "2.2.1" }, "INDEX_CNVNATOR": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "INDEX_TIDDIT": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 + }, + "LAST_INDEX_MT": { + "last": 1611 }, "MANTA": { "manta": "1.6.0" }, "MARKDUPLICATES": { - "picard": "3.3.0" + "picard": "3.4.0" + }, + "ME_SPLIT_ALIGNMENT": { + "samtools": "1.22.1" + }, + "MITOSALT": { + "mitosalt": "1.1.1" }, "MOSDEPTH": { - "mosdepth": "0.3.8" + "mosdepth": "0.3.11" }, "MT_DELETION": { - "samtools": "1.19.2" + "mitodel": 1.0, + "samtools": 1.23 + }, + "NGSBITS_SAMPLEGENDER": { + "ngsbits": 202512 + }, + "PEDDY": { + "peddy": "0.4.8" }, "PICARD_ADDORREPLACEREADGROUPS_MT": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTHSMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTMULTIPLEMETRICS": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_WG": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_COLLECTWGSMETRICS_Y": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_LIFTOVERVCF": { - "picard": "3.3.0" + "picard": "3.4.0" }, "PICARD_MARKDUPLICATES_MT": { - "picard": "3.3.0" + "picard": "3.4.0" + }, + "PICARD_SORTVCF": { + "picard": "3.4.0" }, "REMOVE_DUPLICATES_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "REMOVE_DUPLICATES_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "RENAMESAMPLE_EXP": { - "picard": "3.3.0" + "picard": "3.4.0" }, "RENAME_BAI": { - "coreutils": 8.31 + "coreutils": 9.5 }, "RENAME_BAM": { - "coreutils": 8.31 + "coreutils": 9.5 + }, + "RETROSEQ_CALL": { + "retroseq": 1.5 + }, + "RETROSEQ_DISCOVER": { + "retroseq": 1.5 }, "RHOCALL_ANNOTATE": { "rhocall": "0.5.1" @@ -237,181 +315,262 @@ "RHOCALL_VIZ": { "rhocall": "0.5.1" }, + "SALTSHAKER_CALL": { + "saltshaker": "1.1.1" + }, + "SALTSHAKER_CLASSIFY": { + "saltshaker": "1.1.1" + }, + "SALTSHAKER_PLOT": { + "saltshaker": "1.1.1" + }, + "SAMTOOLS_COLLATE": { + "samtools": "1.22.1" + }, "SAMTOOLS_EXTRACT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_FAIDX_MT": { - "samtools": 1.21 - }, - "SAMTOOLS_INDEX": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_ALIGN": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_MARKDUP": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_INDEX_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_SORT_MT": { - "samtools": 1.21 + "samtools": "1.22.1" }, "SAMTOOLS_STATS": { - "samtools": 1.21 + "samtools": "1.22.1" + }, + "SAMTOOLS_VIEW": { + "samtools": "1.22.1" + }, + "SAM_TO_BAM": { + "samtools": "1.22.1" + }, + "SEQTK_SAMPLE": { + "seqtk": "1.4-r122" }, "SMNCOPYNUMBERCALLER": { - "SMNCopyNumberCaller": "1.1.2" + "smncopynumbercaller": "1.1.2" + }, + "SPLIT_AND_FILTER_SV_VCF": { + "bcftools": 1.22 + }, + "SPLIT_CHR": { + "bioawk": 1.0 }, "SPLIT_MULTIALLELICS_EXP": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_GL": { - "bcftools": 1.2 + "bcftools": 1.22 }, "SPLIT_MULTIALLELICS_MT": { - "bcftools": 1.2 + "bcftools": 1.22 }, "STRANGER": { - "stranger": "0.9.4", - "tabix": 1.21 + "stranger": "0.10.0", + "tabix": 1.23 }, "SVDB_MERGE": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_CNVNATOR": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" + }, + "SVDB_MERGE_ME": { + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_REPEATS": { - "svdb": "2.8.2", - "bcftools": 1.21 + "bcftools": 1.23, + "svdb": "2.8.4" }, "SVDB_MERGE_TIDDIT": { - "svdb": "2.8.2", - "bcftools": 1.21 - }, - "TABIX_ANNOTATE": { - "tabix": 1.2 + "bcftools": 1.23, + "svdb": "2.8.4" }, - "TABIX_BCFTOOLS_CONCAT": { - "tabix": 1.2 + "SVDB_QUERY_DB": { + "svdb": "2.8.4" }, - "TABIX_BGZIP": { - "tabix": 1.2 + "TABIX_ANNOTATE": { + "tabix": 1.21 }, "TABIX_BGZIPINDEX_PADDED_BED": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_BGZIPTABIX": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 }, "TABIX_DBSNP": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_EXP_RENAME": { - "tabix": 1.2 - }, - "TABIX_GL": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_GNOMAD_AF": { - "tabix": 1.2 + "tabix": 1.21 }, - "TABIX_PBT": { - "tabix": 1.2 + "TABIX_ME": { + "tabix": 1.21 + }, + "TABIX_ME_SPLIT": { + "tabix": 1.21 }, "TABIX_TABIX": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MERGE": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT2": { - "tabix": 1.2 + "tabix": 1.21 }, "TABIX_TABIX_MT": { - "tabix": 1.2 - }, - "TABIX_VEP": { - "tabix": 1.2 + "tabix": 1.21 }, "TIDDIT_COV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" + }, + "TIDDIT_COV_VCF2CYTOSURE": { + "tiddit": "3.9.5" }, "TIDDIT_SV": { - "tiddit": "3.6.1" + "tiddit": "3.9.5" }, "UCSC_WIGTOBIGWIG": { - "ucsc": 447 + "ucsc": 482 }, "UNTAR_VEP_CACHE": { "untar": 1.34 }, + "VCF2CYTOSURE": { + "vcf2cytosure": "0.9.3" + }, "VCFANNO": { - "vcfanno": "0.3.5" + "vcfanno": "0.3.7" + }, + "VCFANNO_MT": { + "vcfanno": "0.3.7" }, "Workflow": { - "nf-core/raredisease": "v2.6.0" + "nf-core/raredisease": "v3.2.0dev" }, "ZIP_TABIX_ROHCALL": { - "tabix": 1.2 - }, - "ZIP_TABIX_VCFANNO": { - "tabix": 1.2 + "bgzip": 1.21, + "tabix": 1.21 } }, [ "alignment", - "alignment/hugelymodelbat_sorted_md.MarkDuplicates.metrics.txt", + "alignment/hugelymodelbat_mt_subsample.bam", + "alignment/hugelymodelbat_mt_subsample.bam.bai", "alignment/hugelymodelbat_sorted_md.bam", "alignment/hugelymodelbat_sorted_md.bam.bai", + "alignment/hugelymodelbat_sorted_md.metrics.txt", + "annotate_mobile_elements", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_clinical.vcf.gz.tbi", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz", + "annotate_mobile_elements/justhusky_me_pli_research.vcf.gz.tbi", "annotate_snv", "annotate_snv/genome", "annotate_snv/genome/hugelymodelbat_rhocallviz", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr1.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr10.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr11.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr12.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr13.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr14.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr15.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr16.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr17.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr18.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr19.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr2.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr20.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr21.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr22.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr3.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr4.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr5.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr6.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr7.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr8.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chr9.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrM.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrX.png", + "annotate_snv/genome/hugelymodelbat_rhocallviz.bed_chrY.png", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bed", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.bw", "annotate_snv/genome/hugelymodelbat_rhocallviz/hugelymodelbat_rhocallviz.wig", - "annotate_snv/genome/hugelymodelbat_rhocallviz_autozyg_chromograph", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz", - "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.csi", "annotate_snv/genome/justhusky_rhocall_filter_vep.vcf.gz.tbi", + "annotate_snv/mitochondria", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz", + "annotate_snv/mitochondria/justhusky_mitochondria_vcfanno_vep.vcf.gz.tbi", + "annotate_sv", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz", + "annotate_sv/justhusky_svdbquery_vep.vcf.gz.tbi", + "annotate_sv/justhusky_svdbquery_vep_summary.html", + "call_mobile_elements", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz", + "call_mobile_elements/justhusky_mobile_elements.vcf.gz.tbi", "call_snv", "call_snv/genome", "call_snv/genome/justhusky_snv.vcf.gz", "call_snv/genome/justhusky_snv.vcf.gz.tbi", "call_snv/mitochondria", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz", - "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.csi", "call_snv/mitochondria/justhusky_mitochondria.vcf.gz.tbi", "call_sv", - "call_sv/genome", - "call_sv/genome/justhusky_sv.vcf.gz", - "call_sv/genome/justhusky_sv.vcf.gz.csi", - "call_sv/genome/justhusky_sv.vcf.gz.tbi", - "call_sv/mitochondria", - "call_sv/mitochondria/hugelymodelbat_mitochondria_deletions.txt", + "call_sv/hugelymodelbat.saltshaker.png", + "call_sv/hugelymodelbat_mitochondria_deletions.txt", + "call_sv/justhusky.saltshaker_classify.html", + "call_sv/justhusky_sv.vcf.gz", + "call_sv/justhusky_sv.vcf.gz.tbi", "fastqc", "fastqc/hugelymodelbat_LNUMBER1", "fastqc/hugelymodelbat_LNUMBER1/hugelymodelbat_LNUMBER1.html", "fastqc/hugelymodelbat_LNUMBER1/hugelymodelbat_LNUMBER1.zip", - "haplocheck", - "haplocheck/hugelymodelbat.raw.txt", "multiqc", "multiqc/multiqc_data", + "multiqc/multiqc_data/.stub", "multiqc/multiqc_plots", + "multiqc/multiqc_plots/.stub", "multiqc/multiqc_report.html", + "ngsbits_samplegender", + "ngsbits_samplegender/hugelymodelbat_ngsbits_sex.tsv", + "peddy", + "peddy/justhusky.het_check.csv", + "peddy/justhusky.het_check.png", + "peddy/justhusky.html", + "peddy/justhusky.ped_check.csv", + "peddy/justhusky.ped_check.png", + "peddy/justhusky.ped_check.rel-difference.csv", + "peddy/justhusky.peddy.ped", + "peddy/justhusky.sex_check.csv", + "peddy/justhusky.sex_check.png", + "peddy/justhusky.vs.html", "pedigree", "pedigree/justhusky.ped", "pipeline_info", "pipeline_info/nf_core_raredisease_software_mqc_versions.yml", "qc_bam", - "qc_bam/hugelymodelbat_chromographcov", "qc_bam/hugelymodelbat_hsmetrics.CollectHsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_mosdepth.global.dist.txt", "qc_bam/hugelymodelbat_mosdepth.per-base.bed.gz", @@ -438,34 +597,70 @@ "qc_bam/hugelymodelbat_tidditcov.bed", "qc_bam/hugelymodelbat_tidditcov.bw", "qc_bam/hugelymodelbat_tidditcov.wig", + "qc_bam/hugelymodelbat_tidditcov.wig_chr1.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr10.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr11.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr12.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr13.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr14.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr15.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr16.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr17.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr18.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr19.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr2.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr20.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr21.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr22.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr3.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr4.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr5.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr6.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr7.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr8.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chr9.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrM.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrX.png", + "qc_bam/hugelymodelbat_tidditcov.wig_chrY.png", "qc_bam/hugelymodelbat_wgsmetrics.CollectWgsMetrics.coverage_metrics", "qc_bam/hugelymodelbat_wgsmetrics_y.CollectWgsMetrics.coverage_metrics", "rank_and_filter", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz", + "rank_and_filter/justhusky_mt_ranked_research.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_clinical.vcf.gz.tbi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.csi", - "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.gzi", "rank_and_filter/justhusky_snv_ranked_research.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_clinical.vcf.gz.tbi", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz", + "rank_and_filter/justhusky_sv_ranked_research.vcf.gz.tbi", "repeat_expansions", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam", "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.bai", - "repeat_expansions/hugelymodelbat_exphunter_sorted.bam.csi", "repeat_expansions/hugelymodelbat_repeat_expansion.vcf", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz", "repeat_expansions/justhusky_repeat_expansion_stranger.vcf.gz.tbi", "smncopynumbercaller", "smncopynumbercaller/out", "smncopynumbercaller/out/justhusky_smncopynumbercaller.json", - "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv" + "smncopynumbercaller/out/justhusky_smncopynumbercaller.tsv", + "trimming", + "trimming/hugelymodelbat_LNUMBER1.fastp.html", + "trimming/hugelymodelbat_LNUMBER1.fastp.json", + "trimming/hugelymodelbat_LNUMBER1.fastp.log", + "trimming/hugelymodelbat_LNUMBER1_R1.fastp.fastq.gz", + "trimming/hugelymodelbat_LNUMBER1_R2.fastp.fastq.gz", + "vcf2cytosure", + "vcf2cytosure/hugelymodelbat.cgh" ] ], + "timestamp": "2026-06-26T14:21:28.826151619", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" - }, - "timestamp": "2025-06-16T15:14:25.756733004" + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } } } \ No newline at end of file diff --git a/workflows/raredisease.nf b/workflows/raredisease.nf index 531dc27ec..7b4324023 100644 --- a/workflows/raredisease.nf +++ b/workflows/raredisease.nf @@ -3,10 +3,10 @@ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { paramsSummaryMap;samplesheetToList } from 'plugin/nf-schema' -include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' -include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' -include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_raredisease_pipeline' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' +include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_raredisease_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -34,40 +34,41 @@ include { STRANGER } from '../modules/n include { RENAME_ALIGN_FILES as RENAME_BAM } from '../modules/local/rename_align_files' include { RENAME_ALIGN_FILES as RENAME_BAI } from '../modules/local/rename_align_files' -include { CREATE_HGNCIDS_FILE } from '../modules/local/create_hgncids_file' -include { CREATE_PEDIGREE_FILE } from '../modules/local/create_pedigree_file' +include { PARSE_CONTAMINATION } from '../modules/local/parse_contamination/main' +include { SANITY_CHECK_VCFANNO_DATABASES } from '../modules/local/sanity_check_vcfanno_databases/main' // // SUBWORKFLOWS // -include { ALIGN } from '../subworkflows/local/align' -include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_ME } from '../subworkflows/local/annotate_consequence_pli.nf' -include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_MT } from '../subworkflows/local/annotate_consequence_pli' -include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_SNV } from '../subworkflows/local/annotate_consequence_pli' -include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_SV } from '../subworkflows/local/annotate_consequence_pli' -include { ANNOTATE_GENOME_SNVS } from '../subworkflows/local/annotate_genome_snvs' -include { ANNOTATE_MOBILE_ELEMENTS } from '../subworkflows/local/annotate_mobile_elements' -include { ANNOTATE_MT_SNVS } from '../subworkflows/local/annotate_mt_snvs' -include { ANNOTATE_STRUCTURAL_VARIANTS } from '../subworkflows/local/annotate_structural_variants' -include { CALL_MOBILE_ELEMENTS } from '../subworkflows/local/call_mobile_elements' -include { CALL_REPEAT_EXPANSIONS } from '../subworkflows/local/call_repeat_expansions' -include { CALL_SNV } from '../subworkflows/local/call_snv' -include { CALL_STRUCTURAL_VARIANTS } from '../subworkflows/local/call_structural_variants' -include { GENERATE_CLINICAL_SET as GENERATE_CLINICAL_SET_ME } from '../subworkflows/local/generate_clinical_set.nf' -include { GENERATE_CLINICAL_SET as GENERATE_CLINICAL_SET_MT } from '../subworkflows/local/generate_clinical_set' -include { GENERATE_CLINICAL_SET as GENERATE_CLINICAL_SET_SNV } from '../subworkflows/local/generate_clinical_set' -include { GENERATE_CLINICAL_SET as GENERATE_CLINICAL_SET_SV } from '../subworkflows/local/generate_clinical_set' -include { GENERATE_CYTOSURE_FILES } from '../subworkflows/local/generate_cytosure_files' -include { GENS } from '../subworkflows/local/gens' -include { PREPARE_REFERENCES } from '../subworkflows/local/prepare_references' -include { QC_BAM } from '../subworkflows/local/qc_bam' -include { RANK_VARIANTS as RANK_VARIANTS_MT } from '../subworkflows/local/rank_variants' -include { RANK_VARIANTS as RANK_VARIANTS_SNV } from '../subworkflows/local/rank_variants' -include { RANK_VARIANTS as RANK_VARIANTS_SV } from '../subworkflows/local/rank_variants' -include { SCATTER_GENOME } from '../subworkflows/local/scatter_genome' -include { SUBSAMPLE_MT } from '../subworkflows/local/subsample_mt' -include { VARIANT_EVALUATION } from '../subworkflows/local/variant_evaluation' +include { ALIGN } from '../subworkflows/local/align' +include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_ME } from '../subworkflows/local/annotate_consequence_pli' +include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_MT } from '../subworkflows/local/annotate_consequence_pli' +include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_SNV } from '../subworkflows/local/annotate_consequence_pli' +include { ANNOTATE_CSQ_PLI as ANN_CSQ_PLI_SV } from '../subworkflows/local/annotate_consequence_pli' +include { ANNOTATE_GENOME_SNVS } from '../subworkflows/local/annotate_genome_snvs' +include { ANNOTATE_MOBILE_ELEMENTS } from '../subworkflows/local/annotate_mobile_elements' +include { ANNOTATE_MT_SNVS } from '../subworkflows/local/annotate_mt_snvs' +include { ANNOTATE_STRUCTURAL_VARIANTS } from '../subworkflows/local/annotate_structural_variants' +include { CALL_MOBILE_ELEMENTS } from '../subworkflows/local/call_mobile_elements' +include { CALL_REPEAT_EXPANSIONS } from '../subworkflows/local/call_repeat_expansions' +include { CALL_SNV } from '../subworkflows/local/call_snv' +include { CALL_STRUCTURAL_VARIANTS } from '../subworkflows/local/call_structural_variants' +include { CONTAMINATION_CHECK } from '../subworkflows/local/contamination_check/main' +include { GENERATE_CYTOSURE_FILES } from '../subworkflows/local/generate_cytosure_files' +include { GENS } from '../subworkflows/local/gens' +include { PREPARE_REFERENCES } from '../subworkflows/local/prepare_references' +include { QC_BAM } from '../subworkflows/local/qc_bam' +include { RANK_VARIANTS as RANK_VARIANTS_MT } from '../subworkflows/local/rank_variants' +include { RANK_VARIANTS as RANK_VARIANTS_SNV } from '../subworkflows/local/rank_variants' +include { RANK_VARIANTS as RANK_VARIANTS_SV } from '../subworkflows/local/rank_variants' +include { SUBSAMPLE_MT_FRAC } from '../subworkflows/local/subsample_mt_frac' +include { SUBSAMPLE_MT_READS } from '../subworkflows/local/subsample_mt_reads' +include { VARIANT_EVALUATION } from '../subworkflows/local/variant_evaluation' +include { VCF_FILTER_BCFTOOLS_FILTERVEP as GENERATE_CLINICAL_SET_ME } from '../subworkflows/local/vcf_filter_bcftools_filtervep' +include { VCF_FILTER_BCFTOOLS_FILTERVEP as GENERATE_CLINICAL_SET_MT } from '../subworkflows/local/vcf_filter_bcftools_filtervep' +include { VCF_FILTER_BCFTOOLS_FILTERVEP as GENERATE_CLINICAL_SET_SNV } from '../subworkflows/local/vcf_filter_bcftools_filtervep' +include { VCF_FILTER_BCFTOOLS_FILTERVEP as GENERATE_CLINICAL_SET_SV } from '../subworkflows/local/vcf_filter_bcftools_filtervep' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -78,268 +79,268 @@ include { VARIANT_EVALUATION } from '../subworkf workflow RAREDISEASE { take: - ch_reads ch_alignments - ch_samples + ch_bait_intervals + ch_cadd_header + ch_cadd_prescored + ch_cadd_resources + ch_call_interval ch_case_info + ch_dbsnp + ch_dbsnp_tbi + ch_foundin_header + ch_gcnvcaller_model + ch_genome_bwafastalignindex + ch_genome_bwaindex + ch_genome_bwamem2index + ch_genome_bwamemeindex + ch_genome_chrsizes + ch_genome_dictionary + ch_genome_fai + ch_genome_fasta + ch_genome_hisat2index + ch_gens_gnomad_pos + ch_gens_interval_list + ch_gens_pon_female + ch_gens_pon_male + ch_gnomad_af + ch_hgnc_ids + ch_intervals_wgs + ch_intervals_y + ch_manta_regions + ch_me_references + ch_me_svdb_resources + ch_ml_model + ch_mt_bwaindex + ch_mt_bwamem2index + ch_mt_dictionary + ch_mt_fai + ch_mt_fasta + ch_mt_intervals + ch_mt_lastdb + ch_mtshift_backchain + ch_mtshift_bwaindex + ch_mtshift_bwamem2index + ch_mtshift_dictionary + ch_mtshift_fai + ch_mtshift_fasta + ch_mtshift_intervals + ch_ngsbits_method + ch_par_bed + ch_pedfile + ch_ploidy_model + ch_readcount_intervals + ch_reads + ch_reduced_penetrance + ch_rtg_truthvcfs + ch_sambamba_bed + ch_sample_id_map + ch_samples + ch_scatter_genome_split_intervals + ch_score_config_mt + ch_score_config_snv + ch_score_config_sv + ch_sdf + ch_sentieon_pcr_indel_model + ch_subdepth + ch_svcaller_priority + ch_svd_bed + ch_svd_mu + ch_svd_ud + ch_svdb_bedpedbs + ch_svdb_dbs + ch_target_bed + ch_target_intervals + ch_variant_catalog + ch_variant_consequences_snv + ch_variant_consequences_sv + ch_vcf2cytosure_blacklist + ch_vcfanno_extra + ch_vcfanno_lua + ch_vcfanno_resources + ch_vcfanno_toml + ch_vep_cache + ch_vep_extra_files + ch_versions + skip_me_calling + skip_me_annotation + skip_mt_annotation + skip_mt_subsample + skip_repeat_annotation + skip_repeat_calling + skip_snv_annotation + skip_snv_calling + skip_sv_annotation + skip_sv_calling + skip_generate_clinical_set + skip_fastp + skip_fastqc + skip_gens + skip_germlinecnvcaller + skip_mitosalt + skip_ngsbits + skip_peddy + skip_smncopynumbercaller + skip_vcf2cytosure + val_aligner + val_analysis_type + val_cadd_resources + val_concatenate_snv_calls + val_skip_split_multiallelics + val_exclude_alt + val_extract_alignments + val_genome + val_heavy_strand_origin_end + val_heavy_strand_origin_start + val_homoplasmy_af_threshold + val_light_strand_origin_end + val_light_strand_origin_start + val_mito_length + val_mito_name + val_mitosalt_breakspan + val_mitosalt_breakthreshold + val_mitosalt_cluster_threshold + val_mitosalt_deletion_threshold_max + val_mitosalt_deletion_threshold_min + val_mitosalt_evalue_threshold + val_mitosalt_exclude + val_mitosalt_flank + val_mitosalt_heteroplasmy_limit + val_mitosalt_paired_distance + val_mitosalt_score_threshold + val_mitosalt_sizelimit + val_mitosalt_split_distance_threshold + val_mitosalt_split_length + val_mt_aligner + val_mt_subsample_approach + val_mt_subsample_rd + val_mt_subsample_seed + val_multiqc_config + val_multiqc_logo + val_multiqc_methods_description + val_multiqc_samples + val_outdir + val_platform + val_run_mt_for_wes + val_run_rtgvcfeval + val_run_vcfanno_db_sanity_check + val_sample_id_map + val_save_all_mapped_as_cram + val_save_noalt_mapped_as_cram + val_svdb_query_bedpedbs + val_svdb_query_dbs + val_target_bed + val_variant_caller + val_vep_cache_version + skip_contamination + ch_contamination_sites + ch_intervals_contamination main: - ch_versions = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_mt_txt = Channel.empty() - - // - // Initialize file channels for PREPARE_REFERENCES subworkflow - // - ch_genome_fasta = Channel.fromPath(params.fasta).map { it -> [[id:it.simpleName], it] }.collect() - ch_genome_fai = params.fai ? Channel.fromPath(params.fai).map {it -> [[id:it.simpleName], it]}.collect() - : Channel.empty() - ch_genome_dictionary = params.sequence_dictionary ? Channel.fromPath(params.sequence_dictionary).map {it -> [[id:it.simpleName], it]}.collect() - : Channel.empty() - ch_gnomad_af_tab = params.gnomad_af ? Channel.fromPath(params.gnomad_af).map{ it -> [[id:it.simpleName], it] }.collect() - : Channel.value([[],[]]) - ch_dbsnp = params.known_dbsnp ? Channel.fromPath(params.known_dbsnp).map{ it -> [[id:it.simpleName], it] }.collect() - : Channel.value([[],[]]) - ch_mt_fasta = params.mt_fasta ? Channel.fromPath(params.mt_fasta).map { it -> [[id:it.simpleName], it] }.collect() - : Channel.empty() - ch_target_bed_unprocessed = params.target_bed ? Channel.fromPath(params.target_bed).map{ it -> [[id:it.simpleName], it] }.collect() - : Channel.value([[],[]]) - ch_vcfanno_extra_unprocessed = params.vcfanno_extra_resources ? Channel.fromPath(params.vcfanno_extra_resources).map { it -> [[id:it.baseName], it] }.collect() - : Channel.empty() - ch_vep_cache_unprocessed = params.vep_cache ? Channel.fromPath(params.vep_cache).map { it -> [[id:'vep_cache'], it] }.collect() - : Channel.value([[],[]]) - - // - // Prepare references and indices. - // - PREPARE_REFERENCES ( - ch_genome_fasta, - ch_genome_fai, - ch_genome_dictionary, - ch_mt_fasta, - ch_gnomad_af_tab, - ch_dbsnp, - ch_target_bed_unprocessed, - ch_vcfanno_extra_unprocessed, - ch_vep_cache_unprocessed - ) - .set { ch_references } - - // - // Gather built indices or get them from the params - // - ch_bait_intervals = ch_references.bait_intervals - ch_cadd_header = Channel.fromPath("$projectDir/assets/cadd_to_vcf_header_-1.0-.txt", checkIfExists: true).collect() - ch_cadd_resources = params.cadd_resources ? Channel.fromPath(params.cadd_resources).collect() - : Channel.value([]) - ch_call_interval = params.call_interval ? Channel.fromPath(params.call_interval).map {it -> [[id:it.simpleName], it]}.collect() - : Channel.value([[:],[]]) - ch_dbsnp_tbi = params.known_dbsnp_tbi ? Channel.fromPath(params.known_dbsnp_tbi).map {it -> [[id:it.simpleName], it]}.collect() - : ch_references.known_dbsnp_tbi.ifEmpty([[],[]]) - ch_foundin_header = Channel.fromPath("$projectDir/assets/foundin.hdr", checkIfExists: true).collect() - ch_gcnvcaller_model = params.gcnvcaller_model ? Channel.fromPath(params.gcnvcaller_model).splitCsv ( header:true ) - .map { row -> - return [[id:file(row.models).simpleName], row.models] - } - : Channel.empty() - ch_genome_bwaindex = params.bwa ? Channel.fromPath(params.bwa).map {it -> [[id:it.simpleName], it]}.collect() - : ch_references.genome_bwa_index - ch_genome_bwamem2index = params.bwamem2 ? Channel.fromPath(params.bwamem2).map {it -> [[id:it.simpleName], it]}.collect() - : ch_references.genome_bwamem2_index - ch_genome_bwamemeindex = params.bwameme ? Channel.fromPath(params.bwameme).map {it -> [[id:it.simpleName], it]}.collect() - : ch_references.genome_bwameme_index - ch_genome_chrsizes = ch_references.genome_chrom_sizes - ch_genome_fai = ch_references.genome_fai - ch_genome_dictionary = ch_references.genome_dict - ch_gens_gnomad_pos = params.gens_gnomad_pos ? Channel.fromPath(params.gens_gnomad_pos).collect() - : Channel.empty() - ch_gens_interval_list = params.gens_interval_list ? Channel.fromPath(params.gens_interval_list).collect() - : Channel.empty() - ch_gens_pon_female = params.gens_pon_female ? Channel.fromPath(params.gens_pon_female).map { it -> [ [id:it.simpleName], it ] }.collect() - : Channel.empty() - ch_gens_pon_male = params.gens_pon_male ? Channel.fromPath(params.gens_pon_male).map { it -> [ [id:it.simpleName], it ] }.collect() - : Channel.empty() - ch_gnomad_afidx = params.gnomad_af_idx ? Channel.fromPath(params.gnomad_af_idx).collect() - : ch_references.gnomad_af_idx - ch_gnomad_af = params.gnomad_af ? ch_gnomad_af_tab.join(ch_gnomad_afidx).map {meta, tab, idx -> [tab,idx]}.collect() - : Channel.empty() - ch_intervals_wgs = params.intervals_wgs ? Channel.fromPath(params.intervals_wgs).collect() - : Channel.empty() - ch_intervals_y = params.intervals_y ? Channel.fromPath(params.intervals_y).collect() - : Channel.empty() - ch_me_references = params.mobile_element_references ? Channel.fromList(samplesheetToList(params.mobile_element_references, "${projectDir}/assets/mobile_element_references_schema.json")) - : Channel.empty() - ch_me_svdb_resources = params.mobile_element_svdb_annotations ? Channel.fromPath(params.mobile_element_svdb_annotations) - : Channel.empty() - ch_ml_model = params.variant_caller.equals("sentieon") ? Channel.fromPath(params.ml_model).map {it -> [[id:it.simpleName], it]}.collect() - : Channel.value([[:],[]]) - ch_mt_intervals = ch_references.mt_intervals - ch_mt_bwaindex = ch_references.mt_bwa_index - ch_mt_bwamem2index = ch_references.mt_bwamem2_index - ch_mt_dictionary = ch_references.mt_dict - ch_mt_fai = ch_references.mt_fai - ch_mt_fasta = ch_references.mt_fasta - ch_mtshift_backchain = ch_references.mtshift_backchain - ch_mtshift_bwaindex = ch_references.mtshift_bwa_index - ch_mtshift_bwamem2index = ch_references.mtshift_bwamem2_index - ch_mtshift_dictionary = ch_references.mtshift_dict - ch_mtshift_fai = ch_references.mtshift_fai - ch_mtshift_fasta = ch_references.mtshift_fasta - ch_mtshift_intervals = ch_references.mtshift_intervals - ch_par_bed = params.par_bed ? Channel.fromPath(params.par_bed).map{ it -> [[id:'par_bed'], it] }.collect() - : Channel.value([[],[]]) - ch_ploidy_model = params.ploidy_model ? Channel.fromPath(params.ploidy_model).map{ it -> [[id:it.simpleName], it] }.collect() - : Channel.empty() - ch_readcount_intervals = params.readcount_intervals ? Channel.fromPath(params.readcount_intervals).collect() - : Channel.empty() - ch_reduced_penetrance = params.reduced_penetrance ? Channel.fromPath(params.reduced_penetrance).collect() - : Channel.value([]) - ch_rtg_truthvcfs = params.rtg_truthvcfs ? Channel.fromPath(params.rtg_truthvcfs).collect() - : Channel.value([]) - ch_sample_id_map = params.sample_id_map ? Channel.fromList(samplesheetToList(params.sample_id_map, "${projectDir}/assets/sample_id_map.json")) - : Channel.empty() - ch_score_config_mt = params.score_config_mt ? Channel.fromPath(params.score_config_mt).collect() - : Channel.value([]) - ch_score_config_snv = params.score_config_snv ? Channel.fromPath(params.score_config_snv).collect() - : Channel.value([]) - ch_score_config_sv = params.score_config_sv ? Channel.fromPath(params.score_config_sv).collect() - : Channel.value([]) - ch_sdf = params.sdf ? Channel.fromPath(params.sdf).map{it -> [[id:it.simpleName],it]}.collect() - : ch_references.sdf - ch_sv_dbs = params.svdb_query_dbs ? Channel.fromPath(params.svdb_query_dbs) - : Channel.empty() - ch_sv_bedpedbs = params.svdb_query_bedpedbs ? Channel.fromPath(params.svdb_query_bedpedbs) - : Channel.empty() - ch_svd_bed = params.verifybamid_svd_bed ? Channel.fromPath(params.verifybamid_svd_bed) - : Channel.empty() - ch_svd_mu = params.verifybamid_svd_mu ? Channel.fromPath(params.verifybamid_svd_mu) - : Channel.empty() - ch_svd_ud = params.verifybamid_svd_ud ? Channel.fromPath(params.verifybamid_svd_ud) - : Channel.empty() - ch_target_bed = ch_references.target_bed - ch_target_intervals = ch_references.target_intervals - ch_variant_catalog = params.variant_catalog ? Channel.fromPath(params.variant_catalog).map { it -> [[id:it.simpleName],it]}.collect() - : Channel.value([[],[]]) - ch_variant_consequences_snv = params.variant_consequences_snv ? Channel.fromPath(params.variant_consequences_snv).collect() - : Channel.value([]) - ch_variant_consequences_sv = params.variant_consequences_sv ? Channel.fromPath(params.variant_consequences_sv).collect() - : Channel.value([]) - ch_vcfanno_extra = ch_references.vcfanno_extra - ch_vcfanno_resources = params.vcfanno_resources ? Channel.fromPath(params.vcfanno_resources).splitText().map{it -> it.trim()}.collect() - : Channel.value([]) - ch_vcf2cytosure_blacklist = params.vcf2cytosure_blacklist ? Channel.fromPath(params.vcf2cytosure_blacklist).collect() - : Channel.value([]) - ch_vcfanno_lua = params.vcfanno_lua ? Channel.fromPath(params.vcfanno_lua).collect() - : Channel.value([]) - ch_vcfanno_toml = params.vcfanno_toml ? Channel.fromPath(params.vcfanno_toml).collect() - : Channel.value([]) - ch_vep_cache = ( params.vep_cache && params.vep_cache.endsWith("tar.gz") ) ? ch_references.vep_resources - : ( params.vep_cache ? Channel.fromPath(params.vep_cache).collect() : Channel.value([]) ) - ch_vep_extra_files_unsplit = params.vep_plugin_files ? Channel.fromPath(params.vep_plugin_files).collect() - : Channel.value([]) - ch_vep_filters_std_fmt = params.vep_filters ? Channel.fromPath(params.vep_filters).map { it -> [[id:'standard'],it]}.collect() - : Channel.empty() - ch_vep_filters_scout_fmt = params.vep_filters_scout_fmt ? Channel.fromPath(params.vep_filters_scout_fmt).map { it -> [[id:'scout'],it]}.collect() - : Channel.empty() - ch_versions = ch_versions.mix(ch_references.versions) - - // - // SV caller priority - // - if (params.skip_tools && params.skip_tools.split(',').contains('germlinecnvcaller')) { - if (params.analysis_type.equals("wgs")) { - ch_svcaller_priority = Channel.value(["tiddit", "manta", "cnvnator"]) - } else { - ch_svcaller_priority = Channel.value([]) - } - } else { - if (params.analysis_type.equals("wgs")) { - ch_svcaller_priority = Channel.value(["tiddit", "manta", "gcnvcaller", "cnvnator"]) - } else { - ch_svcaller_priority = Channel.value(["manta", "gcnvcaller"]) - } - } - - // - // Generate pedigree file - // - ch_pedfile = CREATE_PEDIGREE_FILE(ch_samples.toList()).ped - ch_versions = ch_versions.mix(CREATE_PEDIGREE_FILE.out.versions) - - // - // Read and store paths in the vep_plugin_files file - // - ch_vep_extra_files = Channel.empty() - if (params.vep_plugin_files) { - ch_vep_extra_files_unsplit.splitCsv ( header:true ) - .map { row -> - def f = file(row.vep_files[0]) - if(f.isFile() || f.isDirectory()){ - return [f] - } else { - error("\nVep database file ${f} does not exist.") - } - } - .collect() - .set {ch_vep_extra_files} - } - - // - // Dump all HGNC ids in a file - // - ch_vep_filters_scout_fmt - .mix (ch_vep_filters_std_fmt) - .set {ch_vep_filters} - - CREATE_HGNCIDS_FILE(ch_vep_filters) - .txt - .set {ch_hgnc_ids} + ch_multiqc_files = channel.empty() + ch_align_fastp_out = channel.empty() + ch_align_genome_marked_cram = channel.empty() + ch_align_genome_marked_crai = channel.empty() + ch_align_genome_marked_bam = channel.empty() + ch_align_genome_marked_bai = channel.empty() + ch_align_markdup_metrics = channel.empty() + ch_subsample_mt_bam = channel.empty() + ch_subsample_mt_bai = channel.empty() + ch_call_snv_publish = channel.empty() + ch_call_sv_vcf = channel.empty() + ch_call_sv_tbi = channel.empty() + ch_mt_del_result = channel.empty() + ch_saltshaker_html = channel.empty() + ch_saltshaker_plot = channel.empty() + ch_call_snv_bcftools_concat_csi = channel.empty() + ch_call_snv_bcftools_concat_tbi = channel.empty() + ch_call_snv_bcftools_concat_vcf = channel.empty() + ch_call_snv_deepvariant_report = channel.empty() + ch_call_snv_genome_tabix = channel.empty() + ch_call_snv_genome_vcf = channel.empty() + ch_call_snv_mt_tabix = channel.empty() + ch_call_snv_mt_vcf = channel.empty() + ch_call_sv_publish = channel.empty() + ch_call_repeat_expansions_expansionhunter_bai = channel.empty() + ch_call_repeat_expansions_expansionhunter_bam = channel.empty() + ch_call_repeat_expansions_expansionhunter_vcf = channel.empty() + ch_call_repeat_expansions_stranger_tbi = channel.empty() + ch_call_repeat_expansions_stranger_vcf = channel.empty() + ch_call_mobile_elements_tbi = channel.empty() + ch_call_mobile_elements_vcf = channel.empty() + ch_ann_csq_pli_me_tbi = channel.empty() + ch_ann_csq_pli_me_vcf_ann = channel.empty() + ch_annotate_genome_snvs_bcftools_concat_tbi = channel.empty() + ch_annotate_genome_snvs_bcftools_concat_vcf = channel.empty() + ch_annotate_genome_snvs_chromograph_autozyg_plots = channel.empty() + ch_annotate_genome_snvs_chromograph_regions_plots = channel.empty() + ch_annotate_genome_snvs_chromograph_sites_plots = channel.empty() + ch_annotate_genome_snvs_rhocall_viz_bed = channel.empty() + ch_annotate_genome_snvs_rhocall_viz_wig = channel.empty() + ch_annotate_genome_snvs_ucsc_wigtobigwig_bw = channel.empty() + ch_annotate_mt_snvs_ensemblvep_mt_tbi = channel.empty() + ch_annotate_mt_snvs_ensemblvep_mt_vcf = channel.empty() + ch_annotate_sv_publish = channel.empty() + ch_generate_cytosure_files_cgh = channel.empty() + ch_gens_baf_bed_gz = channel.empty() + ch_gens_baf_bed_tbi = channel.empty() + ch_gens_cov_bed_gz = channel.empty() + ch_gens_cov_bed_tbi = channel.empty() + ch_fastqc_publish = channel.empty() + ch_smncopynumbercaller_publish = channel.empty() + ch_peddy_publish = channel.empty() + ch_multiqc_publish = channel.empty() + ch_rank_snv_tbi = channel.empty() + ch_rank_snv_vcf = channel.empty() + ch_rank_mt_tbi = channel.empty() + ch_rank_mt_vcf = channel.empty() + ch_rank_sv_tbi = channel.empty() + ch_rank_sv_vcf = channel.empty() + ch_variant_evaluation_baseline_tbi = channel.empty() + ch_variant_evaluation_baseline_vcf = channel.empty() + ch_variant_evaluation_false_negatives_tbi = channel.empty() + ch_variant_evaluation_false_negatives_vcf = channel.empty() + ch_variant_evaluation_false_positives_tbi = channel.empty() + ch_variant_evaluation_false_positives_vcf = channel.empty() + ch_variant_evaluation_non_snp_roc = channel.empty() + ch_variant_evaluation_phasing = channel.empty() + ch_variant_evaluation_snp_roc = channel.empty() + ch_variant_evaluation_summary = channel.empty() + ch_variant_evaluation_true_positives_tbi = channel.empty() + ch_variant_evaluation_true_positives_vcf = channel.empty() + ch_variant_evaluation_weighted_roc = channel.empty() // // Input QC (ch_reads will be empty if fastq input isn't provided so FASTQC won't run if input is not fastq) // - ch_input_by_sample_type = ch_reads.branch{ - fastq_gz: it[0].data_type == "fastq_gz" - interleaved_spring: it[0].data_type == "interleaved_spring" - separate_spring: it[0].data_type == "separate_spring" + ch_input_by_sample_type = ch_reads.branch{ meta, _reads -> + fastq_gz: meta.data_type == "fastq_gz" + interleaved_spring: meta.data_type == "interleaved_spring" + separate_spring: meta.data_type == "separate_spring" } // Just one fastq.gz.spring-file with both R1 and R2 ch_one_fastq_gz_pair_from_spring = SPRING_DECOMPRESS_TO_FQ_PAIR(ch_input_by_sample_type.interleaved_spring, false).fastq - ch_versions = ch_versions.mix(SPRING_DECOMPRESS_TO_FQ_PAIR.out.versions.first()) // Two fastq.gz.spring-files - one for R1 and one for R2 ch_r1_fastq_gz_from_spring = SPRING_DECOMPRESS_TO_R1_FQ(ch_input_by_sample_type.separate_spring.map{ meta, files -> [meta, files[0] ]}, true).fastq ch_r2_fastq_gz_from_spring = SPRING_DECOMPRESS_TO_R2_FQ(ch_input_by_sample_type.separate_spring.map{ meta, files -> [meta, files[1] ]}, true).fastq ch_two_fastq_gz_from_spring = ch_r1_fastq_gz_from_spring.join(ch_r2_fastq_gz_from_spring).map{ meta, fastq_1, fastq_2 -> [meta, [fastq_1, fastq_2]]} - ch_versions = ch_versions.mix(SPRING_DECOMPRESS_TO_R1_FQ.out.versions.first()) - ch_versions = ch_versions.mix(SPRING_DECOMPRESS_TO_R2_FQ.out.versions.first()) ch_input_fastqs = ch_input_by_sample_type.fastq_gz.mix(ch_one_fastq_gz_pair_from_spring).mix(ch_two_fastq_gz_from_spring) - // - // Create chromosome bed and intervals for splitting and gathering operations - // - ch_scatter_split_intervals = Channel.empty() - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('snv_annotation'))) { - SCATTER_GENOME ( - ch_genome_dictionary, - ch_genome_fai, - ch_genome_fasta - ).split_intervals - .set { ch_scatter_split_intervals } - } - // // Input QC (ch_reads will be empty if fastq input isn't provided so FASTQC won't run if input is nott fastq) // - if (!(params.skip_tools && params.skip_tools.split(',').contains('fastqc'))) { + if (!skip_fastqc) { FASTQC (ch_input_fastqs) fastqc_report = FASTQC.out.zip - ch_versions = ch_versions.mix(FASTQC.out.versions.first()) + ch_fastqc_publish = FASTQC.out.html + .mix(FASTQC.out.zip) + .map { meta, value -> ["fastqc/${meta.id}/", [meta, value]] } } /* @@ -349,14 +350,15 @@ workflow RAREDISEASE { */ ALIGN ( - ch_input_fastqs, ch_alignments, - ch_genome_fasta, - ch_genome_fai, + ch_genome_bwafastalignindex, ch_genome_bwaindex, ch_genome_bwamem2index, ch_genome_bwamemeindex, ch_genome_dictionary, + ch_genome_fai, + ch_genome_fasta, + ch_input_fastqs, ch_mt_bwaindex, ch_mt_bwamem2index, ch_mt_dictionary, @@ -367,54 +369,105 @@ workflow RAREDISEASE { ch_mtshift_dictionary, ch_mtshift_fai, ch_mtshift_fasta, - params.mbuffer_mem, - params.platform, - params.samtools_sort_threads + skip_fastp, + val_aligner, + val_analysis_type, + val_exclude_alt, + val_extract_alignments, + val_mt_aligner, + val_platform, + val_run_mt_for_wes, + val_save_all_mapped_as_cram, + val_save_noalt_mapped_as_cram ) .set { ch_mapped } - ch_versions = ch_versions.mix(ALIGN.out.versions) - - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('mt_subsample')) && (params.analysis_type.equals("wgs") || params.run_mt_for_wes)) { - SUBSAMPLE_MT( - ch_mapped.mt_bam_bai, - params.mt_subsample_rd, - params.mt_subsample_seed - ) - ch_versions = ch_versions.mix(SUBSAMPLE_MT.out.versions) + ch_align_fastp_out = ALIGN.out.fastp_out + ch_align_genome_marked_bam = ALIGN.out.genome_marked_bam + ch_align_genome_marked_bai = ALIGN.out.genome_marked_bai + ch_align_genome_marked_cram = ALIGN.out.genome_marked_cram + ch_align_genome_marked_crai = ALIGN.out.genome_marked_crai + ch_align_markdup_metrics = ALIGN.out.markdup_metrics + + if (!(skip_mt_subsample) && (val_analysis_type.equals("wgs") || val_run_mt_for_wes)) { + if (val_mt_subsample_approach.equals("fraction")) { + SUBSAMPLE_MT_FRAC( + ch_mapped.mt_bam_bai, + val_mt_subsample_rd, + val_mt_subsample_seed + ) + ch_subsample_mt_bam = SUBSAMPLE_MT_FRAC.out.bam + ch_subsample_mt_bai = SUBSAMPLE_MT_FRAC.out.bai + } else { + SUBSAMPLE_MT_READS( + ch_mapped.mt_bam_bai, + ) + ch_subsample_mt_bam = SUBSAMPLE_MT_READS.out.bam + ch_subsample_mt_bai = SUBSAMPLE_MT_READS.out.bai + } } // // BAM QUALITY CHECK // QC_BAM ( - ch_mapped.genome_marked_bam, - ch_mapped.genome_marked_bai, - ch_mapped.genome_bam_bai, - ch_genome_fasta, - ch_genome_fai, + ch_mapped.genome_marked_bam_bai, ch_bait_intervals, - ch_target_intervals, ch_genome_chrsizes, + ch_genome_fai, + ch_genome_fasta, ch_intervals_wgs, ch_intervals_y, + ch_ngsbits_method, ch_svd_bed, ch_svd_mu, ch_svd_ud, - Channel.value(params.ngsbits_samplegender_method) + ch_sambamba_bed, + ch_target_intervals, + val_analysis_type, + val_aligner, + val_target_bed, + skip_ngsbits ) - ch_versions = ch_versions.mix(QC_BAM.out.versions) + // + // SUBWORKFLOW: Check for contamination using GATK + // + ch_contamination_mqc = Channel.empty() + ch_contamination_table = Channel.empty() + ch_contamination_pileup = Channel.empty() + + if (!skip_contamination) { + + // Prepare BAM input with BAI + ch_bam_for_contamination = ch_mapped.genome_marked_bam + .join(ch_mapped.genome_marked_bai, failOnMismatch:true, failOnDuplicate:true) + + CONTAMINATION_CHECK ( + ch_bam_for_contamination, + ch_genome_fasta, + ch_genome_fai, + ch_genome_dictionary, + ch_contamination_sites, + ch_intervals_contamination + ) + + // Parse for MultiQC + PARSE_CONTAMINATION ( + CONTAMINATION_CHECK.out.contamination_table + ) + ch_contamination_mqc = PARSE_CONTAMINATION.out.mqc_table + ch_contamination_table = CONTAMINATION_CHECK.out.contamination_table + ch_contamination_pileup = CONTAMINATION_CHECK.out.pileup_table + } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RENAME ALIGNMENT FILES FOR SMNCOPYNUMBERCALLER & REPEATCALLING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if ( params.analysis_type.equals("wgs") && (!(params.skip_tools && params.skip_tools.split(',').contains('smncopynumbercaller')) || !(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('repeat_calling')))) { + if ( val_analysis_type.equals("wgs") && (!skip_smncopynumbercaller || !skip_repeat_calling)) { RENAME_BAM(ch_mapped.genome_marked_bam, "bam") RENAME_BAI(ch_mapped.genome_marked_bai, "bam.bai") - ch_versions = ch_versions.mix(RENAME_BAM.out.versions) - ch_versions = ch_versions.mix(RENAME_BAI.out.versions) } /* @@ -423,7 +476,7 @@ workflow RAREDISEASE { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('repeat_calling')) && params.analysis_type.equals("wgs") ) { + if (!skip_repeat_calling && val_analysis_type.equals("wgs") ) { CALL_REPEAT_EXPANSIONS ( RENAME_BAM.out.output.join(RENAME_BAI.out.output, failOnMismatch:true, failOnDuplicate:true), ch_variant_catalog, @@ -431,14 +484,17 @@ workflow RAREDISEASE { ch_genome_fasta, ch_genome_fai ) - ch_versions = ch_versions.mix(CALL_REPEAT_EXPANSIONS.out.versions) + ch_call_repeat_expansions_expansionhunter_bai = CALL_REPEAT_EXPANSIONS.out.expansionhunter_bai + ch_call_repeat_expansions_expansionhunter_bam = CALL_REPEAT_EXPANSIONS.out.expansionhunter_bam + ch_call_repeat_expansions_expansionhunter_vcf = CALL_REPEAT_EXPANSIONS.out.expansionhunter_vcf - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('repeat_annotation'))) { + if (!skip_repeat_annotation) { STRANGER ( CALL_REPEAT_EXPANSIONS.out.vcf, ch_variant_catalog ) - ch_versions = ch_versions.mix(STRANGER.out.versions) + ch_call_repeat_expansions_stranger_vcf = STRANGER.out.vcf + ch_call_repeat_expansions_stranger_tbi = STRANGER.out.tbi } } @@ -449,129 +505,166 @@ workflow RAREDISEASE { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('snv_calling'))) { + if (!skip_snv_calling) { CALL_SNV ( - ch_mapped.genome_bam_bai, - ch_mapped.mt_bam_bai, - ch_mapped.mtshift_bam_bai, + ch_call_interval, + ch_case_info, + ch_dbsnp, + ch_dbsnp_tbi, + ch_foundin_header, + ch_mapped.genome_marked_bam_bai, ch_genome_chrsizes, ch_genome_fasta, ch_genome_fai, - ch_genome_dictionary, - ch_mt_intervals, + ch_ml_model, + ch_mapped.mt_bam_bai_gatksubwf, ch_mt_dictionary, ch_mt_fai, ch_mt_fasta, + ch_mt_intervals, + ch_mapped.mtshift_bam_bai_gatksubwf, ch_mtshift_dictionary, ch_mtshift_fai, ch_mtshift_fasta, ch_mtshift_intervals, ch_mtshift_backchain, - ch_dbsnp, - ch_dbsnp_tbi, - ch_call_interval, - ch_target_bed, - ch_ml_model, ch_par_bed, - ch_case_info, - ch_foundin_header, - Channel.value(params.sentieon_dnascope_pcr_indel_model) + ch_sentieon_pcr_indel_model, + ch_target_bed, + val_analysis_type, + val_concatenate_snv_calls, + val_run_mt_for_wes, + val_skip_split_multiallelics, + val_variant_caller ) - ch_versions = ch_versions.mix(CALL_SNV.out.versions) - ch_mt_txt = CALL_SNV.out.mt_txt + ch_call_snv_bcftools_concat_csi = CALL_SNV.out.bcftools_concat_csi + ch_call_snv_bcftools_concat_tbi = CALL_SNV.out.bcftools_concat_tbi + ch_call_snv_bcftools_concat_vcf = CALL_SNV.out.bcftools_concat_vcf + ch_call_snv_deepvariant_report = CALL_SNV.out.deepvariant_report + ch_call_snv_genome_tabix = CALL_SNV.out.genome_tabix + ch_call_snv_genome_vcf = CALL_SNV.out.genome_vcf + ch_call_snv_mt_tabix = CALL_SNV.out.mt_tabix + ch_call_snv_mt_vcf = CALL_SNV.out.mt_vcf + + // Removes vcfanno resource with empty records to keep vcfanno from crashing on those files + ch_vcfanno_toml_final = ch_vcfanno_toml + if (val_run_vcfanno_db_sanity_check && (!skip_snv_annotation || (!skip_mt_annotation && (val_run_mt_for_wes || val_analysis_type.matches("wgs|mito"))))) { + ch_vcfanno_resources + .combine(ch_vcfanno_extra) + .map { files -> files.flatten() } + .set { ch_all_vcfanno_dbs } + SANITY_CHECK_VCFANNO_DATABASES (ch_vcfanno_toml, ch_all_vcfanno_dbs) + ch_vcfanno_toml_final = SANITY_CHECK_VCFANNO_DATABASES.out.toml.collect() + } // // ANNOTATE GENOME SNVs // - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('snv_annotation'))) { + if (!skip_snv_annotation) { ANNOTATE_GENOME_SNVS ( - CALL_SNV.out.genome_vcf_tabix, - params.analysis_type, ch_cadd_header, + ch_cadd_prescored, ch_cadd_resources, - ch_vcfanno_extra, - ch_vcfanno_resources, - ch_vcfanno_lua, - ch_vcfanno_toml, - params.genome, - params.vep_cache_version, - ch_vep_cache, + ch_genome_chrsizes, + ch_genome_fai, ch_genome_fasta, ch_gnomad_af, ch_samples, - ch_scatter_split_intervals, + ch_scatter_genome_split_intervals, + CALL_SNV.out.genome_vcf_tabix, + ch_vcfanno_extra, + ch_vcfanno_lua, + ch_vcfanno_resources, + ch_vcfanno_toml_final, + ch_vep_cache, ch_vep_extra_files, - ch_genome_chrsizes - ).set { ch_snv_annotate } - ch_versions = ch_versions.mix(ch_snv_annotate.versions) - - ch_snv_annotate.vcf_ann + val_analysis_type, + val_cadd_resources, + val_genome, + val_vep_cache_version + ) + ch_annotate_genome_snvs_bcftools_concat_tbi = ANNOTATE_GENOME_SNVS.out.bcftools_concat_tbi + ch_annotate_genome_snvs_bcftools_concat_vcf = ANNOTATE_GENOME_SNVS.out.bcftools_concat_vcf + ch_annotate_genome_snvs_chromograph_autozyg_plots = ANNOTATE_GENOME_SNVS.out.chromograph_autozyg_plots + ch_annotate_genome_snvs_chromograph_regions_plots = ANNOTATE_GENOME_SNVS.out.chromograph_regions_plots + ch_annotate_genome_snvs_chromograph_sites_plots = ANNOTATE_GENOME_SNVS.out.chromograph_sites_plots + ch_annotate_genome_snvs_rhocall_viz_bed = ANNOTATE_GENOME_SNVS.out.rhocall_viz_bed + ch_annotate_genome_snvs_rhocall_viz_wig = ANNOTATE_GENOME_SNVS.out.rhocall_viz_wig + ch_annotate_genome_snvs_ucsc_wigtobigwig_bw = ANNOTATE_GENOME_SNVS.out.ucsc_wigtobigwig_bw + + ch_annotate_genome_snvs_bcftools_concat_vcf .multiMap { meta, vcf -> clinical: [ meta + [ set: "clinical" ], vcf ] research: [ meta + [ set: "research" ], vcf ] } .set { ch_clin_research_snv_vcf } - ch_clinical_snv_vcf = Channel.empty() - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('generate_clinical_set'))) { + ch_clinical_snv_vcf = channel.empty() + if (!skip_generate_clinical_set) { GENERATE_CLINICAL_SET_SNV( ch_clin_research_snv_vcf.clinical, ch_hgnc_ids, - false + false, + true ) - .vcf + GENERATE_CLINICAL_SET_SNV.out.vcf .set { ch_clinical_snv_vcf } - ch_versions = ch_versions.mix(GENERATE_CLINICAL_SET_SNV.out.versions) } ch_ann_csq_snv_in = ch_clinical_snv_vcf.mix(ch_clin_research_snv_vcf.research) ANN_CSQ_PLI_SNV ( + ch_variant_consequences_snv, ch_ann_csq_snv_in, - ch_variant_consequences_snv + false ) - ch_versions = ch_versions.mix(ANN_CSQ_PLI_SNV.out.versions) ANN_CSQ_PLI_SNV.out.vcf_ann - .filter { it -> - if (it[0].probands.size()==0) { + .filter { meta, _vcf -> + if (meta.probands.size()==0) { log.warn("Skipping nuclear SNV ranking since no affected samples are detected in the case") } - it[0].probands.size()>0 + meta.probands.size()>0 } .set {ch_ranksnv_nuclear_in} RANK_VARIANTS_SNV ( - ch_ranksnv_nuclear_in, ch_pedfile, ch_reduced_penetrance, - ch_score_config_snv + ch_score_config_snv, + ch_ranksnv_nuclear_in, + false ) - ch_versions = ch_versions.mix(RANK_VARIANTS_SNV.out.versions) + ch_rank_snv_tbi = RANK_VARIANTS_SNV.out.tbi + ch_rank_snv_vcf = RANK_VARIANTS_SNV.out.vcf } // // ANNOTATE MT SNVs // - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('mt_annotation')) && (params.run_mt_for_wes || params.analysis_type.matches("wgs|mito"))) { + if (!(skip_mt_annotation) && (val_run_mt_for_wes || val_analysis_type.matches("wgs|mito"))) { ANNOTATE_MT_SNVS ( - CALL_SNV.out.mt_vcf, - CALL_SNV.out.mt_tabix, ch_cadd_header, + ch_cadd_prescored, ch_cadd_resources, ch_genome_fasta, + ch_genome_fai, + CALL_SNV.out.mt_vcf_tbi, ch_vcfanno_extra, ch_vcfanno_lua, ch_vcfanno_resources, - ch_vcfanno_toml, - params.genome, - params.vep_cache_version, + ch_vcfanno_toml_final, ch_vep_cache, - ch_vep_extra_files + ch_vep_extra_files, + val_cadd_resources, + val_genome, + val_homoplasmy_af_threshold, + val_vep_cache_version ).set { ch_mt_annotate } - ch_versions = ch_versions.mix(ch_mt_annotate.versions) + ch_annotate_mt_snvs_ensemblvep_mt_tbi = ch_mt_annotate.ensemblvep_mt_tbi + ch_annotate_mt_snvs_ensemblvep_mt_vcf = ch_mt_annotate.ensemblvep_mt_vcf ch_mt_annotate.vcf_ann .multiMap { meta, vcf -> @@ -580,88 +673,129 @@ workflow RAREDISEASE { } .set { ch_clin_research_mt_vcf } - ch_clinical_mtsnv_vcf = Channel.empty() - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('generate_clinical_set'))) { + ch_clinical_mtsnv_vcf = channel.empty() + if (!skip_generate_clinical_set) { GENERATE_CLINICAL_SET_MT( ch_clin_research_mt_vcf.clinical, ch_hgnc_ids, - true + true, + false ) - .vcf - .set { ch_clinical_mtsnv_vcf } - ch_versions = ch_versions.mix(GENERATE_CLINICAL_SET_MT.out.versions) + GENERATE_CLINICAL_SET_MT.out.vcf + .set { ch_clinical_mtsnv_vcf } } ch_ann_csq_mtsnv_in = ch_clinical_mtsnv_vcf.mix(ch_clin_research_mt_vcf.research) ANN_CSQ_PLI_MT( + ch_variant_consequences_snv, ch_ann_csq_mtsnv_in, - ch_variant_consequences_snv + false ) - ch_versions = ch_versions.mix(ANN_CSQ_PLI_MT.out.versions) ANN_CSQ_PLI_MT.out.vcf_ann - .filter { it -> - if (it[0].probands.size()==0) { + .filter { meta, _vcf -> + if (meta.probands.size()==0) { log.warn("Skipping mitochondrial SNV ranking since no affected samples are detected in the case") } - it[0].probands.size()>0 + meta.probands.size()>0 } .set {ch_ranksnv_mt_in} RANK_VARIANTS_MT ( - ch_ranksnv_mt_in, ch_pedfile, ch_reduced_penetrance, - ch_score_config_mt + ch_score_config_mt, + ch_ranksnv_mt_in, + false ) - ch_versions = ch_versions.mix(RANK_VARIANTS_MT.out.versions) + ch_rank_mt_tbi = RANK_VARIANTS_MT.out.tbi + ch_rank_mt_vcf = RANK_VARIANTS_MT.out.vcf } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - CALL AND ANNOTATE NUCLEAR SVs + CALL AND ANNOTATE NUCLEAR AND MITOCHONDRIAL SVs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('sv_calling'))) { + if (!skip_sv_calling) { + channel.of([val_mitosalt_breakspan, + val_mitosalt_breakthreshold, + val_mitosalt_cluster_threshold, + val_mitosalt_deletion_threshold_max, + val_mitosalt_deletion_threshold_min, + val_mitosalt_evalue_threshold, + val_mitosalt_exclude, + val_mitosalt_paired_distance, + val_mitosalt_score_threshold, + val_mitosalt_sizelimit, + val_mitosalt_split_distance_threshold, + val_mitosalt_split_length]) + .set{ ch_mitosalt_config } + CALL_STRUCTURAL_VARIANTS ( - ch_mapped.genome_marked_bam, - ch_mapped.genome_marked_bai, - ch_mapped.genome_bam_bai, - ch_mapped.mt_bam_bai, - ch_mapped.mtshift_bam_bai, ch_genome_bwaindex, - ch_genome_fasta, - ch_genome_fai, - ch_mtshift_fasta, ch_case_info, - ch_target_bed, + ch_gcnvcaller_model, + ch_mapped.genome_marked_bai, + ch_mapped.genome_marked_bam, + ch_mapped.genome_marked_bam_bai, + ch_genome_chrsizes, ch_genome_dictionary, - ch_svcaller_priority, - ch_readcount_intervals, + ch_genome_fai, + ch_genome_fasta, + ch_genome_hisat2index, + ch_manta_regions, + ch_mitosalt_config, + ch_mapped.mt_bam_bai, + ch_mt_fai, + ch_mt_fasta, + ch_mt_lastdb, ch_ploidy_model, - ch_gcnvcaller_model + ch_readcount_intervals, + ch_input_fastqs, + ch_sample_id_map, + ch_subdepth, + ch_svcaller_priority, + skip_germlinecnvcaller, + skip_mitosalt, + val_analysis_type, + val_heavy_strand_origin_end, + val_heavy_strand_origin_start, + val_light_strand_origin_end, + val_light_strand_origin_start, + val_mito_length, + val_mito_name, + val_mitosalt_flank, + val_mitosalt_heteroplasmy_limit, + val_run_mt_for_wes ) - ch_versions = ch_versions.mix(CALL_STRUCTURAL_VARIANTS.out.versions) + ch_call_sv_vcf = CALL_STRUCTURAL_VARIANTS.out.vcf + ch_call_sv_tbi = CALL_STRUCTURAL_VARIANTS.out.tbi + ch_saltshaker_html = CALL_STRUCTURAL_VARIANTS.out.saltshaker_html + ch_saltshaker_plot = CALL_STRUCTURAL_VARIANTS.out.saltshaker_plot + ch_mt_del_result = CALL_STRUCTURAL_VARIANTS.out.mt_del_result // // ANNOTATE STRUCTURAL VARIANTS // - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('sv_annotation'))) { + if (!skip_sv_annotation) { ANNOTATE_STRUCTURAL_VARIANTS ( - CALL_STRUCTURAL_VARIANTS.out.vcf, - ch_sv_dbs, - ch_sv_bedpedbs, - params.genome, - params.vep_cache_version, - ch_vep_cache, - ch_genome_fasta, ch_genome_dictionary, - ch_vep_extra_files + ch_genome_fasta, + ch_svdb_bedpedbs, + ch_svdb_dbs, + ch_call_sv_vcf, + ch_vep_cache, + ch_vep_extra_files, + val_svdb_query_bedpedbs, + val_svdb_query_dbs, + val_genome, + val_vep_cache_version ).set { ch_sv_annotate } - ch_versions = ch_versions.mix(ch_sv_annotate.versions) + ch_annotate_sv_publish = ch_sv_annotate.publish ch_sv_annotate.vcf_ann .multiMap { meta, vcf -> @@ -670,74 +804,75 @@ workflow RAREDISEASE { } .set { ch_clin_research_sv_vcf } - ch_clinical_sv_vcf = Channel.empty() - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('generate_clinical_set'))) { + ch_clinical_sv_vcf = channel.empty() + if (!skip_generate_clinical_set) { GENERATE_CLINICAL_SET_SV( ch_clin_research_sv_vcf.clinical, ch_hgnc_ids, - false + false, + true ) - .vcf + GENERATE_CLINICAL_SET_SV.out.vcf .set { ch_clinical_sv_vcf } - ch_versions = ch_versions.mix(GENERATE_CLINICAL_SET_SV.out.versions) } ch_ann_csq_sv_in = ch_clinical_sv_vcf.mix(ch_clin_research_sv_vcf.research) ANN_CSQ_PLI_SV ( + ch_variant_consequences_sv, ch_ann_csq_sv_in, - ch_variant_consequences_sv + false ) - ch_versions = ch_versions.mix(ANN_CSQ_PLI_SV.out.versions) ANN_CSQ_PLI_SV.out.vcf_ann - .filter { it -> - if (it[0].probands.size()==0) { + .filter { meta, _vcf -> + if (meta.probands.size()==0) { log.warn("Skipping SV ranking since no affected samples are detected in the case") } - it[0].probands.size()>0 + meta.probands.size()>0 } .set {ch_ranksnv_sv_in} RANK_VARIANTS_SV ( - ch_ranksnv_sv_in, ch_pedfile, ch_reduced_penetrance, - ch_score_config_sv + ch_score_config_sv, + ch_ranksnv_sv_in, + true ) - ch_versions = ch_versions.mix(RANK_VARIANTS_SV.out.versions) + ch_rank_sv_tbi = RANK_VARIANTS_SV.out.tbi + ch_rank_sv_vcf = RANK_VARIANTS_SV.out.vcf } } - /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CALL AND ANNOTATE MOBILE ELEMENTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('me_calling')) && params.analysis_type.equals("wgs")) { + if (!skip_me_calling && val_analysis_type.equals("wgs")) { CALL_MOBILE_ELEMENTS( - ch_mapped.genome_bam_bai, - ch_genome_fasta, - ch_genome_fai, - ch_me_references, ch_case_info, - params.genome + ch_mapped.genome_marked_bam_bai, + ch_genome_fai, + ch_genome_fasta, + ch_me_references ) - ch_versions = ch_versions.mix(CALL_MOBILE_ELEMENTS.out.versions) + ch_call_mobile_elements_vcf = CALL_MOBILE_ELEMENTS.out.vcf + ch_call_mobile_elements_tbi = CALL_MOBILE_ELEMENTS.out.tbi - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('me_annotation'))) { + if (!skip_me_annotation) { ANNOTATE_MOBILE_ELEMENTS( - CALL_MOBILE_ELEMENTS.out.vcf, - ch_me_svdb_resources, - ch_genome_fasta, ch_genome_dictionary, + ch_genome_fasta, + ch_me_svdb_resources, + CALL_MOBILE_ELEMENTS.out.vcf, ch_vep_cache, - params.genome, - params.vep_cache_version, + val_genome, + val_vep_cache_version, ch_vep_extra_files ).set { ch_me_annotate } - ch_versions = ch_versions.mix(ANNOTATE_MOBILE_ELEMENTS.out.versions) ch_me_annotate.vcf_ann .multiMap { meta, vcf -> @@ -746,25 +881,27 @@ workflow RAREDISEASE { } .set { ch_clin_research_me_vcf } - ch_clinical_me_vcf = Channel.empty() - if (!(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('generate_clinical_set'))) { + ch_clinical_me_vcf = channel.empty() + if (!skip_generate_clinical_set) { GENERATE_CLINICAL_SET_ME( ch_clin_research_me_vcf.clinical, ch_hgnc_ids, - false + false, + true ) - .vcf + GENERATE_CLINICAL_SET_ME.out.vcf .set { ch_clinical_me_vcf } - ch_versions = ch_versions.mix( GENERATE_CLINICAL_SET_ME.out.versions ) } ch_ann_csq_me_in = ch_clinical_me_vcf.mix(ch_clin_research_me_vcf.research) ANN_CSQ_PLI_ME( + ch_variant_consequences_sv, ch_ann_csq_me_in, - ch_variant_consequences_sv + true ) - ch_versions = ch_versions.mix( ANN_CSQ_PLI_ME.out.versions ) + ch_ann_csq_pli_me_vcf_ann = ANN_CSQ_PLI_ME.out.vcf_ann + ch_ann_csq_pli_me_tbi = ANN_CSQ_PLI_ME.out.tbi } } @@ -775,15 +912,15 @@ workflow RAREDISEASE { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if ( params.analysis_type.equals("wgs") && !(params.skip_tools && params.skip_tools.split(',').contains('smncopynumbercaller')) ) { + if ( val_analysis_type.equals("wgs") && !skip_smncopynumbercaller ) { RENAME_BAM.out.output - .collect{it[1]} + .collect{_meta, bam -> bam} .toList() .set { ch_bam_list } RENAME_BAI.out.output - .collect{it[1]} + .collect{_meta, bai -> bai} .toList() .set { ch_bai_list } @@ -795,7 +932,9 @@ workflow RAREDISEASE { SMNCOPYNUMBERCALLER ( ch_bams_bais ) - ch_versions = ch_versions.mix(SMNCOPYNUMBERCALLER.out.versions) + ch_smncopynumbercaller_publish = SMNCOPYNUMBERCALLER.out.smncopynumber + .mix(SMNCOPYNUMBERCALLER.out.run_metrics) + .map { meta, value -> ['smncopynumbercaller/', [meta, value]] } } /* @@ -803,12 +942,23 @@ workflow RAREDISEASE { PEDDY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_tools && params.skip_tools.split(',').contains('peddy'))) { + if (!skip_peddy) { PEDDY ( CALL_SNV.out.genome_vcf.join(CALL_SNV.out.genome_tabix, failOnMismatch:true, failOnDuplicate:true), - ch_pedfile + ch_pedfile.map{ped -> return[[id:"pedigree"], ped]}, + [[:],[]] ) - ch_versions = ch_versions.mix(PEDDY.out.versions.first()) + ch_peddy_publish = PEDDY.out.vs_html + .mix(PEDDY.out.html) + .mix(PEDDY.out.ped) + .mix(PEDDY.out.het_check_png) + .mix(PEDDY.out.ped_check_png) + .mix(PEDDY.out.sex_check_png) + .mix(PEDDY.out.het_check_csv) + .mix(PEDDY.out.ped_check_csv) + .mix(PEDDY.out.sex_check_csv) + .mix(PEDDY.out.ped_check_rel_difference_csv) + .map { meta, value -> ['peddy/', [meta, value]] } } /* @@ -816,15 +966,16 @@ workflow RAREDISEASE { Generate CGH files from sequencing data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if ( !(params.skip_tools && params.skip_tools.split(',').contains('vcf2cytosure')) && params.analysis_type.equals("wgs") && !(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('sv_calling')) && !(params.skip_subworkflows && params.skip_subworkflows.split(',').contains('sv_annotation'))) { + if (!skip_vcf2cytosure && val_analysis_type.equals("wgs") && !skip_sv_calling && !skip_sv_annotation) { GENERATE_CYTOSURE_FILES ( - ch_sv_annotate.vcf_ann, - ch_sv_annotate.tbi, - ch_mapped.genome_marked_bam, + ch_mapped.genome_marked_bam_bai, + ch_vcf2cytosure_blacklist, ch_sample_id_map, - ch_vcf2cytosure_blacklist + ch_sv_annotate.tbi, + ch_sv_annotate.vcf_ann, + val_sample_id_map ) - ch_versions = ch_versions.mix(GENERATE_CYTOSURE_FILES.out.versions) + ch_generate_cytosure_files_cgh = GENERATE_CYTOSURE_FILES.out.cgh } /* @@ -832,20 +983,23 @@ workflow RAREDISEASE { GENS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (!(params.skip_tools && params.skip_tools.split(',').contains('gens')) && params.analysis_type.equals("wgs")) { + if (!skip_gens && val_analysis_type.equals("wgs")) { GENS ( - ch_mapped.genome_bam_bai, - CALL_SNV.out.genome_gvcf, - ch_genome_fasta, + ch_mapped.genome_marked_bam_bai, + ch_genome_dictionary, ch_genome_fai, + ch_genome_fasta, + ch_gens_gnomad_pos, + CALL_SNV.out.genome_gvcf, + CALL_SNV.out.genome_gtabix, ch_gens_interval_list, ch_gens_pon_female, - ch_gens_pon_male, - ch_gens_gnomad_pos, - ch_case_info, - ch_genome_dictionary + ch_gens_pon_male ) - ch_versions = ch_versions.mix(GENS.out.versions) + ch_gens_baf_bed_gz = GENS.out.gens_baf_bed_gz + ch_gens_baf_bed_tbi = GENS.out.gens_baf_bed_tbi + ch_gens_cov_bed_gz = GENS.out.gens_cov_bed_gz + ch_gens_cov_bed_tbi = GENS.out.gens_cov_bed_tbi } /* @@ -854,14 +1008,25 @@ workflow RAREDISEASE { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - if (params.run_rtgvcfeval) { + if (val_run_rtgvcfeval) { VARIANT_EVALUATION ( - CALL_SNV.out.genome_vcf_tabix, - ch_genome_fai, ch_rtg_truthvcfs, - ch_sdf + ch_sdf, + CALL_SNV.out.genome_vcf_tabix ) - ch_versions = ch_versions.mix(VARIANT_EVALUATION.out.versions) + ch_variant_evaluation_baseline_tbi = VARIANT_EVALUATION.out.baseline_tbi + ch_variant_evaluation_baseline_vcf = VARIANT_EVALUATION.out.baseline_vcf + ch_variant_evaluation_false_negatives_tbi = VARIANT_EVALUATION.out.false_negatives_tbi + ch_variant_evaluation_false_negatives_vcf = VARIANT_EVALUATION.out.false_negatives_vcf + ch_variant_evaluation_false_positives_tbi = VARIANT_EVALUATION.out.false_positives_tbi + ch_variant_evaluation_false_positives_vcf = VARIANT_EVALUATION.out.false_positives_vcf + ch_variant_evaluation_non_snp_roc = VARIANT_EVALUATION.out.non_snp_roc + ch_variant_evaluation_phasing = VARIANT_EVALUATION.out.phasing + ch_variant_evaluation_snp_roc = VARIANT_EVALUATION.out.snp_roc + ch_variant_evaluation_summary = VARIANT_EVALUATION.out.summary + ch_variant_evaluation_true_positives_tbi = VARIANT_EVALUATION.out.true_positives_tbi + ch_variant_evaluation_true_positives_vcf = VARIANT_EVALUATION.out.true_positives_vcf + ch_variant_evaluation_weighted_roc = VARIANT_EVALUATION.out.weighted_roc } /* @@ -870,40 +1035,58 @@ workflow RAREDISEASE { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - softwareVersionsToYAML(ch_versions) + // + // Collate and save software versions + // + def topic_versions = channel.topic("versions") + .distinct() + .branch { entry -> + versions_file: entry instanceof Path + versions_tuple: true + } + + def topic_versions_string = topic_versions.versions_tuple + .map { process, tool, version -> + [ process[process.lastIndexOf(':')+1..-1], " ${tool}: ${version}" ] + } + .groupTuple(by:0) + .map { process, tool_versions -> + tool_versions.unique().sort() + "${process}:\n${tool_versions.join('\n')}" + } + + def ch_collated_versions = softwareVersionsToYAML(ch_versions.mix(topic_versions.versions_file)) + .mix(topic_versions_string) .collectFile( - storeDir: "${params.outdir}/pipeline_info", + storeDir: "${val_outdir}/pipeline_info", name: 'nf_core_' + 'raredisease_software_' + 'mqc_' + 'versions.yml', sort: true, newLine: true - ).set { ch_collated_versions } - + ) // // MODULE: MultiQC // - ch_multiqc_config = Channel.fromPath( + ch_multiqc_config = channel.fromPath( "$projectDir/assets/multiqc_config.yml", checkIfExists: true) - ch_multiqc_custom_config = params.multiqc_config ? - Channel.fromPath(params.multiqc_config, checkIfExists: true) : - Channel.empty() - ch_multiqc_logo = params.multiqc_logo ? - Channel.fromPath(params.multiqc_logo, checkIfExists: true) : - Channel.fromPath("$projectDir/docs/images/nf-core-raredisease_logo_light.png", checkIfExists: true) - + ch_multiqc_custom_config = val_multiqc_config ? + channel.fromPath(val_multiqc_config, checkIfExists: true) : + channel.empty() + ch_multiqc_logo = val_multiqc_logo ? + channel.fromPath(val_multiqc_logo, checkIfExists: true) : + channel.fromPath("$projectDir/docs/images/nf-core-raredisease_logo_light.png", checkIfExists: true) summary_params = paramsSummaryMap( workflow, parameters_schema: "nextflow_schema.json") - ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) + ch_workflow_summary = channel.value(paramsSummaryMultiqc(summary_params)) + ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) ch_multiqc_files = ch_multiqc_files.mix( ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - ch_multiqc_custom_methods_description = params.multiqc_methods_description ? - file(params.multiqc_methods_description, checkIfExists: true) : + ch_multiqc_custom_methods_description = val_multiqc_methods_description ? + file(val_multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) - ch_methods_description = Channel.value( + ch_methods_description = channel.value( methodsDescriptionText(ch_multiqc_custom_methods_description)) - - ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) ch_multiqc_files = ch_multiqc_files.mix( ch_methods_description.collectFile( name: 'methods_description_mqc.yaml', @@ -911,35 +1094,154 @@ workflow RAREDISEASE { ) ) - ch_multiqc_files = ch_multiqc_files.mix(fastqc_report.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(ch_mt_txt.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(ALIGN.out.fastp_json.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(ALIGN.out.markdup_metrics.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.sex_check.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.multiple_metrics.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.hs_metrics.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.qualimap_results.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.global_dist.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.cov.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.self_sm.map{it[1]}.collect().ifEmpty([])) - - if (!(params.skip_tools && params.skip_tools.split(',').contains('peddy'))) { - ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.ped.map{it[1]}.collect().ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.csv.map{it[1]}.collect().ifEmpty([])) + if (!skip_fastqc) { + ch_multiqc_files = ch_multiqc_files.mix(fastqc_report.collect{_meta, reports -> reports}.ifEmpty([])) + } + ch_multiqc_files = ch_multiqc_files.mix(ALIGN.out.fastp_json.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ALIGN.out.markdup_metrics.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.ngsbits_samplegender_tsv.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.picard_collectmultiplemetrics_metrics.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.picard_collecthsmetrics_metrics.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.mosdepth_global_txt.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.wgsmetrics_wg.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QC_BAM.out.verifybamid_self_sm.map{_meta, reports -> reports}.collect().ifEmpty([])) + + // Add contamination results to MultiQC + ch_multiqc_files = ch_multiqc_files.mix(ch_contamination_mqc.map { _meta, file -> file }) + + if (!skip_peddy) { + ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.ped.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.het_check_csv.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.ped_check_csv.map{_meta, reports -> reports}.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(PEDDY.out.sex_check_csv.map{_meta, reports -> reports}.collect().ifEmpty([])) } + // config: custom config if provided, otherwise the default pipeline config + // logo: custom logo if provided, otherwise omitted + // sample_names: optional TSV for MultiQC --sample-names MULTIQC ( - ch_multiqc_files.collect(), - ch_multiqc_config.toList(), - ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList(), - [], - [] + ch_multiqc_files.flatten().collect().map { files -> + [ + [id: 'raredisease'], + files, + val_multiqc_config + ? file(val_multiqc_config, checkIfExists: true) + : file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true), + val_multiqc_logo ? file(val_multiqc_logo, checkIfExists: true) : [], + [], + val_multiqc_samples ? file(val_multiqc_samples) : [], + ] + } ) - - emit:multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html - versions = ch_versions // channel: [ path(versions.yml) ] - + ch_multiqc_publish = MULTIQC.out.report + .mix(MULTIQC.out.data) + .mix(MULTIQC.out.plots) + .map { _meta, value -> ['multiqc/', value] } + + emit: + align_fastp_out = ch_align_fastp_out // channel: [ val(meta), path(json|html|log|reads|reads_fail|reads_merged) ] + align_genome_marked_bam = ch_align_genome_marked_bam // channel: [ val(meta), path(bam) ] + align_genome_marked_bai = ch_align_genome_marked_bai // channel: [ val(meta), path(bai) ] + align_genome_marked_cram = ch_align_genome_marked_cram // channel: [ val(meta), path(cram) ] + align_genome_marked_crai = ch_align_genome_marked_crai // channel: [ val(meta), path(crai) ] + align_markdup_metrics = ch_align_markdup_metrics // channel: [ val(meta), path(metrics) ] + multiqc_report = MULTIQC.out.report.map { _meta, report -> report }.toList() + qc_bam_chromograph_cov_plots = QC_BAM.out.chromograph_cov_plots // channel: [ val(meta), path(png) ] + qc_bam_mosdepth_global_txt = QC_BAM.out.mosdepth_global_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_per_base_bed = QC_BAM.out.mosdepth_per_base_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_per_base_csi = QC_BAM.out.mosdepth_per_base_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_per_base_d4 = QC_BAM.out.mosdepth_per_base_d4 // channel: [ val(meta), path(d4) ] + qc_bam_mosdepth_quantized_bed = QC_BAM.out.mosdepth_quantized_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_quantized_csi = QC_BAM.out.mosdepth_quantized_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_regions_bed = QC_BAM.out.mosdepth_regions_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_regions_csi = QC_BAM.out.mosdepth_regions_csi // channel: [ val(meta), path(csi) ] + qc_bam_mosdepth_regions_txt = QC_BAM.out.mosdepth_regions_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_summary_txt = QC_BAM.out.mosdepth_summary_txt // channel: [ val(meta), path(txt) ] + qc_bam_mosdepth_thresholds_bed = QC_BAM.out.mosdepth_thresholds_bed // channel: [ val(meta), path(bed.gz) ] + qc_bam_mosdepth_thresholds_csi = QC_BAM.out.mosdepth_thresholds_csi // channel: [ val(meta), path(csi) ] + qc_bam_ngsbits_samplegender_tsv = QC_BAM.out.ngsbits_samplegender_tsv // channel: [ val(meta), path(tsv) ] + qc_bam_picard_collecthsmetrics_metrics = QC_BAM.out.picard_collecthsmetrics_metrics // channel: [ val(meta), path(metrics) ] + qc_bam_picard_collectmultiplemetrics_metrics = QC_BAM.out.picard_collectmultiplemetrics_metrics // channel: [ val(meta), path(metrics) ] + qc_bam_picard_collectmultiplemetrics_pdf = QC_BAM.out.picard_collectmultiplemetrics_pdf // channel: [ val(meta), path(pdf) ] + qc_bam_sambamba_depth_bed = QC_BAM.out.sambamba_depth_bed // channel: [ val(meta), path(bed) ] + qc_bam_tiddit_cov_cov = QC_BAM.out.tiddit_cov_cov // channel: [ val(meta), path(bed) ] + qc_bam_tiddit_cov_wig = QC_BAM.out.tiddit_cov_wig // channel: [ val(meta), path(wig) ] + qc_bam_ucsc_wigtobigwig_bw = QC_BAM.out.ucsc_wigtobigwig_bw // channel: [ val(meta), path(bw) ] + qc_bam_verifybamid_ancestry = QC_BAM.out.verifybamid_ancestry // channel: [ val(meta), path(ancestry) ] + qc_bam_verifybamid_bed = QC_BAM.out.verifybamid_bed // channel: [ val(meta), path(bed) ] + qc_bam_verifybamid_log = QC_BAM.out.verifybamid_log // channel: [ val(meta), path(log) ] + qc_bam_verifybamid_mu = QC_BAM.out.verifybamid_mu // channel: [ val(meta), path(mu) ] + qc_bam_verifybamid_self_sm = QC_BAM.out.verifybamid_self_sm // channel: [ val(meta), path(selfSM) ] + qc_bam_verifybamid_ud = QC_BAM.out.verifybamid_ud // channel: [ val(meta), path(ud) ] + qc_bam_wgsmetrics_wg = QC_BAM.out.wgsmetrics_wg // channel: [ val(meta), path(metrics) ] + qc_bam_wgsmetrics_y = QC_BAM.out.wgsmetrics_y // channel: [ val(meta), path(metrics) ] + call_sv_vcf = ch_call_sv_vcf // channel: [ val(meta), path(vcf) ] + call_sv_tbi = ch_call_sv_tbi // channel: [ val(meta), path(tbi) ] + saltshaker_html = ch_saltshaker_html // channel: [ val(meta), path(html) ] + saltshaker_plot = ch_saltshaker_plot // channel: [ val(meta), path(png) ] + generate_cytosure_files_cgh = ch_generate_cytosure_files_cgh // channel: [ val(meta), path(cgh) ] + mt_del_result = ch_mt_del_result // channel: [ val(meta), path(txt) ] + call_repeat_expansions_expansionhunter_bai = ch_call_repeat_expansions_expansionhunter_bai // channel: [ val(meta), path(bai) ] + call_repeat_expansions_expansionhunter_bam = ch_call_repeat_expansions_expansionhunter_bam // channel: [ val(meta), path(bam) ] + call_repeat_expansions_expansionhunter_vcf = ch_call_repeat_expansions_expansionhunter_vcf // channel: [ val(meta), path(vcf) ] + call_repeat_expansions_stranger_tbi = ch_call_repeat_expansions_stranger_tbi // channel: [ val(meta), path(tbi) ] + call_repeat_expansions_stranger_vcf = ch_call_repeat_expansions_stranger_vcf // channel: [ val(meta), path(vcf) ] + call_snv_bcftools_concat_csi = ch_call_snv_bcftools_concat_csi // channel: [ val(meta), path(csi) ] + call_snv_bcftools_concat_tbi = ch_call_snv_bcftools_concat_tbi // channel: [ val(meta), path(tbi) ] + call_snv_bcftools_concat_vcf = ch_call_snv_bcftools_concat_vcf // channel: [ val(meta), path(vcf) ] + call_snv_deepvariant_report = ch_call_snv_deepvariant_report // channel: [ val(meta), path(html) ] + call_snv_genome_tabix = ch_call_snv_genome_tabix // channel: [ val(meta), path(tbi) ] + call_snv_genome_vcf = ch_call_snv_genome_vcf // channel: [ val(meta), path(vcf) ] + call_snv_mt_tabix = ch_call_snv_mt_tabix // channel: [ val(meta), path(tbi) ] + call_snv_mt_vcf = ch_call_snv_mt_vcf // channel: [ val(meta), path(vcf) ] + gens_baf_bed_gz = ch_gens_baf_bed_gz // channel: [ val(meta), path(bed.gz) ] + gens_baf_bed_tbi = ch_gens_baf_bed_tbi // channel: [ val(meta), path(tbi) ] + gens_cov_bed_gz = ch_gens_cov_bed_gz // channel: [ val(meta), path(bed.gz) ] + gens_cov_bed_tbi = ch_gens_cov_bed_tbi // channel: [ val(meta), path(tbi) ] + annotate_genome_snvs_bcftools_concat_tbi = ch_annotate_genome_snvs_bcftools_concat_tbi // channel: [ val(meta), path(tbi) ] + annotate_genome_snvs_bcftools_concat_vcf = ch_annotate_genome_snvs_bcftools_concat_vcf // channel: [ val(meta), path(vcf) ] + annotate_genome_snvs_chromograph_autozyg_plots = ch_annotate_genome_snvs_chromograph_autozyg_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_chromograph_regions_plots = ch_annotate_genome_snvs_chromograph_regions_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_chromograph_sites_plots = ch_annotate_genome_snvs_chromograph_sites_plots // channel: [ val(meta), path(png) ] + annotate_genome_snvs_rhocall_viz_bed = ch_annotate_genome_snvs_rhocall_viz_bed // channel: [ val(meta), path(bed) ] + annotate_genome_snvs_rhocall_viz_wig = ch_annotate_genome_snvs_rhocall_viz_wig // channel: [ val(meta), path(wig) ] + annotate_genome_snvs_ucsc_wigtobigwig_bw = ch_annotate_genome_snvs_ucsc_wigtobigwig_bw // channel: [ val(meta), path(bw) ] + annotate_mt_snvs_ensemblvep_mt_tbi = ch_annotate_mt_snvs_ensemblvep_mt_tbi // channel: [ val(meta), path(tbi) ] + annotate_mt_snvs_ensemblvep_mt_vcf = ch_annotate_mt_snvs_ensemblvep_mt_vcf // channel: [ val(meta), path(vcf) ] + call_mobile_elements_tbi = ch_call_mobile_elements_tbi // channel: [ val(meta), path(tbi) ] + call_mobile_elements_vcf = ch_call_mobile_elements_vcf // channel: [ val(meta), path(vcf) ] + ann_csq_pli_me_tbi = ch_ann_csq_pli_me_tbi // channel: [ val(meta), path(tbi) ] + ann_csq_pli_me_vcf_ann = ch_ann_csq_pli_me_vcf_ann // channel: [ val(meta), path(vcf) ] + rank_snv_tbi = ch_rank_snv_tbi // channel: [ val(meta), path(tbi) ] + rank_snv_vcf = ch_rank_snv_vcf // channel: [ val(meta), path(vcf) ] + rank_mt_tbi = ch_rank_mt_tbi // channel: [ val(meta), path(tbi) ] + rank_mt_vcf = ch_rank_mt_vcf // channel: [ val(meta), path(vcf) ] + rank_sv_tbi = ch_rank_sv_tbi // channel: [ val(meta), path(tbi) ] + rank_sv_vcf = ch_rank_sv_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_baseline_tbi = ch_variant_evaluation_baseline_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_baseline_vcf = ch_variant_evaluation_baseline_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_false_negatives_tbi = ch_variant_evaluation_false_negatives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_false_negatives_vcf = ch_variant_evaluation_false_negatives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_false_positives_tbi = ch_variant_evaluation_false_positives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_false_positives_vcf = ch_variant_evaluation_false_positives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_non_snp_roc = ch_variant_evaluation_non_snp_roc // channel: [ val(meta), path(tsv) ] + variant_evaluation_phasing = ch_variant_evaluation_phasing // channel: [ val(meta), path(txt) ] + variant_evaluation_snp_roc = ch_variant_evaluation_snp_roc // channel: [ val(meta), path(tsv) ] + variant_evaluation_summary = ch_variant_evaluation_summary // channel: [ val(meta), path(txt) ] + variant_evaluation_true_positives_tbi = ch_variant_evaluation_true_positives_tbi // channel: [ val(meta), path(tbi) ] + variant_evaluation_true_positives_vcf = ch_variant_evaluation_true_positives_vcf // channel: [ val(meta), path(vcf) ] + variant_evaluation_weighted_roc = ch_variant_evaluation_weighted_roc // channel: [ val(meta), path(tsv) ] + subsample_mt_bai = ch_subsample_mt_bai // channel: [ val(meta), path(bai) ] + subsample_mt_bam = ch_subsample_mt_bam // channel: [ val(meta), path(bam) ] + contamination_table = ch_contamination_table // channel: [ val(meta), path(table) ] + contamination_pileup = ch_contamination_pileup // channel: [ val(meta), path(table) ] + versions = ch_versions + publish = ch_call_sv_publish + .mix(ch_annotate_sv_publish) + .mix(ch_fastqc_publish) + .mix(ch_smncopynumbercaller_publish) + .mix(ch_peddy_publish) + .mix(ch_multiqc_publish) }