diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b290e09..237c9ed 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 0000000..8f078f3 --- /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/nextbigthing devcontainer!" > /usr/local/etc/vscode-dev-containers/first-run-notice.txt diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 3bca66c..0000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,125 +0,0 @@ -# `nf-core/funcprofiler`: Contributing Guidelines - -Hi there! -Many thanks for taking an interest in improving nf-core/funcprofiler. - -We try to manage the required tasks for nf-core/funcprofiler using GitHub issues, you probably came to this page when creating one. -Please use the pre-filled template to save time. - -However, don't be put off by this template - other more general issues and suggestions are welcome! -Contributions to the code are even more welcome ;) - -> [!NOTE] -> If you need help using or modifying nf-core/funcprofiler then the best place to ask is on the nf-core Slack [#funcprofiler](https://nfcore.slack.com/channels/funcprofiler) channel ([join our Slack here](https://nf-co.re/join/slack)). - -## Contribution workflow - -If you'd like to write some code for nf-core/funcprofiler, the standard workflow is as follows: - -1. Check that there isn't already an issue about your idea in the [nf-core/funcprofiler issues](https://github.com/nf-core/funcprofiler/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/funcprofiler repository](https://github.com/nf-core/funcprofiler) to your GitHub account -3. Make the necessary changes / additions within your forked repository following [Pipeline conventions](#pipeline-contribution-conventions) -4. Use `nf-core pipelines schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](https://github.com/nf-core/tools) >= 1.10). -5. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged - -If you're not used to this workflow with git, you can start with some [docs from GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or even their [excellent `git` resources](https://try.github.io/). - -## Tests - -You have the option to test your changes locally by running the pipeline. For receiving warnings about process selectors and other `debug` information, it is recommended to use the debug profile. Execute all the tests with the following command: - -```bash -nf-test test --profile debug,test,docker --verbose -``` - -When you create a pull request with changes, [GitHub Actions](https://github.com/features/actions) will run automatic tests. -Typically, pull-requests are only fully reviewed when these tests are passing, though of course we can help out before then. - -There are typically two types of tests that run: - -### Lint tests - -`nf-core` has a [set of guidelines](https://nf-co.re/developers/guidelines) which all pipelines must adhere to. -To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core pipelines lint ` command. - -If any failures or warnings are encountered, please follow the listed URL for more documentation. - -### Pipeline tests - -Each `nf-core` pipeline should be set up with a minimal set of test-data. -`GitHub Actions` then runs the pipeline on this data to ensure that it exits successfully. -If there are any failures then the automated tests fail. -These tests are run both with the latest available version of `Nextflow` and also the minimum required version that is stated in the pipeline code. - -## Patch - -:warning: Only in the unlikely and regretful event of a release happening with a bug. - -- On your own fork, make a new branch `patch` based on `upstream/main` or `upstream/master`. -- Fix the bug, and bump version (X.Y.Z+1). -- Open a pull-request from `patch` to `main`/`master` with the changes. - -## Getting help - -For further information/help, please consult the [nf-core/funcprofiler documentation](https://nf-co.re/funcprofiler/usage) and don't hesitate to get in touch on the nf-core Slack [#funcprofiler](https://nfcore.slack.com/channels/funcprofiler) channel ([join our Slack here](https://nf-co.re/join/slack)). - -## Pipeline contribution conventions - -To make the `nf-core/funcprofiler` code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written. - -### Adding a new step - -If you wish to contribute a new step, please use the following coding standards: - -1. Define the corresponding input channel into your new process from the expected previous process channel. -2. Write the process block (see below). -3. Define the output channel if needed (see below). -4. Add any new parameters to `nextflow.config` with a default (see below). -5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core pipelines schema build` tool). -6. Add sanity checks and validation for all relevant parameters. -7. Perform local tests to validate that the new code works as expected. -8. If applicable, add a new test in the `tests` directory. -9. Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name clean up and module plots are in the appropriate order. If applicable, add a [MultiQC](https://https://multiqc.info/) module. -10. Add a description of the output files and if relevant any appropriate images from the MultiQC report to `docs/output.md`. - -### Default values - -Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. - -Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`. - -### Default processes resource requirements - -Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. - -The process resources can be passed on to the tool dynamically within the process with the `${task.cpus}` and `${task.memory}` variables in the `script:` block. - -### Naming schemes - -Please use the following naming schemes, to make it easy to understand what is going where. - -- initial process channel: `ch_output_from_` -- intermediate and terminal channels: `ch__for_` - -### Nextflow version bumping - -If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core pipelines bump-version --nextflow . [min-nf-version]` - -### Images and figures - -For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines). - -## GitHub Codespaces - -This repo includes a devcontainer configuration which will create a GitHub Codespaces for Nextflow development! This is an online developer environment that runs in your browser, complete with VSCode and a terminal. - -To get started: - -- Open the repo in [Codespaces](https://github.com/nf-core/funcprofiler/codespaces) -- Tools installed - - nf-core - - Nextflow - -Devcontainer specs: - -- [DevContainer config](.devcontainer/devcontainer.json) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f7d3c8b..1b90bf3 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/funcprofiler/tree/main/.github/CONTRIBUTING.md) +Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/funcprofiler/tree/main/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/funcprofiler/tree/main/.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/funcprofiler/tree/main/docs/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/funcprofiler _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 3408527..e2833ee 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 bf44d96..d5c04a1 100644 --- a/.github/actions/nf-test/action.yml +++ b/.github/actions/nf-test/action.yml @@ -20,38 +20,43 @@ runs: using: "composite" steps: - name: Setup Nextflow - uses: nf-core/setup-nextflow@v2 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: "${{ env.NXF_VERSION }}" - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: - python-version: "3.13" + python-version: "3.14" - name: Install nf-test - uses: nf-core/setup-nf-test@v1 + uses: nf-core/setup-nf-test@4069fbbaabe94c08faba4ad261bfa88225ba133f # v2 with: version: "${{ env.NFT_VER }}" install-pdiff: true - name: Setup apptainer if: contains(inputs.profile, 'singularity') - uses: eWaterCycle/setup-apptainer@main + uses: eWaterCycle/setup-apptainer@3f706d898c9db585b1d741b4692e66755f3a1b40 # v2.0.0 - name: Set up Singularity if: contains(inputs.profile, 'singularity') shell: bash run: | + # The runner image restricts unprivileged user namespaces, which non-suid + # apptainer needs to start a container at all. + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true mkdir -p $NXF_SINGULARITY_CACHEDIR mkdir -p $NXF_SINGULARITY_LIBRARYDIR - name: Conda setup if: contains(inputs.profile, 'conda') - uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3 + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4 with: auto-update-conda: true conda-solver: libmamba + channels: conda-forge + channel-priority: flexible conda-remove-defaults: true - name: Run nf-test diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 39b4062..4f60919 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -23,26 +23,44 @@ 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 - # TODO nf-core: You can customise AWS full pipeline tests as required + uses: seqeralabs/action-tower-launch@51565b514bff1827cf34620de25d0055759f1fc9 # v2 # 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/funcprofiler/work-${{ steps.revision.outputs.revision }} + workdir: s3://${{ vars.AWS_S3_BUCKET }}/work/funcprofiler/work-${{ steps.revision.outputs.revision }} + nextflow_config: | + plugins { + id 'nf-slack@0.5.0' + } + slack { + enabled = true + bot { + token = '${{ secrets.NFSLACK_BOT_TOKEN }}' + channel = 'funcprofiler' + } + onStart { + enabled = false + } + onComplete { + message = ':white_check_mark: *funcprofiler/test_full* completed successfully! :tada:' + } + onError { + message = ':x: *funcprofiler/test_full* failed :crying_cat_face:' + } + } parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/funcprofiler/results-${{ steps.revision.outputs.revision }}" + "outdir": "s3://${{ vars.AWS_S3_BUCKET }}/funcprofiler/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 49116c5..1daec37 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/funcprofiler/work-${{ github.sha }} + workdir: s3://${{ vars.AWS_S3_BUCKET }}/work/funcprofiler/work-${{ github.sha }} parameters: | { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/funcprofiler/results-test-${{ github.sha }}" + "outdir": "s3://${{ vars.AWS_S3_BUCKET }}/funcprofiler/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 a6d4926..f16c675 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -2,11 +2,13 @@ name: nf-core branch protection # This workflow is triggered on PRs to `main`/`master` branch on the repository # It fails when someone tries to make a PR against the nf-core `main`/`master` branch instead of `dev` on: - pull_request_target: + pull_request: branches: - main - master +permissions: {} + jobs: test: runs-on: ubuntu-latest @@ -14,33 +16,47 @@ jobs: # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs if: github.repository == 'nf-core/funcprofiler' + env: + HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} run: | - { [[ ${{github.event.pull_request.head.repo.full_name }} == nf-core/funcprofiler ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] + { [[ "$HEAD_REPO" == nf-core/funcprofiler ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] - # If the above check failed, post a comment on the PR explaining the failure - # 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 the above check failed, build a comment to be posted by the shared poster workflow + - name: Build PR comment if: failure() - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 - with: - message: | - ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} + PR_USER: ${{ github.event.pull_request.user.login }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "branch" > pr-comment/header.txt + cat > pr-comment/comment.md <> "$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 19f7b8d..96ae9d8 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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 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@893c28b667aedeba26e37f296d260ccc5bc4d914 # 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@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # 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 8b0f88c..82b54d0 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -11,33 +11,36 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - - name: Set up Python 3.13 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 - with: - python-version: "3.13" + - name: Install Nextflow + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 - - name: Install pre-commit - run: pip install pre-commit + - name: Set up Python 3.14 + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 + with: + python-version: "3.14" - - name: Run pre-commit - run: pre-commit run --all-files + - name: Run prek + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 nf-core: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow - uses: nf-core/setup-nextflow@v2 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: - python-version: "3.13" + python-version: "3.14" architecture: "x64" + - name: Setup uv + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 id: read_yml @@ -45,12 +48,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 +59,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,10 +72,28 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: linting-logs path: | lint_log.txt lint_results.md PR_number.txt + + # Build a comment for the shared pr-comment.yml poster to publish on the PR + - name: Prepare PR comment + if: ${{ always() }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "lint" > pr-comment/header.txt + [ -f lint_results.md ] && cp lint_results.md pr-comment/comment.md || true + + - name: Upload PR comment artifact + if: ${{ always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-comment + path: pr-comment/ diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml deleted file mode 100644 index d43797d..0000000 --- a/.github/workflows/linting_comment.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: nf-core linting comment -# This workflow is triggered after the linting action is complete -# It posts an automated comment to the PR, even if the PR is coming from a fork - -on: - workflow_run: - workflows: ["nf-core linting"] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Download lint results - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 - with: - workflow: linting.yml - workflow_conclusion: completed - - - name: Get PR number - id: pr_number - run: echo "pr_number=$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - - - name: Post PR comment - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - number: ${{ steps.pr_number.outputs.pr_number }} - path: linting-logs/lint_results.md diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index 9d7642e..d089b70 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -18,7 +18,7 @@ concurrency: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NFT_VER: "0.9.2" + NFT_VER: "0.9.5" NFT_WORKDIR: "~" NXF_ANSI_LOG: false NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity @@ -40,7 +40,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 @@ -50,7 +50,7 @@ jobs: env: NFT_VER: ${{ env.NFT_VER }} with: - max_shards: 7 + max_shards: 19 - name: debug run: | @@ -68,24 +68,22 @@ jobs: fail-fast: false matrix: shard: ${{ fromJson(needs.nf-test-changes.outputs.shard) }} - profile: [conda, docker, singularity] + profile: [docker, singularity, conda] isMain: - ${{ github.base_ref == 'master' || github.base_ref == 'main' }} # Exclude conda and singularity on dev exclude: - - isMain: false - profile: "conda" - isMain: false profile: "singularity" NXF_VER: - - "24.10.5" + - "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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 @@ -95,11 +93,24 @@ jobs: continue-on-error: ${{ matrix.NXF_VER == 'latest-everything' }} env: NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + NXF_VERSION: ${{ matrix.NXF_VER }} with: profile: ${{ matrix.profile }} shard: ${{ matrix.shard }} total_shards: ${{ env.TOTAL_SHARDS }} - + - name: list contents + run: ls -R "${{ env.NFT_WORKDIR }}" + - name: list funcprofilercontents + run: ls -R /home/runner/_work/funcprofiler/funcprofiler/ + - name: Upload artifact + if: ${{ always() }} + uses: actions/upload-artifact@v7 + with: + name: my-artifact-${{ matrix.profile }}-${{ matrix.NXF_VER }}-${{ matrix.shard }} + path: | + /home/runner/_work/funcprofiler/funcprofiler/ + !/home/runner/_work/funcprofiler/funcprofiler/**/work/conda/ + retention-days: 2 - name: Report test status if: ${{ always() }} run: | @@ -115,10 +126,26 @@ jobs: fi fi + # continue-on-error keeps latest-everything from failing the job, so it never shows up in + # `needs.nf-test.result` downstream and CI stays green. Surface it via a PR comment instead; + # other NXF_VER failures already fail the job/CI directly, so no comment is needed for those. + - name: Prepare PR comment fragment + if: ${{ always() && steps.run_nf_test.outcome == 'failure' && matrix.NXF_VER == 'latest-everything' }} + run: | + mkdir -p pr-comment-fragment + echo "* ❌ \`${{ matrix.profile }}\` | \`${{ matrix.NXF_VER }}\` | Shard ${{ matrix.shard }}/${{ env.TOTAL_SHARDS }}" > pr-comment-fragment/fragment.md + + - name: Upload PR comment fragment + if: ${{ always() && steps.run_nf_test.outcome == 'failure' && matrix.NXF_VER == 'latest-everything' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-comment-fragment-${{ strategy.job-index }} + path: pr-comment-fragment/ + confirm-pass: needs: [nf-test] if: always() - runs-on: # use self-hosted runners + runs-on: # use self-hosted runners - runs-on=${{ github.run_id }}-confirm-pass - runner=2cpu-linux-x64 steps: @@ -141,3 +168,44 @@ jobs: echo "DEBUG: toJSON(needs) = ${{ toJSON(needs) }}" echo "DEBUG: toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}" echo "::endgroup::" + + - name: Download PR comment fragments + if: ${{ always() }} + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + continue-on-error: true + with: + pattern: pr-comment-fragment-* + path: pr-comment-fragments + merge-multiple: true + + # Build a comment for the shared pr-comment.yml poster to publish on the PR. + # Based on the fragments above (not needs.*.result) so non-blocking failures are still reported. + - name: Prepare PR comment + if: ${{ always() }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "nf-test" > pr-comment/header.txt + if [ -d pr-comment-fragments ] && [ -n "$(ls -A pr-comment-fragments)" ]; then + { + echo "## ❌ nf-test failed with latest Nextflow version" + echo "" + echo "> [!NOTE]" + echo "> Tests with Nextflow's latest version failed but it will not cause a CI workflow failure." + echo "> Please check if the failure is expected with newer (edge-)releases of Nextflow or if it needs fixing." + echo "" + cat pr-comment-fragments/*.md + echo "" + echo "See the [full run](${RUN_URL}) for details." + } > pr-comment/comment.md + fi + + - name: Upload PR comment artifact + if: ${{ always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-comment + path: pr-comment/ diff --git a/.github/workflows/pr-comment.yml b/.github/workflows/pr-comment.yml new file mode 100644 index 0000000..ab7b59d --- /dev/null +++ b/.github/workflows/pr-comment.yml @@ -0,0 +1,82 @@ +name: Post PR comment +# Shared, privileged comment poster. +# +# This is the single workflow that runs with a write token. It is triggered +# after any of the listed "producer" workflows complete on a pull request. +# Each producer runs untrusted PR code (if any) with a read-only token and +# uploads a `pr-comment` artifact describing the comment to post; this workflow +# only ever reads that plain-text artifact, so no PR code is executed here. +# +# Artifact contract (uploaded by producers under the name `pr-comment`): +# pr_number.txt - the pull request number +# header.txt - sticky-comment identifier (keeps comment types separate) +# comment.md - the Markdown body (omit the file to post nothing) + +on: + workflow_run: + workflows: + - "nf-core linting" + - "nf-core template version comment" + - "nf-core branch protection" + - "Run nf-test" + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + post-comment: + runs-on: ubuntu-latest + if: github.event.workflow_run.event == 'pull_request' + steps: + - name: Download PR comment artifact + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 + with: + run_id: ${{ github.event.workflow_run.id }} + name: pr-comment + path: pr-comment + if_no_artifact_found: ignore + + - name: Read comment metadata + id: meta + run: | + echo "::group::Downloaded pr-comment contents" + ls -la pr-comment 2>/dev/null || echo "No pr-comment/ directory was downloaded." + echo "::endgroup::" + + if [ ! -d pr-comment ]; then + echo "No pr-comment artifact found; nothing to post." + exit 0 + fi + + if [ ! -f pr-comment/comment.md ]; then + echo "Artifact present but no comment.md; nothing to post." + exit 0 + fi + + pr_number=$(cat pr-comment/pr_number.txt) + header=$(cat pr-comment/header.txt) + echo "Found comment.md (header='$header', pr_number='$pr_number')." + + # Guard against anything unexpected ending up in the PR number. + case "$pr_number" in + ''|*[!0-9]*) + echo "Invalid PR number: '$pr_number'" + exit 1 + ;; + esac + + echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT" + echo "header=$header" >> "$GITHUB_OUTPUT" + echo "post=true" >> "$GITHUB_OUTPUT" + echo "Will post comment to PR #${pr_number}." + + - name: Post PR comment + if: steps.meta.outputs.post == 'true' + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + number: ${{ steps.meta.outputs.pr_number }} + header: ${{ steps.meta.outputs.header }} + path: pr-comment/comment.md diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index 0f73249..4974f44 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@66c2cbb5b1997666b0e28d597631b6a4f09a2719 # v0.0.6 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@6461056ea355ea43b977e149f7bf76aaa572e5e8 # v0.3.0 + - uses: zentered/bluesky-post-action@5a91cc2ad10a304a4e96c16182dbe4918710bcf6 # v0.4.0 with: post: | Pipeline release! ${{ github.repository }} v${{ github.event.release.tag_name }} - ${{ github.event.release.name }}! diff --git a/.github/workflows/template-version-comment.yml b/.github/workflows/template-version-comment.yml index beb5c77..149e285 100644 --- a/.github/workflows/template-version-comment.yml +++ b/.github/workflows/template-version-comment.yml @@ -2,14 +2,17 @@ name: nf-core template version comment # This workflow is triggered on PRs to check if the pipeline template version matches the latest nf-core version. # It posts a comment to the PR, even if it comes from a fork. -on: pull_request_target +on: + pull_request: + +permissions: {} jobs: - template_version: + check_template_version: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: ref: ${{ github.event.pull_request.head.sha }} @@ -22,25 +25,36 @@ jobs: - name: Install nf-core run: | python -m pip install --upgrade pip - pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + pip install nf-core + + - name: Build PR comment if template is outdated + # The fork-controlled version is passed via the environment and only ever + # used as quoted shell data (never interpolated into a command), so it + # cannot be used for script injection. + env: + PR_VERSION: ${{ steps.read_yml.outputs['nf_core_version'] }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "template-version" > pr-comment/header.txt + + latest_version=$(nf-core --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1) - - name: Check nf-core outdated - id: nf_core_outdated - run: echo "OUTPUT=$(pip list --outdated | grep nf-core)" >> ${GITHUB_ENV} + if [ -n "$PR_VERSION" ] && [ -n "$latest_version" ] && [ "$PR_VERSION" != "$latest_version" ]; then + cat > pr-comment/comment.md < [!WARNING] + > Newer version of the nf-core template is available. + > + > Your pipeline is using an old version of the nf-core template: ${PR_VERSION}. + > Please update your pipeline to the latest version. + > + > For more documentation on how to update your pipeline, please see the [Synchronisation documentation](https://nf-co.re/docs/developing/template-syncs/overview). + EOF + fi - - name: Post nf-core template version comment - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 - if: | - contains(env.OUTPUT, 'nf-core') + - name: Upload PR comment artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} - allow-repeats: false - message: | - > [!WARNING] - > Newer version of the nf-core template is available. - > - > Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. - > Please update your pipeline to the latest version. - > - > For more documentation on how to update your pipeline, please see the [nf-core documentation](https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). - # + name: pr-comment + path: pr-comment/ diff --git a/.gitignore b/.gitignore index a42ce01..393cd5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,12 @@ testing/ testing* *.pyc null/ +*~ +.nf-test/ +.nf-test.log +dontcommit +tmp/ +.data/ +*.code-workspace +.lineage/ +conf/tmp.config diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 83599f6..0000000 --- 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/.hooks/block_pipeline_outdir.sh b/.hooks/block_pipeline_outdir.sh new file mode 100755 index 0000000..e9ba4f9 --- /dev/null +++ b/.hooks/block_pipeline_outdir.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# This hook is used to block commits if they include staged files inside a directory +# which also contains a subdirectory called `pipeline_info`. The purpose of this is to +# prevent users from inadvertently committing output from pipeline test runs inside the +# development directory. + +set -e + +status=0 +seen_dirs="" + +while IFS= read -r file; do + # The offending output bundle's root is the ancestor directory that has + # `pipeline_info` as an immediate child, so callers can restore it in one go. + if [[ "$file" == pipeline_info/* ]]; then + top_dir="pipeline_info" + elif [[ "$file" == */pipeline_info/* ]]; then + top_dir="${file%%/pipeline_info/*}" + else + top_dir="" + dir=$(dirname "$file") + while [[ "$dir" != "." && "$dir" != "/" ]]; do + if [[ -d "$dir/pipeline_info" ]]; then + top_dir="$dir" + break + fi + dir=$(dirname "$dir") + done + fi + + if [[ -n "$top_dir" ]]; then + echo "❌ Commit blocked: Please do not commit output from pipeline test runs to the pipeline code itself: $file" + status=1 + case "$seen_dirs" in + *"|$top_dir|"*) ;; + *) + echo "Run 'git restore --staged $top_dir' to remove the whole output folder from the staging area." + seen_dirs="$seen_dirs|$top_dir|" + ;; + esac + fi +done < <(git diff --cached --name-only) + +exit "$status" diff --git a/.nf-core.yml b/.nf-core.yml index f7b23f8..8ceb31e 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,15 +1,19 @@ +lint: + files_unchanged: + - assets/nf-core-funcprofiler_logo_light.png + - .github/PULL_REQUEST_TEMPLATE.md + - .github/workflows/linting.yml + - .github/workflows/branch.yml + - .gitignore +nf_core_version: 4.1.0 repository_type: pipeline -nf_core_version: 3.3.2 - -lint: {} - template: - org: nf-core - name: funcprofiler + author: Nick Waters, Vini Salazar, Yixuan Yang, Mirae Baichoo description: Read-based functional profiling of microbiome sequencing data - author: Nick Waters - version: 1.0.0dev - force: true - outdir: . + force: false is_nfcore: true + name: funcprofiler + org: nf-core + outdir: . + version: 1.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb41bee..e9503db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,24 +4,47 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.6.2 + - prettier@3.9.6 - 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$ )$ + - id: check-added-large-files + args: [--maxkb=5000] + exclude: | + (?x)^( + .*ro-crate-metadata.json$| + .*\.snap$| + lib/nfcore_external_java_deps.jar$| + docs/.*\.(svg|pdf)$| + assets/.*$ + )$ + - id: check-merge-conflict + - repo: https://github.com/seqeralabs/nf-lint-pre-commit + rev: v0.3.0 + hooks: + - id: nextflow-lint + files: '\.nf$|nextflow\.config$' + args: ["-output", "json"] + - repo: local + hooks: + - id: block-pipeline-outdir + name: Prevent committing output from pipeline test runs to the pipeline code itself + entry: ./.hooks/block_pipeline_outdir.sh + language: script diff --git a/.prettierignore b/.prettierignore index edd29f0..63cde50 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 5a029db..a84f032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ 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). -## v1.0.0dev - [date] +## v1.0.0 - [unreleased] Initial release of nf-core/funcprofiler, created with the [nf-core](https://nf-co.re/) template. diff --git a/CITATIONS.md b/CITATIONS.md index 5f71d8d..32b76f4 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -10,14 +10,60 @@ ## Pipeline tools + + +- [DIAMOND](https://github.com/bbuchfink/diamond/) + +> Buchfink B, Reuter K, Drost HG. Sensitive protein alignments at tree-of-life scale using DIAMOND. Nat Methods. 2021 Apr;18(4):366-368. doi: 10.1038/s41592-021-01101-x. PubMed PMID: 33828273. + +> Buchfink B, Xie C, Huson DH. Fast and sensitive protein alignment using DIAMOND. Nat Methods. 2015 Jan;12(1):59-60. doi: 10.1038/nmeth.3176. Epub 2014 Nov 17. PMID: 25402007. + +- [eggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) + +> Cantalapiedra CP, Hernández-Plaza A, Letunic I, Bork P, Huerta-Cepas J. eggNOG-mapper v2: Functional Annotation, Orthology Assignments, and Domain Prediction at the Metagenomic Scale. Mol Biol Evol. 2021 Dec 9;38(12):5825-5829. doi: 10.1093/molbev/msab293. PubMed PMID: 34597405. + - [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) > Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. +- [fmh-funprofiler](https://pubmed.ncbi.nlm.nih.gov/39230701/) + +> Hera MR, Liu S, Wei W, Rodriguez JS, Ma C, Koslicki D. Metagenomic functional profiling: to sketch or not to sketch? Bioinformatics. 2024 Sep 1;40(Suppl 2):ii165-ii173. doi: 10.1093/bioinformatics/btae397. PMID: 39230701; PMCID: PMC11373326. + +- [HUMAnN](http://huttenhower.sph.harvard.edu/humann) + +> Beghini F, McIver L, Blanco-Mìguez A, Dubois L, Asnicar F, Maharjan S ,Mailyan A, Thomas AM, Manghi P, Valles-Colomer M, Weingart G ,Zhang Y, Zolfo M,Huttenhower C, Franzosa EA, Segata N. Integrating taxonomic, functional, and strain-level profiling of diverse microbial communities with bioBakery 3. eLife 2021;10:e65088 + +- [mi-faser](https://academic.oup.com/nar/advance-article/doi/10.1093/nar/gkx1209/4670955) + +> Zhu C, Miller M, Marpaka S, Vaysberg P, Rühlemann M, Wu G, Heinsen FA, Tempel M, Zhao L, Leib W, Franke A, Bromberg Y. Functional sequencing read annotation for high precision microbiome analysis. Nucleic Acids Research. Volume 46, Issue 4. 2017. doi: 10.1093/nar/gkx1209. + +> Mahlich Y, Zhu C, Chung H, Velaga PK, De Paolis Kaluza MC, Radivojac P, Friedberg I, Bromberg Y. Learning from the unknown: exploring the range of bacterial functionality. Nucleic Acids Res. 2023 Oct 27;51(19):10162-10175. doi: 10.1093/nar/gkad757. PubMed PMID: 37739408. + +> Zhu C, Delmont TO, Vogel TM, Bromberg Y. Functional Basis of Microorganism Classification. PLoS Comput Biol. 2015 Aug 28;11(8):e1004472. doi: 10.1371/journal.pcbi.1004472. PubMed PMID: 26317871. + +- [MetaPhlAn3](http://segatalab.cibio.unitn.it/tools/metaphlan/index.html) + +> Beghini F, McIver LJ, Blanco-Míguez A, Dubois L, Asnicar F, Maharjan S, Mailyan A, Manghi P, Scholz M, Thomas AM, Valles-Colomer M, Weingart G, Zhang Y, Zolfo M, Huttenhower C, Franzosa EA, Segata N. Integrating taxonomic, functional, and strain-level profiling of diverse microbial communities with bioBakery 3. Elife. 2021 May 4;10:e65088. doi: 10.7554/eLife.65088. PMID: 33944776; PMCID: PMC8096432. + +- [MetaPhlAn4](http://segatalab.cibio.unitn.it/tools/metaphlan/index.html) + +> Blanco-Míguez A, Beghini F, Cumbo F, McIver LJ, Thompson KN, Zolfo M, Manghi P, Dubois L, Huang KD, Thomas AM, Nickols WA, Piccinno G, Piperni E, Punčochář M, Valles-Colomer M, Tett A, Giordano F, Davies R, Wolf J, Berry SE, Spector TD, Franzosa EA, Pasolli E, Asnicar F, Huttenhower C, Segata N. Extending and improving metagenomic taxonomic profiling with uncharacterized species using MetaPhlAn 4. Nat Biotechnol. 2023 Nov;41(11):1633-1644. doi: 10.1038/s41587-023-01688-w. Epub 2023 Feb 23. PMID: 36823356; PMCID: PMC10635831. + - [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. +- [RGI/CARD](https://pubmed.ncbi.nlm.nih.gov/36263822/) + +> Alcock BP, Huynh W, Chalil R, Smith KW, Raphenya AR, Wlodarski MA, Edalatmand A, Petkau A, Syed SA, Tsang KK, Baker SJC, Dave M, McCarthy MC, Mukiri KM, Nasir JA, Golbon B, Imtiaz H, Jiang X, Kaur K, Kwong M, Liang ZC, Niu KC, Shan P, Yang JYJ, Gray KL, Hoad GR, Jia B, Bhando T, Carfrae LA, Farha MA, French S, Gordzevich R, Rachwalski K, Tu MM, Bordeleau E, Dooley D, Griffiths E, Zubyk HL, Brown ED, Maguire F, Beiko RG, Hsiao WWL, Brinkman FSL, Van Domselaar G, McArthur AG. CARD 2023: expanded curation, support for machine learning, and resistome prediction at the Comprehensive Antibiotic Resistance Database. Nucleic Acids Res. 2023 Jan 6;51(D1):D690-D699. doi: 10.1093/nar/gkac920. PMID: 36263822; PMCID: PMC9825576. + +> McArthur AG, Waglechner N, Nizam F, Yan A, Azad MA, Baylay AJ, Bhullar K, Canova MJ, De Pascale G, Ejim L, Kalan L, King AM, Koteva K, Morar M, Mulvey MR, O'Brien JS, Pawlowski AC, Piddock LJ, Spanogiannopoulos P, Sutherland AD, Tang I, Taylor PL, Thaker M, Wang W, Yan M, Yu T, Wright GD. The comprehensive antibiotic resistance database. Antimicrob Agents Chemother. 2013 Jul;57(7):3348-57. doi: 10.1128/AAC.00419-13. Epub 2013 May 6. PMID: 23650175; PMCID: PMC3697360. + +- [seqkit](https://pubmed.ncbi.nlm.nih.gov/27706213/) + +> Shen W, Le S, Li Y, Hu F. SeqKit: A Cross-Platform and Ultrafast Toolkit for FASTA/Q File Manipulation. PLoS One. 2016 Oct 5;11(10):e0163962. doi: 10.1371/journal.pone.0163962. PMID: 27706213; PMCID: PMC5051824. + ## Software packaging/containerisation tools - [Anaconda](https://anaconda.com) diff --git a/README.md b/README.md index 770a6da..6435ae3 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,13 @@ +[![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/funcprofiler) [![GitHub Actions CI Status](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml) [![GitHub Actions Linting Status](https://github.com/nf-core/funcprofiler/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/funcprofiler/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/funcprofiler/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/) -[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2) +[![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.1.0-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.1.0) [![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/) @@ -20,52 +21,67 @@ ## Introduction -**nf-core/funcprofiler** is a bioinformatics pipeline that ... +**nf-core/funcprofiler** is a bioinformatics pipeline for read-based functional profiling of microbiome sequencing data. It accepts short-read (Illumina) and long-read (Oxford Nanopore) FASTQ files and runs one or more functional profilers against user-supplied databases, producing gene family abundances, pathway abundances, pathway coverages, and antimicrobial resistance profiles. - +### Pipeline Summary - -1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) +![](./assets/pipeline_light.svg) + +Supported profilers and current status: + +1. [**HUMANn v3**](https://huttenhower.sph.harvard.edu/humann/) — functional profiling via MetaPhlAn + HUMANn 3 (`--run_humann_v3`) +2. [**HUMANn v4**](https://docs.google.com/document/d/1rCx5JkuO7wCKWrL8_-UJx_FkopJAfcDFtZktgPspak0/edit?tab=t.0#heading=h.i5hn0zprhwld) — functional profiling via MetaPhlAn + HUMANn 4 (`--run_humann_v4`) +3. [**FMH FunProfiler**](https://github.com/KoslickiLab/fmh-funprofiler) — sketch-based functional profiling (`--run_fmhfunprofiler`) +4. [**RGI**](https://github.com/arpcard/rgi) — antimicrobial resistance gene identification (`--run_rgi`, available) +5. [**mifaser**](https://bromberglab.org/project/mifaser/) — functional profiling via mifaser (`--run_mifaser`, available) +6. [**DIAMOND**](https://github.com/bbuchfink/diamond) — alignment with DIAMOND blastx (`--run_diamond`, work in progress / beta) +7. [**eggNOG-mapper**](https://github.com/eggnogdb/eggnog-mapper) — functional annotation, orthology assignments and domain prediction (`--run_eggnogmapper`, work in progress / beta) + +> [!WARNING] +> DIAMOND and eggNOG-mapper support is currently in beta and should be treated as work in progress. These modules are still being validated in the full pipeline, including database handling, output behavior, and downstream reporting. Use them with caution, expect potential issues, and independently review results before using them for production analyses or interpretation. ## 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. - - +Then prepare a databases sheet — see [docs/usage.md](docs/usage.md) for the full format. Here is an abbreviated example for running HUMANn (which requires 4 databases): -Now, you can run the pipeline using: +`databases.csv` - +```csv +tool,db_name,db_entity,db_params,db_type,db_path +humann_v3,uniref90_v3,humann_metaphlan,,,/data/databases/metaphlan_db +humann_v3,uniref90_v3,humann_nucleotide,,,/data/databases/chocophlan +humann_v3,uniref90_v3,humann_protein,,,/data/databases/uniref90_diamond +humann_v3,uniref90_v3,humann_utility,,,/data/databases/utility_mapping +``` + +Now, you can run the pipeline using: ```bash nextflow run nf-core/funcprofiler \ -profile \ --input samplesheet.csv \ - --outdir + --outdir \ + --databases databases.csv \ + --run_humann_v3 ``` > [!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/funcprofiler/usage) and the [parameter documentation](https://nf-co.re/funcprofiler/parameters). @@ -77,25 +93,24 @@ For more details about the output files and reports, please refer to the ## Credits -nf-core/funcprofiler was originally written by Nick Waters. +nf-core/funcprofiler was written by Nick Waters, Vini Salazar, Yixuan Yang, Mirae Baichoo. We thank the following people for their extensive assistance in the development of this pipeline: - +- Matthias Hörtenhuber +- James Fellows Yates +- Jonas Scheid ## 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 `#funcprofiler` channel](https://nfcore.slack.com/channels/funcprofiler) (you can join with [this invite](https://nf-co.re/join/slack)). ## Citations - - - An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. You can cite the `nf-core` publication as follows: diff --git a/assets/adaptivecard.json b/assets/adaptivecard.json deleted file mode 100644 index 4a0a4e4..0000000 --- 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/funcprofiler 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/methods_description_template.yml b/assets/methods_description_template.yml index d1de92d..7900625 100644 --- a/assets/methods_description_template.yml +++ b/assets/methods_description_template.yml @@ -3,7 +3,6 @@ description: "Suggested text and references to use when describing pipeline usag section_name: "nf-core/funcprofiler Methods Description" section_href: "https://github.com/nf-core/funcprofiler" plot_type: "html" -## TODO nf-core: Update the HTML below to your preferred methods description, e.g. add publication citation for this pipeline ## You inject any metadata in the Nextflow '${workflow}' object data: |

Methods

diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 4b613e4..6d55204 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -1,7 +1,7 @@ report_comment: > - This report has been generated by the nf-core/funcprofiler + This report has been generated by the nf-core/funcprofiler analysis pipeline. For information about how to interpret these results, please see the - documentation. + documentation. report_section_order: "nf-core-funcprofiler-methods-description": order: -1000 diff --git a/assets/nf-core-funcprofiler_logo_light.png b/assets/nf-core-funcprofiler_logo_light.png index e2abc52..2f68d36 100644 Binary files a/assets/nf-core-funcprofiler_logo_light.png and b/assets/nf-core-funcprofiler_logo_light.png differ diff --git a/assets/nf-metro_command.sh b/assets/nf-metro_command.sh new file mode 100644 index 0000000..61eb508 --- /dev/null +++ b/assets/nf-metro_command.sh @@ -0,0 +1,2 @@ +nf-metro render pipeline.mmd -o pipeline_light.svg --logo nf-core-funcprofiler_logo_light.png --theme light --animate +nf-metro render pipeline.mmd -o pipeline_nf-core.svg --logo nf-core-funcprofiler_logo_light.png --theme nfcore --animate diff --git a/assets/pipeline.mmd b/assets/pipeline.mmd new file mode 100644 index 0000000..c412e9f --- /dev/null +++ b/assets/pipeline.mmd @@ -0,0 +1,79 @@ +graph LR + %%metro line: qc | Preprocessing & QC | #4CAF50 + %%metro line: concat | Merge & Concat | #2196F3 + %%metro line: humann3 | HUMAnN v3 | #FF9800 + %%metro line: humann4 | HUMAnN v4 | #FF5722 + %%metro line: fmhfunprofiler | FMH FunProfiler | #E91E63 + %%metro line: rgi | RGI | #CDDC39 + %%metro line: mifaser | mifaser | #00BCD4 + %%metro line: diamond | DIAMOND | #9C27B0 + %%metro line: eggnog | eggNOG-mapper | #3F51B5 + %%metro line: multiqc | Reporting | #795548 + %%metro line: db | Database Prep | #607D8B + + subgraph input[Input] + input_short([Short Read\nFASTQ]) + input_dbs([Input Databases]) + sr_qc(Preprocess) + merge(MERGE_RUNS) + end + + subgraph profiling[Functional Profiling] + humann3(HUMAnN v3) + humann4(HUMAnN v4) + fmhfunprofiler(FMH FunProfiler) + RGI(RGI) + mifaser(mifaser) + diamond(DIAMOND) + eggnog_mapper(eggNOG-mapper) + end + + subgraph QC[Quality Check] + multiqc(MultiQC) + end + + subgraph Output[Output] + output([Results Directory]) + end + + %% DB Prep + input_dbs -->|db| humann3 + input_dbs -->|db| humann4 + input_dbs -->|db| fmhfunprofiler + input_dbs -->|db| RGI + input_dbs -->|db| mifaser + input_dbs -->|db| diamond + input_dbs -->|db| eggnog_mapper + + %% Preprocessing + input_short -->|qc| sr_qc + sr_qc -->|concat| merge + + %% Profiling split + merge -->|humann3| humann3 + merge -->|humann4| humann4 + merge -->|fmhfunprofiler| fmhfunprofiler + merge -->|rgi| RGI + merge -->|mifaser| mifaser + merge -->|diamond| diamond + merge -->|eggnog| eggnog_mapper + + %% Reporting + sr_qc -->|multiqc| multiqc + humann3 -->|multiqc| multiqc + humann4 -->|multiqc| multiqc + fmhfunprofiler -->|multiqc| multiqc + RGI -->|multiqc| multiqc + mifaser -->|multiqc| multiqc + diamond -->|multiqc| multiqc + eggnog_mapper -->|multiqc| multiqc + + %% Output + multiqc -->|multiqc| output + humann3 -->|humann3| output + humann4 -->|humann4| output + fmhfunprofiler -->|fmhfunprofiler| output + RGI -->|rgi| output + mifaser -->|mifaser| output + diamond -->|diamond| output + eggnog_mapper -->|eggnog| output diff --git a/assets/pipeline_light.svg b/assets/pipeline_light.svg new file mode 100644 index 0000000..450b48e --- /dev/null +++ b/assets/pipeline_light.svg @@ -0,0 +1,272 @@ + + + + + + + +1 + + + +2 + + + +3 + + + +4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Short ReadFASTQ +Input Databases +HUMAnN v3 +MultiQC +Results Directory +HUMAnN v4 +FMH FunProfiler +RGI +mifaser +DIAMOND +eggNOG-mapper +Preprocess +MERGE_RUNS + + + +Preprocessing & QC + +Merge & Concat + +HUMAnN v3 + +HUMAnN v4 + +FMH FunProfiler + +RGI + +mifaser + +DIAMOND + +eggNOG-mapper + +Reporting + +Database Prep +created with nf-metro v0.6.1 + diff --git a/assets/pipeline_nf-core.svg b/assets/pipeline_nf-core.svg new file mode 100644 index 0000000..2095688 --- /dev/null +++ b/assets/pipeline_nf-core.svg @@ -0,0 +1,267 @@ + + + + + + + +1 + + + +2 + + + +3 + + + +4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Short ReadFASTQ +Input Databases +HUMAnN v3 +MultiQC +Results Directory +HUMAnN v4 +FMH FunProfiler +RGI +mifaser +DIAMOND +eggNOG-mapper +Preprocess +MERGE_RUNS + + + +Preprocessing & QC + +Merge & Concat + +HUMAnN v3 + +HUMAnN v4 + +FMH FunProfiler + +RGI + +mifaser + +DIAMOND + +eggNOG-mapper + +Reporting + +Database Prep +created with nf-metro v0.6.1 + diff --git a/assets/schema_database.json b/assets/schema_database.json new file mode 100644 index 0000000..467adf1 --- /dev/null +++ b/assets/schema_database.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/nf-core/funcprofiler/master/assets/schema_database.json", + "title": "nf-core/funcprofiler pipeline - params.database schema", + "description": "Schema for the file provided with params.database", + "type": "array", + "items": { + "type": "object", + "properties": { + "tool": { + "type": "string", + "enum": ["humann_v3", "humann_v4", "fmhfunprofiler", "rgi", "mifaser", "diamond", "eggnogmapper"], + "errorMessage": "Invalid tool name. Please see documentation for all supported profilers.", + "meta": ["tool"] + }, + "db_name": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "The unique name of the database should be provided.", + "meta": ["db_name"] + }, + "db_entity": { + "type": "string", + "enum": [ + "humann_metaphlan", + "humann_nucleotide", + "humann_utility", + "humann_protein", + "eggnogmapper_db", + "eggnogmapper_data_dir" + ], + "errorMessage": "The unique name of the database entity should be provided. (eg, for HUMAnN, specify whether db_path is the humann_nucleotide, humann_protein, or humann_metaphlan database; for eggnogmapper, specify eggnogmapper_db or eggnogmapper_data_dir)", + "meta": ["db_entity"] + }, + "db_params": { + "type": "string", + "pattern": "^[^\"']*$", + "errorMessage": "Invalid database db_params entry. No quotes allowed.", + "meta": ["db_params"] + }, + "db_type": { + "type": "string", + "enum": ["short", "long", "short;long"], + "default": "short;long", + "meta": ["db_type"] + }, + "db_path": { + "type": "string", + "exists": true, + "format": "path", + "errorMessage": "db_path should be either a file path or a directory." + } + }, + "required": ["tool", "db_name", "db_path"] + }, + "uniqueEntries": ["tool", "db_name", "db_entity"] +} diff --git a/assets/schema_input.json b/assets/schema_input.json index 6529c93..9d03c20 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/nf-core/funcprofiler/main/assets/schema_input.json", + "$id": "https://raw.githubusercontent.com/nf-core/funcprofiler/master/assets/schema_input.json", "title": "nf-core/funcprofiler pipeline - params.input schema", "description": "Schema for the file provided with params.input", "type": "array", @@ -8,26 +8,61 @@ "type": "object", "properties": { "sample": { - "type": "string", - "pattern": "^\\S+$", - "errorMessage": "Sample name must be provided and cannot contain spaces", + "type": ["string", "integer"], + "pattern": "^[^\\s]+$", + "errorMessage": "Sample name must be a string or an integer and cannot contain spaces", "meta": ["id"] }, + "run_accession": { + "type": ["string", "integer"], + "pattern": "^[^\\s]+$", + "errorMessage": "Run accession must be provided and cannot contain spaces." + }, + "instrument_platform": { + "type": "string", + "enum": [ + "ABI_SOLID", + "BGISEQ", + "CAPILLARY", + "COMPLETE_GENOMICS", + "DNBSEQ", + "HELICOS", + "ILLUMINA", + "ION_TORRENT", + "LS454", + "OXFORD_NANOPORE", + "PACBIO_SMRT" + ], + "errorMessage": "Sequencing platform must be provided." + }, "fastq_1": { "type": "string", - "format": "file-path", "exists": true, - "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", - "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + "format": "file-path", + "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "errorMessage": "Gzipped FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" }, "fastq_2": { "type": "string", + "exists": true, "format": "file-path", + "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "errorMessage": "Gzipped FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'. If not applicable, leave it empty." + }, + "fasta": { + "type": "string", "exists": true, - "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", - "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + "format": "file-path", + "pattern": "^\\S+\\.(fasta|fas|fna|fa)\\.gz?$", + "errorMessage": "Gzipped FastA file must be provided, cannot contain spaces and must have extension '.fa.gz', 'fna.gz', 'fas.gz', or '.fasta.gz'. If not applicable, leave it empty." } }, - "required": ["sample", "fastq_1"] - } + "required": ["sample", "run_accession", "instrument_platform"] + }, + "allOf": [ + { "uniqueEntries": ["fastq_1"] }, + { "uniqueEntries": ["fastq_2"] }, + { "uniqueEntries": ["fasta"] }, + { "uniqueEntries": ["sample", "run_accession"] } + ] } diff --git a/assets/slackreport.json b/assets/slackreport.json deleted file mode 100644 index db3564c..0000000 --- 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/funcprofiler ${version} - ${runName}", - "author_icon": "https://www.nextflow.io/docs/latest/_static/favicon.ico", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors<% } %>", - "fields": [ - { - "title": "Command used to launch the workflow", - "value": "```${commandLine}```", - "short": false - } - <% - if (!success) { %> - , - { - "title": "Full error message", - "value": "```${errorReport}```", - "short": false - }, - { - "title": "Pipeline configuration", - "value": "<% out << summary.collect{ k,v -> k == "hook_url" ? "_${k}_: (_hidden_)" : ( ( v.class.toString().contains('Path') || ( v.class.toString().contains('String') && v.contains('/') ) ) ? "_${k}_: `${v}`" : (v.class.toString().contains('DateTime') ? ("_${k}_: " + v.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM))) : "_${k}_: ${v}") ) }.join(",\n") %>", - "short": false - } - <% } - %> - ], - "footer": "Completed at <% out << dateComplete.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM)) %> (duration: ${duration})" - } - ] -} diff --git a/conf/base.config b/conf/base.config index 05c9d05..49af73f 100644 --- a/conf/base.config +++ b/conf/base.config @@ -10,12 +10,11 @@ process { - // TODO nf-core: Check the defaults for all processes cpus = { 1 * task.attempt } 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' @@ -24,7 +23,6 @@ process { // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. // If possible, it would be nice to keep the same label naming convention when // adding in your local modules too. - // TODO nf-core: Customise requirements for specific processes. // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_single { cpus = { 1 } @@ -49,6 +47,9 @@ process { withLabel:process_long { time = { 20.h * task.attempt } } + withLabel:process_low_memory { + memory = { 1.GB * task.attempt } + } withLabel:process_high_memory { memory = { 200.GB * task.attempt } } diff --git a/conf/containers_conda_lock_files_amd64.config b/conf/containers_conda_lock_files_amd64.config new file mode 100644 index 0000000..375bc63 --- /dev/null +++ b/conf/containers_conda_lock_files_amd64.config @@ -0,0 +1,3 @@ +process { withName: 'FASTQC' { conda = 'modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt' } } +process { withName: 'MULTIQC' { conda = 'modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt' } } +process { withName: 'RGI_BWT' { conda = 'modules/nf-core/rgi/bwt/.conda-lock/linux_amd64-bd-e905ecb8305e2609_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 0000000..f10a4e3 --- /dev/null +++ b/conf/containers_conda_lock_files_arm64.config @@ -0,0 +1,3 @@ +process { withName: 'FASTQC' { conda = 'modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt' } } +process { withName: 'MULTIQC' { conda = 'modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt' } } +process { withName: 'RGI_BWT' { conda = 'modules/nf-core/rgi/bwt/.conda-lock/linux_arm64-bd-fab5219836c1d880_1.txt' } } diff --git a/conf/containers_docker_amd64.config b/conf/containers_docker_amd64.config new file mode 100644 index 0000000..d4a0596 --- /dev/null +++ b/conf/containers_docker_amd64.config @@ -0,0 +1,3 @@ +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.35--c17fb751507e9dfc' } } +process { withName: 'RGI_BWT' { container = 'community.wave.seqera.io/library/rgi_kma:e905ecb8305e2609' } } diff --git a/conf/containers_docker_arm64.config b/conf/containers_docker_arm64.config new file mode 100644 index 0000000..75dc75b --- /dev/null +++ b/conf/containers_docker_arm64.config @@ -0,0 +1,3 @@ +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.35--5c84a5000a226ab5' } } +process { withName: 'RGI_BWT' { container = 'community.wave.seqera.io/library/rgi_kma:fab5219836c1d880' } } diff --git a/conf/containers_singularity_https_amd64.config b/conf/containers_singularity_https_amd64.config new file mode 100644 index 0000000..d2714de --- /dev/null +++ b/conf/containers_singularity_https_amd64.config @@ -0,0 +1,3 @@ +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/c8/c8e346f4f6080eadf1253505e6ff09ef004454fc18e8d672006fd7b222cc412e/data' } } +process { withName: 'RGI_BWT' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/3f/3f452c8e124ee58ab6b26442d15401c57d471cb753f53921570dc484df4e7620/data' } } diff --git a/conf/containers_singularity_https_arm64.config b/conf/containers_singularity_https_arm64.config new file mode 100644 index 0000000..d80474b --- /dev/null +++ b/conf/containers_singularity_https_arm64.config @@ -0,0 +1,3 @@ +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/e4/e48aa28aebc881254a499b24c3e1ce77b8df1b85a5432699ed6f72eb17ac7fb5/data' } } +process { withName: 'RGI_BWT' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e83b71b5dae10e1d771490c36f49d314718888c3cc8214350eb7f149090f0e/data' } } diff --git a/conf/containers_singularity_oras_amd64.config b/conf/containers_singularity_oras_amd64.config new file mode 100644 index 0000000..1fb613f --- /dev/null +++ b/conf/containers_singularity_oras_amd64.config @@ -0,0 +1,3 @@ +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.35--c680f2aea25ccec2' } } +process { withName: 'RGI_BWT' { container = 'oras://community.wave.seqera.io/library/rgi_kma:06c9375141c15d16' } } diff --git a/conf/containers_singularity_oras_arm64.config b/conf/containers_singularity_oras_arm64.config new file mode 100644 index 0000000..5a52534 --- /dev/null +++ b/conf/containers_singularity_oras_arm64.config @@ -0,0 +1,3 @@ +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.35--c0468833d65b2f81' } } +process { withName: 'RGI_BWT' { container = 'oras://community.wave.seqera.io/library/rgi_kma:a6eaadaaffbeaf85' } } diff --git a/conf/igenomes.config b/conf/igenomes.config index 3f11437..b8c8154 100644 --- a/conf/igenomes.config +++ b/conf/igenomes.config @@ -8,433 +8,431 @@ ---------------------------------------------------------------------------------------- */ -params { +params.genomes = [ // illumina iGenomes reference file paths - genomes { - 'GRCh37' { - fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/GRCh37-blacklist.bed" - } - 'GRCh38' { - fasta = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'CHM13' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAIndex/" - bwamem2 = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAmem2Index/" - gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/CHM13/Annotation/Genes/genes.gtf" - gff = "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/009/914/755/GCF_009914755.1_T2T-CHM13v2.0/GCF_009914755.1_T2T-CHM13v2.0_genomic.gff.gz" - mito_name = "chrM" - } - 'GRCm38' { - fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/GRCm38-blacklist.bed" - } - 'TAIR10' { - fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt" - mito_name = "Mt" - } - 'EB2' { - fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt" - } - 'UMD3.1' { - fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt" - mito_name = "MT" - } - 'WBcel235' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" - mito_name = "MtDNA" - macs_gsize = "9e7" - } - 'CanFam3.1' { - fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt" - mito_name = "MT" - } - 'GRCz10' { - fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'BDGP6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" - mito_name = "M" - macs_gsize = "1.2e8" - } - 'EquCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt" - mito_name = "MT" - } - 'EB1' { - fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt" - } - 'Galgal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Gm01' { - fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt" - } - 'Mmul_1' { - fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt" - mito_name = "MT" - } - 'IRGSP-1.0' { - fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'CHIMP2.1.4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt" - mito_name = "MT" - } - 'Rnor_5.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Rnor_6.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'R64-1-1' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" - mito_name = "MT" - macs_gsize = "1.2e7" - } - 'EF2' { - fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.21e7" - } - 'Sbi1' { - fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt" - } - 'Sscrofa10.2' { - fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt" - mito_name = "MT" - } - 'AGPv3' { - fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'hg38' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'hg19' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg19-blacklist.bed" - } - 'mm10' { - fasta = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/mm10-blacklist.bed" - } - 'bosTau8' { - fasta = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'ce10' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "9e7" - } - 'canFam3' { - fasta = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt" - mito_name = "chrM" - } - 'danRer10' { - fasta = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.37e9" - } - 'dm6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.2e8" - } - 'equCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt" - mito_name = "chrM" - } - 'galGal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt" - mito_name = "chrM" - } - 'panTro4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt" - mito_name = "chrM" - } - 'rn6' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'sacCer3' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/" - readme = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.2e7" - } - 'susScr3' { - fasta = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt" - mito_name = "chrM" - } - } -} + 'GRCh37' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/GRCh37-blacklist.bed", + ], + 'GRCh38' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg38-blacklist.bed", + ], + 'CHM13' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAIndex/", + bwamem2 : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAmem2Index/", + gtf : "${params.igenomes_base}/Homo_sapiens/NCBI/CHM13/Annotation/Genes/genes.gtf", + gff : "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/009/914/755/GCF_009914755.1_T2T-CHM13v2.0/GCF_009914755.1_T2T-CHM13v2.0_genomic.gff.gz", + mito_name : "chrM", + ], + 'GRCm38' : [ + fasta : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "1.87e9", + blacklist : "${projectDir}/assets/blacklists/GRCm38-blacklist.bed", + ], + 'TAIR10' : [ + fasta : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt", + mito_name : "Mt", + ], + 'EB2' : [ + fasta : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt", + ], + 'UMD3.1' : [ + fasta : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt", + mito_name : "MT", + ], + 'WBcel235' : [ + fasta : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed", + mito_name : "MtDNA", + macs_gsize : "9e7", + ], + 'CanFam3.1' : [ + fasta : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt", + mito_name : "MT", + ], + 'GRCz10' : [ + fasta : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'BDGP6' : [ + fasta : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed", + mito_name : "M", + macs_gsize : "1.2e8", + ], + 'EquCab2' : [ + fasta : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt", + mito_name : "MT", + ], + 'EB1' : [ + fasta : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt", + ], + 'Galgal4' : [ + fasta : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'Gm01' : [ + fasta : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt", + ], + 'Mmul_1' : [ + fasta : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt", + mito_name : "MT", + ], + 'IRGSP-1.0' : [ + fasta : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed", + mito_name : "Mt", + ], + 'CHIMP2.1.4' : [ + fasta : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt", + mito_name : "MT", + ], + 'Rnor_5.0' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'Rnor_6.0' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'R64-1-1' : [ + fasta : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed", + mito_name : "MT", + macs_gsize : "1.2e7", + ], + 'EF2' : [ + fasta : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "1.21e7", + ], + 'Sbi1' : [ + fasta : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt", + ], + 'Sscrofa10.2' : [ + fasta : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt", + mito_name : "MT", + ], + 'AGPv3' : [ + fasta : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed", + mito_name : "Mt", + ], + 'hg38' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg38-blacklist.bed", + ], + 'hg19' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg19-blacklist.bed", + ], + 'mm10' : [ + fasta : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "1.87e9", + blacklist : "${projectDir}/assets/blacklists/mm10-blacklist.bed", + ], + 'bosTau8' : [ + fasta : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed", + mito_name : "chrM", + ], + 'ce10' : [ + fasta : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "9e7", + ], + 'canFam3' : [ + fasta : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt", + mito_name : "chrM", + ], + 'danRer10' : [ + fasta : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "1.37e9", + ], + 'dm6' : [ + fasta : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "1.2e8", + ], + 'equCab2' : [ + fasta : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt", + mito_name : "chrM", + ], + 'galGal4' : [ + fasta : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt", + mito_name : "chrM", + ], + 'panTro4' : [ + fasta : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt", + mito_name : "chrM", + ], + 'rn6' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed", + mito_name : "chrM", + ], + 'sacCer3' : [ + fasta : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/", + readme : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "1.2e7", + ], + 'susScr3' : [ + fasta : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt", + mito_name : "chrM", + ], +] diff --git a/conf/modules.config b/conf/modules.config index d203d2b..17eb876 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,14 +21,72 @@ process { withName: FASTQC { ext.args = '--quiet' } - + withName: UNTAR { + ext.prefix = { "${archive.simpleName}" } + publishDir = [ + path: { "${params.outdir}/untar/databases" }, + mode: params.publish_dir_mode, + enabled: params.save_untarred_databases, + ] + } + // humann4 requires a metaphlan profile with the extra columns provided by -t rel_ab_w_read_stats + withName: MPAHUMANN4 { + container = 'ghcr.io/vdblab/biobakery-profiler:4.0.6--4.0.0.alpha.1-final_smaller-pt2' + ext.args = '-t rel_ab_w_read_stats' + } + withName: HUMANN3_HUMANN { + publishDir = [ + path: { "${params.outdir}/humann3/" }, + mode: params.publish_dir_mode, + pattern: '*.{tsv.gz,log,.command.*}' + ] + } + withName: HUMANN4 { + publishDir = [ + path: { "${params.outdir}/humann4/" }, + mode: params.publish_dir_mode, + pattern: '*.{tsv.gz,log,.command.*}' + ] + } + withName: FMHFUNPROFILER { + ext.prefix = { "${meta.id}_${ko_sketch.baseName}.fmhfunprofiler" } + publishDir = [ + path: { "${params.outdir}/fmhfunprofiler/${ko_sketch}/" }, + mode: params.publish_dir_mode, + pattern: '*.{csv}' + ] + } + withName: RGI_BWT { + publishDir = [ + path: { "${params.outdir}/rgi/${meta.db_name}/" }, + mode: params.publish_dir_mode, + pattern: '*.{txt,json}' + ] + } + withName: DIAMOND_BLASTX { + // DBPREP stores '-' when a database row carries no db_params + ext.args = { meta.db_params && meta.db_params != '-' ? "${meta.db_params}" : '' } + ext.prefix = { "${meta.id}_${meta.db_name}.diamond" } + publishDir = [ + path: { "${params.outdir}/diamond/${meta.db_name}/" }, + mode: params.publish_dir_mode, + pattern: '*.{blast,xml,txt,daa,sam,tsv,paf,log}' + ] + } + withName: EGGNOGMAPPER { + ext.args = "--itype metagenome --genepred search --sensmode fast --pident 90 --query_cover 80" + // .emapper.hits is unpublished: several GB/sample, and reannotation uses the seed orthologs + publishDir = [ + path: { "${params.outdir}/eggnogmapper/" }, + mode: params.publish_dir_mode, + pattern: '*.{emapper.annotations,emapper.seed_orthologs}' + ] + } withName: 'MULTIQC' { ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } publishDir = [ path: { "${params.outdir}/multiqc" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } - } diff --git a/conf/test.config b/conf/test.config index 9f7ea72..e01414a 100644 --- a/conf/test.config +++ b/conf/test.config @@ -19,12 +19,15 @@ process { } params { - config_profile_name = 'Test profile' - config_profile_description = 'Minimal test dataset to check pipeline function' - - // Input data - // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets - // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv'// Genome references - genome = 'R64-1-1' + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + input = params.pipelines_testdata_base_path + 'funcprofiler/samplesheets/test.csv' + databases = params.pipelines_testdata_base_path + 'funcprofiler/database.csv' + run_fmhfunprofiler = true + run_humann_v3 = true + run_mifaser = true + run_diamond = false + run_humann_v4 = false + run_rgi = true + run_eggnogmapper = false } diff --git a/conf/test_full.config b/conf/test_full.config index 0568518..51aa7ef 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -11,14 +11,14 @@ */ params { - config_profile_name = 'Full test profile' - config_profile_description = 'Full test dataset to check pipeline function' - - // Input data for full size test - // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) - // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_full_illumina_amplicon.csv' - - // Genome references - genome = 'R64-1-1' + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/taxprofiler/samplesheet_shortreadsonly.csv' + databases = params.pipelines_testdata_base_path + 'funcprofiler/database_full.csv' + run_fmhfunprofiler = true + run_humann_v3 = true + run_mifaser = false + run_diamond = false + run_rgi = true + run_eggnogmapper = false } diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..95b80c6 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,190 @@ +--- +title: Contributing +markdownPlugin: checklist +--- + +# `nf-core/funcprofiler`: Contributing guidelines + +Hi there! +Thanks for taking an interest in improving nf-core/funcprofiler. + +This page describes the recommended nf-core way to contribute to both nf-core/funcprofiler 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/funcprofiler. + +> [!NOTE] +> If you need help using or modifying nf-core/funcprofiler, ask on the nf-core Slack [#funcprofiler](https://nfcore.slack.com/channels/funcprofiler) 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/funcprofiler/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/funcprofiler repository](https://github.com/nf-core/funcprofiler) to your GitHub account. +- [ ] Create a branch on your forked repository and make your changes following [pipeline conventions](#pipeline-contribution-conventions) (if applicable). +- [ ] To fix major bugs, name your branch `patch` and follow the [patch release](#patch-release) process. +- [ ] Update relevant documentation within the `docs/` folder, use nf-core/tools to update `nextflow_schema.json`, and update `CITATIONS.md`. +- [ ] Run and/or update tests. See [Testing](#testing) for more information. +- [ ] [Lint](#lint-tests) your code with nf-core/tools. +- [ ] Submit a pull request (PR) against the `dev` branch and request a review. + +If you are not used to this workflow with Git, see the [GitHub documentation](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or [Git resources](https://try.github.io/) for more information. + +## Use of AI and LLMs + +The nf-core stance on the use of AI and LLMs is that humans are still ultimately responsible for their submitted code, regardless of the tools they use. + +If you’re using AI tools, try to stick by these guidelines: + +- Keep PRs as small and focused 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 [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/funcprofiler documentation](https://nf-co.re/funcprofiler/usage) or ask on the nf-core [#funcprofiler](https://nfcore.slack.com/channels/funcprofiler) Slack channel ([join our Slack here](https://nf-co.re/join/slack)). + +### GitHub Codespaces + +You can contribute to nf-core/funcprofiler 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/funcprofiler/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/funcprofiler 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-tests) 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 `${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 + +When adding a new profiler: + +- Add it to [nf-core/modules](https://github.com/nf-core/modules) rather than to `modules/local`. A local module is only a stopgap for tools that are not yet packaged on Bioconda. +- Gate it behind a `run_` parameter, and take its database from the database sheet so it is grouped by `dbprep` like every other tool. +- Add it to the `profile` subworkflow, to `docs/output.md`, and to `CITATIONS.md`. +- Cover it with an nf-test, and regenerate snapshots with `nf-test test --update-snapshot`. diff --git a/docs/images/nf-core-funcprofiler_logo_dark.png b/docs/images/nf-core-funcprofiler_logo_dark.png index 7e733e3..105ef36 100644 Binary files a/docs/images/nf-core-funcprofiler_logo_dark.png and b/docs/images/nf-core-funcprofiler_logo_dark.png differ diff --git a/docs/images/nf-core-funcprofiler_logo_light.png b/docs/images/nf-core-funcprofiler_logo_light.png index a67fe7a..2ce2a8d 100644 Binary files a/docs/images/nf-core-funcprofiler_logo_light.png and b/docs/images/nf-core-funcprofiler_logo_light.png differ diff --git a/docs/output.md b/docs/output.md index 5f1fbf1..3d6ad22 100644 --- a/docs/output.md +++ b/docs/output.md @@ -6,49 +6,106 @@ This document describes the output produced by the pipeline. Most of the plots a The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. - - ## Pipeline overview The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes data using the following steps: -- [FastQC](#fastqc) - Raw read QC +- [FastQC](#fastqc) - Raw read QC and preprocessing +- [HUMAnN v3 / v4](#humann-v3--v4) - Functional profiling via MetaPhlAn + HUMAnN +- [FMH FunProfiler](#fmh-funprofiler) - Sketch-based functional profiling +- [mifaser](#mifaser) - Read-level functional profiling +- [DIAMOND blastx](#diamond-blastx) - Translated alignment against a protein database (work in progress / beta) +- [EggNOG-mapper](#eggnog-mapper) - Functional annotation via orthology assignment (work in progress / beta) +- [RGI BWT](#rgi-bwt) - Antimicrobial resistance gene identification - [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution +:::note +Other than FastQC, MultiQC and pipeline information, all other steps (the profilers) are off by default, and must be switched on manually. +::: + ### FastQC -
-Output files +[FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content, adapter contamination, and overrepresented sequences. For further reading and documentation see the [FastQC help pages](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). - `fastqc/` - - `*_fastqc.html`: FastQC report containing quality metrics. - - `*_fastqc.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. + - `*_fastqc.html`: FastQC report containing quality metrics for each sample. + - `*_fastqc.zip`: Zip archive containing the FastQC report and data files. + +### HUMAnN v3 / v4 + +[HUMAnN](https://huttenhower.sph.harvard.edu/humann/) (HMP Unified Metabolic Analysis Network) is a method for efficiently and accurately profiling the presence/absence and abundance of microbial pathways in a community from metagenomic or metatranscriptomic sequencing data. Enabled with `--run_humann_v3` or `--run_humann_v4`. HUMAnN 4 is in alpha status; it will become the default when fully released. Each sample is first run through MetaPhlAn to generate a taxonomic profile, which guides HUMAnN functional profiling. + +- `humann_v3//` or `humann_v4//` + - `*_genefamilies.tsv`: Gene family abundances in reads per kilobase (RPK), stratified by contributing species. + - `*_pathabundance.tsv`: Metabolic pathway abundances in RPK, stratified by species contribution. + - `*_pathcoverage.tsv`: Pathway coverage scores (0–1), indicating the fraction of reactions detected per pathway. +- `metaphlan//` + - `*_profile.txt`: Species-level taxonomic abundance profile used as input to HUMAnN. + +### FMH FunProfiler + +[FMH FunProfiler](https://github.com/vdblab/fmhfunprofiler) uses FracMinHash sketching to rapidly assign reads to KEGG Orthology (KO) functional categories. Enabled with `--run_fmhfunprofiler`. + +- `fmhfunprofiler//` + - `*.fmhfunprofiler.ko`: KO (KEGG Orthology) abundance table for the sample. + +### mi-faser + +[mi-faser](https://bromberglab.org/project/mifaser/) maps reads to functional databases at the protein level to produce enzyme function profiles. Enabled with `--run_mifaser`. + +- `mifaser///` + - `analysis.tsv`: Tab-separated table of functional assignments with read counts per enzyme function (EC number). + - `analysis.log`: Log file with run statistics including number of reads processed and assigned. + +### DIAMOND blastx + +Enabled with `--run_diamond`. Performs fast translated alignment of (meta)genomic reads against a protein reference database. Each read is aligned in all six reading frames and only significant hits are reported. + +:::warning +DIAMOND support is currently in beta and should be treated as work in progress. The module is still being validated in the full pipeline, including database handling, output behavior, and downstream reporting. Use with caution and independently review results before production use or interpretation. +::: -
+- `diamond//` + - `*.tsv`: Tabular alignment results (BLAST tabular format 6) with one row per query-subject hit. + - `*.log`: DIAMOND run log containing alignment statistics (query count, alignment rate, etc.). -[FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content (%A/T/G/C), adapter contamination and overrepresented sequences. For further reading and documentation see the [FastQC help pages](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). +### EggNOG-mapper + +Enabled with `--run_eggnogmapper`. Assigns functional annotations to sequences by mapping them to orthologous groups in the EggNOG database. + +:::warning +EggNOG-mapper support is currently in beta and should be treated as work in progress. The module is still being validated in the full pipeline, including database handling, output behavior, and downstream reporting. Use with caution and independently review results before production use or interpretation. +::: + +- `eggnogmapper//` + - `*.emapper.annotations`: TSV file with functional annotations per query sequence, including GO terms, KEGG pathways, COG categories, and more. + - `*.emapper.seed_orthologs`: TSV linking query sequences to their best seed orthologs _(optional, produced when search is performed)_. Pass this back to `emapper.py -m no_search --annotate_hits_table` to reannotate against a newer eggNOG release without repeating the search. + +The search phase also writes `*.emapper.hits`, the full hit table for every query. It is a big file and not used very often, so it doesn't get published by default. + +### RGI BWT + +[RGI](https://github.com/arpcard/rgi) (Resistance Gene Identifier) aligns reads against the CARD database using Bowtie2/BWA to identify antimicrobial resistance genes. Enabled with `--run_rgi`. + +- `rgi//` + - `*.txt`: Tab-separated AMR gene hit table with gene family, resistance mechanism, drug class, and read counts. + - `*.json`: Full RGI output in JSON format with detailed per-hit annotations. ### MultiQC -
-Output files +[MultiQC](http://multiqc.info) is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. - `multiqc/` - `multiqc_report.html`: a standalone HTML file that can be viewed in your web browser. - `multiqc_data/`: directory containing parsed statistics from the different tools used in the pipeline. - `multiqc_plots/`: directory containing static images from the report in various formats. -
- -[MultiQC](http://multiqc.info) is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. - Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQC. The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . ### Pipeline information -
-Output files +[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. - `pipeline_info/` - Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. @@ -56,6 +113,4 @@ Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQ - Reformatted samplesheet files used as input to the pipeline: `samplesheet.valid.csv`. - Parameters used by the pipeline run: `params.json`. -
- -[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. +[Nextflow](https://docs.seqera.io/platform-cloud/reports/overview) 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 9c0d947..d3cc90a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -6,7 +6,7 @@ ## Introduction - +**nf-core/funcprofiler** performs read-based functional profiling of microbiome sequencing data. It requires two input CSV files: a samplesheet describing your samples and a databases sheet describing the profiling databases to use. ## Samplesheet input @@ -16,48 +16,197 @@ You will need to create a samplesheet with information about the samples you wou --input '[path to samplesheet file]' ``` -### Multiple runs of the same sample +The samplesheet is a comma-separated file with the following columns: -The `sample` identifiers have to be the same when you have re-sequenced the same sample more than once e.g. to increase sequencing depth. The pipeline will concatenate the raw reads before performing any downstream analysis. Below is an example for the same sample sequenced across 3 lanes: +| Column | Required | Description | +| --------------------- | -------- | ----------------------------------------------------------------------------------------------------------------- | +| `sample` | Yes | Sample name. Rows with the same `sample` name (and different `run_accession`) are merged before profiling. | +| `run_accession` | Yes | Unique run identifier (e.g. `RUN1`, `SRR12345`). Used to distinguish multiple sequencing runs of the same sample. | +| `instrument_platform` | Yes | Sequencing platform. Must be one of: `ILLUMINA`, `ION_TORRENT`, `BGISEQ`, `DNBSEQ`, or `LS454`. | +| `fastq_1` | Yes | Full path to gzipped FASTQ file for read 1. Must end in `.fastq.gz` or `.fq.gz`. | +| `fastq_2` | No | Full path to gzipped FASTQ file for read 2 (paired-end only). Leave empty for single-end or Nanopore reads. | +| `fasta` | No | This column is unused, but retained for compatibility with nf-core/taxprofiler. | -```csv title="samplesheet.csv" -sample,fastq_1,fastq_2 -CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz +:::note +\* `fastq_1` must be provided for each row! We do **not** support `OXFORD_NANOPORE` or `PACBIO_SMRT` unput platforms, as long reads are incompatible (or at least, require nuanced interpretation) with most of these tools. Similarly, we do not support `fasta` input, as assembly-based pipelines like nf-core/funcscan would be more appropriate. +::: + +### Example samplesheet + +```csv +sample,run_accession,instrument_platform,fastq_1,fastq_2,fasta +SAMPLE1,RUN1,ILLUMINA,/data/sample1_R1.fastq.gz,/data/sample1_R2.fastq.gz, +SAMPLE1,RUN2,ILLUMINA,/data/sample1_lane2_R1.fastq.gz,/data/sample1_lane2_R2.fastq.gz, +SAMPLE2,RUN1,ILLUMINA,/data/sample2_R1.fastq.gz,, +``` + +In this example, `SAMPLE1` has two runs which will be merged before profiling. `SAMPLE2` is single-end short reads. . + +## Enabling profilers + +The pipeline will only run the profilers you explicitly turn on, and for which a database has been specified in your database samplesheet: + +| Flag | Profiler | Status | +| ---------------------- | --------------- | ----------------------- | +| `--run_humann_v3` | HUMANn v3 | Available | +| `--run_humann_v4` | HUMANn v4 | Available | +| `--run_fmhfunprofiler` | FMH FunProfiler | Available | +| `--run_mifaser` | mifaser | Available | +| `--run_diamond` | diamond | Work in progress / beta | +| `--run_eggnogmapper` | EggNOG-mapper | Work in progress / beta | +| `--run_rgi` | RGI BWT | Available | + +:::info +Each `--run_` flag requires a matching database entry in the `--databases` CSV. Database rows for tools that are not enabled will be ignored. +::: + +## Databases input + +```bash +--databases '[path to databases file]' +``` + +The databases sheet is a comma-separated file that specifies which databases to use for each profiler. Only tools enabled via `--run_` flags will use the corresponding database entries. + +Use the `db_name` column to record the database release or version used for the run, for example `uniref90_v3`, `eggnog_v5`, `card_v3`, or `GS-24-all`. + +| Column | Required | Description | +| ----------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `tool` | Yes | Profiler name. Must be one of: `humann_v3`, `humann_v4`, `fmhfunprofiler`, `mifaser`, `diamond`, `rgi`, `eggnogmapper`. | +| `db_name` | Yes | Unique identifier for this database set. All HUMANn database components must share the same `db_name`. | +| `db_entity` | No | For HUMANn: specifies the component (`humann_metaphlan`, `humann_nucleotide`, `humann_protein`, `humann_utility`). For EggNOG-mapper: `eggnogmapper_db` or `eggnogmapper_data_dir`. | +| `db_params` | No | Additional parameters to pass to the profiler (no quotes allowed). | +| `db_path` | Yes | Absolute path to the database file or directory. Gzipped TAR archives (`.tar.gz`) are automatically decompressed. | + +### HUMANn databases + +HUMANn requires four database components per named database, each as a separate row with the same `db_name`. The example below uses a HUMANn v3-compatible UniRef90 database set; replace `uniref90_v3` with the exact release or version used in your analysis. + +```csv +tool,db_name,db_entity,db_params,db_type,db_path +humann_v3,uniref90_v3,humann_metaphlan,,,/data/databases/metaphlan_db +humann_v3,uniref90_v3,humann_nucleotide,,,/data/databases/chocophlan +humann_v3,uniref90_v3,humann_protein,,,/data/databases/uniref90_diamond +humann_v3,uniref90_v3,humann_utility,,,/data/databases/utility_mapping ``` -### Full samplesheet +### FMH FunProfiler databases + +FMH FunProfiler requires a single sketch database. The example below uses a KEGG-derived sketch database labeled `kegg_v1`; replace this with the exact sketch/database version used in your analysis. -The pipeline will auto-detect whether a sample is single- or paired-end using the information provided in the samplesheet. The samplesheet can have as many columns as you desire, however, there is a strict requirement for the first 3 columns to match those defined in the table below. +```csv +tool,db_name,db_entity,db_params,db_type,db_path +fmhfunprofiler,kegg_v1,,,short;long,/data/databases/fmhfunprofiler_kegg.sig.zip +``` -A final samplesheet file consisting of both single- and paired-end data may look something like the one below. This is for 6 samples, where `TREATMENT_REP3` has been sequenced twice. +### EggNOG-mapper databases -```csv title="samplesheet.csv" -sample,fastq_1,fastq_2 -CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz -CONTROL_REP2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz -CONTROL_REP3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz -TREATMENT_REP1,AEG588A4_S4_L003_R1_001.fastq.gz, -TREATMENT_REP2,AEG588A5_S5_L003_R1_001.fastq.gz, -TREATMENT_REP3,AEG588A6_S6_L003_R1_001.fastq.gz, -TREATMENT_REP3,AEG588A6_S6_L004_R1_001.fastq.gz, +[EggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) requires two database entries per named database: the search database and the EggNOG data directory. The `db_params` field of the `eggnogmapper_db` row must specify the search mode (e.g. `diamond`, `mmseqs`, `hmmer`). The example below uses an EggNOG v5 database label; replace `eggnog_v5` with the exact EggNOG database release used in your analysis. + +:::warning +EggNOG-mapper support is currently in beta and should be treated as work in progress. Database handling, output behavior, and downstream reporting are still being validated in the full pipeline, so use with caution and independently review results before production use or interpretation. +::: + +```csv +tool,db_name,db_entity,db_params,db_type,db_path +eggnogmapper,eggnog_v5,eggnogmapper_db,diamond,,/data/databases/eggnog_mapper/eggnog_proteins.dmnd +eggnogmapper,eggnog_v5,eggnogmapper_data_dir,,,/data/databases/eggnog_mapper/data ``` -| Column | Description | -| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | -| `fastq_1` | Full path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `fastq_2` | Full path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | +:::note +The EggNOG data directory can be downloaded with `download_eggnog_data.py` from the eggnog-mapper package. See the [EggNOG-mapper documentation](https://github.com/eggnogdb/eggnog-mapper/wiki) for details. +::: + +### mi-faser -An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline. +[mi-faser](https://bromberglab.org/project/mifaser/) performs functional profiling by mapping reads to functional databases at the protein level. It supports both short-read and long-read data. Enable with `--run_mifaser`. + +#### Database preparation + +Download a pre-built mifaser database (e.g. GS-21, GS-24-all, or GS-580) from the [mifaser website](https://bromberglab.org/project/mifaser/). The `db_path` should point to the directory containing the database files and `db_name` should record the downloaded database version. + +```csv +tool,db_name,db_entity,db_params,db_type,db_path +mifaser,GS-24-all,,,short,/data/databases/mifaser/GS-24-all +``` + +### Full example databases sheet + +This example uses versioned database names to make the database releases traceable in the run outputs. Replace these names and paths with the exact database releases you downloaded. + +```csv +tool,db_name,db_entity,db_params,db_type,db_path +humann_v3,uniref90_v3,humann_metaphlan,,,/data/databases/metaphlan_db +humann_v3,uniref90_v3,humann_nucleotide,,,/data/databases/chocophlan +humann_v3,uniref90_v3,humann_protein,,,/data/databases/uniref90_diamond +humann_v3,uniref90_v3,humann_utility,,,/data/databases/utility_mapping +humann_v4,uniref90_v4,humann_metaphlan,,,/data/databases/metaphlan4_db +humann_v4,uniref90_v4,humann_nucleotide,,,/data/databases/chocophlan_v4 +humann_v4,uniref90_v4,humann_protein,,,/data/databases/uniref90_v4_diamond +humann_v4,uniref90_v4,humann_utility,,,/data/databases/utility_mapping_v4 +fmhfunprofiler,kegg_v1,,,short;long,/data/databases/fmhfunprofiler_kegg.sig.zip +``` + +### RGI BWT + +[RGI](https://card.mcmaster.ca/about) (Resistance Gene Identifier) uses the Comprehensive Antibiotic Resistance Database (CARD) to identify AMR genes. The `bwt` subcommand aligns reads directly to CARD using Bowtie2/BWA. Enable with `--run_rgi`. + +#### Database preparation + +Download the CARD database and extract it to a directory. The example CSV below labels the database as `card_v3`; replace this with the exact CARD release used in your analysis. + +```bash +wget https://card.mcmaster.ca/latest/data +tar -xvf data ./card.json +rgi load --card_json card.json --local +``` + +The `db_path` in the databases CSV must point to the directory containing `card.json` and the pre-built CARD annotation files (`card_database_v*.fasta`). + +```csv +tool,db_name,db_entity,db_params,db_type,db_path +rgi,card_v3,,,,/data/databases/card +``` + +:::note +Wildcard variant databases are not currently supported by the pipeline. Only the core CARD database is used. +::: + +### DIAMOND blastx + +[DIAMOND](https://github.com/bbuchfink/diamond/wiki/) is a high-throughput sequence aligner for translated (nucleotide-vs-protein) alignment. Enable it with `--run_diamond`. + +:::warning +DIAMOND support is currently in beta and should be treated as work in progress. Database handling, output behavior, and downstream reporting are still being validated in the full pipeline, so use with caution and independently review results before production use or interpretation. +::: + +#### Database preparation + +The database supplied in the `--databases` CSV must already be in DIAMOND binary format (`.dmnd`). Build it from a versioned protein FASTA using `diamond makedb`, and use `db_name` to record the source database and release. + +```bash +diamond makedb --in proteins.faa --db proteins +# produces proteins.dmnd +``` + +See the [DIAMOND makedb documentation](https://github.com/bbuchfink/diamond/wiki/3.-Command-line-options#makedb-options) for all available options (e.g. adding taxonomy, setting block size). + +:::warning +The path should point to the **directory** containing the `.dmnd` file, not the file itself. The pipeline will automatically locate the `.dmnd` file within that directory. +::: ## Running the pipeline The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/funcprofiler --input ./samplesheet.csv --outdir ./results --genome GRCh37 -profile docker +nextflow run nf-core/funcprofiler \ + --input samplesheet.csv \ + --databases databases.csv \ + --outdir results \ + --run_humann_v3 \ + --run_fmhfunprofiler \ + -profile docker ``` This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. @@ -71,12 +220,15 @@ work # Directory containing the nextflow working files # Other nextflow hidden files, eg. history of pipeline runs and old logs. ``` +### Parameters + If you wish to repeatedly use the same parameters for multiple runs, rather than specifying each flag in the command, you can specify these in a params file. Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `. -> [!WARNING] -> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). +:::warning +Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). +::: The above pipeline run specified with a params file in yaml format: @@ -87,10 +239,10 @@ nextflow run nf-core/funcprofiler -profile docker -params-file params.yaml with: ```yaml title="params.yaml" -input: './samplesheet.csv' -outdir: './results/' -genome: 'GRCh37' -<...> +input: "./samplesheet.csv" +databases: "./databases.csv" +outdir: "./results/" +run_humann_v3: true ``` You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-co.re/launch). @@ -113,13 +265,15 @@ This version number will be logged in reports when you run the pipeline, so that To further assist in reproducibility, you can use share and reuse [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. -> [!TIP] -> If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. +:::tip +If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. +::: ## Core Nextflow arguments -> [!NOTE] -> These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen) +:::note +These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen) +::: ### `-profile` @@ -127,8 +281,9 @@ Use this parameter to choose a configuration profile. Profiles can give configur Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Apptainer, Conda) - see below. -> [!IMPORTANT] -> We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. +:::warning +We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. +::: The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to check if your system is supported, please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). @@ -149,11 +304,11 @@ 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` - - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). + - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow `24.03.0-edge` or later). - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. @@ -173,19 +328,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 e16f51d..4b07c09 100644 --- a/main.nf +++ b/main.nf @@ -15,21 +15,9 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { FUNCPROFILER } from './workflows/funcprofiler' +include { FUNCPROFILER } from './workflows/funcprofiler' include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_funcprofiler_pipeline' -include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_funcprofiler_pipeline' -include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_funcprofiler_pipeline' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GENOME PARAMETER VALUES -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// TODO nf-core: Remove this line if you don't need a FASTA file -// This is an example of how to use getGenomeAttribute() to fetch parameters -// from igenomes.config using `--genome` -params.fasta = getGenomeAttribute('fasta') +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_funcprofiler_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -41,18 +29,24 @@ params.fasta = getGenomeAttribute('fasta') // WORKFLOW: Run main analysis pipeline depending on type of input // workflow NFCORE_FUNCPROFILER { - take: samplesheet // channel: samplesheet read in from --input + databases // channel: databases in from --databases main: // // WORKFLOW: Run pipeline // - FUNCPROFILER ( - samplesheet + FUNCPROFILER( + samplesheet, + databases, + params.multiqc_config, + params.multiqc_logo, + params.multiqc_methods_description, + params.outdir, ) + emit: multiqc_report = FUNCPROFILER.out.multiqc_report // channel: /path/to/multiqc_report.html } @@ -63,42 +57,39 @@ workflow NFCORE_FUNCPROFILER { */ workflow { - - main: // // SUBWORKFLOW: Run initialisation tasks // - PIPELINE_INITIALISATION ( + PIPELINE_INITIALISATION( params.version, params.validate_params, params.monochrome_logs, args, params.outdir, - params.input + params.input, + params.databases, + params.help, + params.help_full, + params.show_hidden, ) // // WORKFLOW: Run main workflow // - NFCORE_FUNCPROFILER ( - PIPELINE_INITIALISATION.out.samplesheet + NFCORE_FUNCPROFILER( + PIPELINE_INITIALISATION.out.samplesheet, + PIPELINE_INITIALISATION.out.databases, ) // // SUBWORKFLOW: Run completion tasks // - PIPELINE_COMPLETION ( + PIPELINE_COMPLETION( params.email, params.email_on_fail, params.plaintext_email, params.outdir, params.monochrome_logs, params.hook_url, - NFCORE_FUNCPROFILER.out.multiqc_report + NFCORE_FUNCPROFILER.out.multiqc_report, ) } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ diff --git a/modules.json b/modules.json index 0e7d944..68fa76c 100644 --- a/modules.json +++ b/modules.json @@ -5,14 +5,84 @@ "https://github.com/nf-core/modules.git": { "modules": { "nf-core": { + "cat/fastq": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "diamond/blastx": { + "branch": "master", + "git_sha": "83ce9b314157a24d9a92f17a07ed5d55f30b78f9", + "installed_by": ["modules"] + }, + "eggnogmapper": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, "fastqc": { "branch": "master", - "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "fmhfunprofiler": { + "branch": "master", + "git_sha": "da290c59a571dbc2fddcd9b87b69b7517cad6a94", + "installed_by": ["modules"] + }, + "gunzip": { + "branch": "master", + "git_sha": "0902eac3012baaf4f9ab6513c8c55acc9353c96c", + "installed_by": ["modules"] + }, + "humann3/humann": { + "branch": "master", + "git_sha": "7a2d8f7e1861c9c62472f1cd168d33cef918b108", + "installed_by": ["modules"] + }, + "humann3/regroup": { + "branch": "master", + "git_sha": "7a2d8f7e1861c9c62472f1cd168d33cef918b108", + "installed_by": ["modules"] + }, + "humann3/renorm": { + "branch": "master", + "git_sha": "7a2d8f7e1861c9c62472f1cd168d33cef918b108", + "installed_by": ["modules"] + }, + "metaphlan/metaphlan": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "mifaser": { + "branch": "master", + "git_sha": "522d0a5709833aaa28c58d4464b4348d03316a62", "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", + "git_sha": "98403d15b0e50edae1f3fec5eae5e24982f1fade", + "installed_by": ["modules"] + }, + "rgi/bwt": { + "branch": "master", + "git_sha": "587ef528a2f42a2415ad1b5f760ea93ab1983603", + "installed_by": ["modules"] + }, + "rgi/cardannotation": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["modules"] + }, + "seqkit/fq2fa": { + "branch": "master", + "git_sha": "d07a945f421a4a91ce4e5a22db63e0e7f8741607", + "installed_by": ["modules"] + }, + "untar": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["modules"] } } @@ -21,17 +91,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", + "git_sha": "1a545fcbd762911c21a64ced3dbef99b2b51ac75", "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": "a7b27fd25bfa8dcc07d299e88bd790585901a436", "installed_by": ["subworkflows"] } } diff --git a/modules/local/humann4/humann/environment.yml b/modules/local/humann4/humann/environment.yml new file mode 100644 index 0000000..fe49246 --- /dev/null +++ b/modules/local/humann4/humann/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: + - biobakery::humann==4.0.0a1 + - bioconda::metaphlan==4.0.0 + - pip + - pip: + - setuptools diff --git a/modules/local/humann4/humann/main.nf b/modules/local/humann4/humann/main.nf new file mode 100644 index 0000000..861ef5e --- /dev/null +++ b/modules/local/humann4/humann/main.nf @@ -0,0 +1,70 @@ +// Taken 98% from https://github.com/nf-core/modules/pull/1089/files +process HUMANN4 { + tag "${meta.id}" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container 'ghcr.io/vdblab/biobakery-profiler:4.0.6--4.0.0.alpha.1-final_smaller-pt2' + + input: + tuple val(meta), path(input) + tuple val(_meta), path(profile) + path nucleotide_db + path protein_db + path utility_db + + output: + tuple val(meta), path("*_genefamilies.tsv.gz"), emit: genefamilies + tuple val(meta), path("*_pathabundance.tsv.gz"), emit: pathabundance + tuple val(meta), path("*_reactions.tsv.gz"), emit: reactions + tuple val(meta), path("*.log"), emit: log + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + tuple val("${task.process}"), val('MetaPHLan'), eval("metaphlan --version 2>&1 | sed 's/metaphlan v//'"), emit: versions_metaphlan, topic: versions + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def nuc_ext = '*.fna.gz' + // TODO: I never got this to successfully run + // def pangenome_string = "--metaphlan-options \"-t rel_ab --bowtie2db ./${pangenome_db} --index ${pangenome_db_index_name} \"" + def pangenome_string = "--taxonomic-profile ${profile}" + """ + PROTS_DB=`find -L "${protein_db}" -name "*.dmnd" -exec dirname {} \\;` + nuclist=`find -L "${nucleotide_db}" -name "${nuc_ext}" -print -quit ` + NUCS_DB=\$(dirname \$nuclist) + + STATIC_CONFIG=`python -c "import humann; print(humann.__file__.replace('__init__.py', 'humann.cfg'))"` + cat \$STATIC_CONFIG | sed "s|utility_mapping = .*|utility_mapping = ${utility_db}|g" > humann.cfg + export HUMANN_CONFIG=humann.cfg + + find \${NUCS_DB} + humann \\ + ${args} \\ + --threads ${task.cpus} \\ + --input ${input} \\ + --protein-database \${PROTS_DB} \\ + --nucleotide-database \${NUCS_DB} \\ + --output-basename ${prefix} \\ + ${pangenome_string} \\ + ${args} \\ + --o-log ${prefix}.log \\ + --output . + + + gzip -n *.tsv + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo ${args} + + for suf in genefamilies.tsv.gz pathabundance.tsv.gz reactions.tsv.gz + do + echo stub | gzip > ${prefix}_\$suf + done + touch ${prefix}.log + """ +} diff --git a/modules/local/humann4/humann/meta.yaml b/modules/local/humann4/humann/meta.yaml new file mode 100644 index 0000000..f0f7a6a --- /dev/null +++ b/modules/local/humann4/humann/meta.yaml @@ -0,0 +1,67 @@ +name: humann4 +description: Functional analysis of metagenome or metatranscrtiptome data +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network, version 4" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann4 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: ["MIT"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: | + A metagenome (DNA reads) or metatranscriptome (RNA reads) [fastq,fastq.gz,fasta,fasta.gz] + - please note: no paired-end files are supported, concatenate paired and reads into one file! + OR Pre-computed mappings of reads to database sequences [sam,bam,blastm8] + OR Pre-computed (typically gene) abundance tables [tsv,biom] + pattern: "*.{fastq,fastq.gz,fasta,fasta.gz,sam,bam,blastm8,tsv,biom}" + - profile: + type: file + description: a taxonomic profile generated by Metaphlan + - nucleotide_db: + type: file + description: | + Can be a compressed tar archive (*.tar.gz) or a folder containing compressed fasta files (folder/*.gz) + See http://huttenhower.sph.harvard.edu/humann_data/chocophlan + - protein_db: + type: file + description: | + Can be a compressed tar archive (*.tar.gz) or a folder containing compressed fasta files (folder/*.gz) + See http://huttenhower.sph.harvard.edu/humann_data/uniprot + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - genefamilies: + type: file + description: Compressed tab separated text file + pattern: "*.{tsv.gz}" + - pathabundance: + type: file + description: Compressed tab separated text file + pattern: "*.{tsv.gz}" + - reactions: + type: file + description: Compressed tab separated text file + pattern: "*.{tsv.gz}" + +authors: + - "@d4straub" + - "@nickp60" diff --git a/modules/local/humann4/humann/tests/main_v4.nf.test b/modules/local/humann4/humann/tests/main_v4.nf.test new file mode 100644 index 0000000..cce38e3 --- /dev/null +++ b/modules/local/humann4/humann/tests/main_v4.nf.test @@ -0,0 +1,115 @@ +nextflow_process { + + name "Test Process HUMANN_HUMANN as HUMANN4" + script "../main.nf" + process "HUMANN4" + tag "modules" + tag "modules_" + tag "humann" + + setup{ + run("UNTAR", alias: "UNTAR_v4_nuc") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v4/chocophlan_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("UNTAR", alias: "UNTAR_v4_prot") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v4/uniref_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("UNTAR", alias: "UNTAR_v4_util") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v4/utility_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + } + test("humann_v4 sarscov2 - fastq") { + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0]= Channel.of([ + [ id:'test', single_end:false, run_accession:"abc" ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + ]) + input[1] = Channel.of([[], file("${moduleDir}/tests/mpa_test.txt")]) + input[2] = UNTAR_v4_nuc.out.untar.map{ it[1] } + input[3] = UNTAR_v4_prot.out.untar.map{ it[1] } + input[4] = UNTAR_v4_util.out.untar.map{ it[1] } + """ + } + } + + then { + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', '**/*.log', '**/*.biom', 'humann3/*', 'untar/*']) + println(stable_name) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore', ignore: ['**/*.log', '**/*.biom']) + println(stable_path) + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + stable_path + ).match() + } + ) + } + } + + test("humann_v4 sarscov2 - fastq - stub") { + + options "-stub" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0]= Channel.of([ + [ id:'test', single_end:false, run_accession:"abc" ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + ]) + input[1] = Channel.of([[], file("${moduleDir}/tests/mpa_test.txt")]) + input[2] = UNTAR_v4_nuc.out.untar.map{ it[1] } + input[3] = UNTAR_v4_prot.out.untar.map{ it[1] } + input[4] = UNTAR_v4_util.out.untar.map{ it[1] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.genefamilies, process.out.pathabundance, process.out.pathcoverage, process.out.reactions).match() } + ) + } + + } +} diff --git a/modules/local/humann4/humann/tests/main_v4.nf.test.snap b/modules/local/humann4/humann/tests/main_v4.nf.test.snap new file mode 100644 index 0000000..9ea548c --- /dev/null +++ b/modules/local/humann4/humann/tests/main_v4.nf.test.snap @@ -0,0 +1,62 @@ +{ + "humann_v4 sarscov2 - fastq": { + "content": [ + 4, + [ + "humann4", + "humann4/test_2_genefamilies.tsv.gz", + "humann4/test_3_reactions.tsv.gz", + "humann4/test_4_pathabundance.tsv.gz", + "pipeline_info" + ], + [ + + ] + ], + "timestamp": "2026-08-04T11:59:37.715128", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "humann_v4 sarscov2 - fastq - stub": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_genefamilies.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_pathabundance.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + null, + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_reactions.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ] + ], + "timestamp": "2026-06-11T09:26:56.574951", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} \ No newline at end of file diff --git a/modules/local/humann4/humann/tests/mpa_test.txt b/modules/local/humann4/humann/tests/mpa_test.txt new file mode 100644 index 0000000..68b3769 --- /dev/null +++ b/modules/local/humann4/humann/tests/mpa_test.txt @@ -0,0 +1,7 @@ +#vOct22_CHOCOPhlAnSGB_202403 +#/opt/venv/bin/metaphlan --nproc 6 --input_type fastq test_1.fastq.gz -t rel_ab_w_read_stats --bowtie2out test.bowtie2out.txt --bowtie2db metaphlan4_database --index vOct22_CHOCOPhlAnSGB_202403 --biom test.biom --output_file test_profile.txt +#100 reads processed +#SampleID Metaphlan_Analysis +#estimated_reads_mapped_to_known_clades:0 +#clade_name clade_taxid relative_abundance coverage estimated_number_of_reads_from_the_clade +unclassified -1 100.0 0 0 diff --git a/modules/local/humann4/regroup/environment.yml b/modules/local/humann4/regroup/environment.yml new file mode 100644 index 0000000..fe49246 --- /dev/null +++ b/modules/local/humann4/regroup/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: + - biobakery::humann==4.0.0a1 + - bioconda::metaphlan==4.0.0 + - pip + - pip: + - setuptools diff --git a/modules/local/humann4/regroup/main.nf b/modules/local/humann4/regroup/main.nf new file mode 100644 index 0000000..93916ec --- /dev/null +++ b/modules/local/humann4/regroup/main.nf @@ -0,0 +1,49 @@ +process HUMANN4_REGROUP { + tag "${meta.id}" + label 'process_low' + + //conda 'bioconda::humann=4.0.0.alpha.1-final' + conda "${moduleDir}/environment.yml" + + container 'ghcr.io/vdblab/biobakery-profiler:4.0.6--4.0.0.alpha.1-final_smaller-pt2' + + input: + tuple val(meta), path(input) + val groups + path utility_db + + output: + tuple val(meta), path("*_regroup.tsv.gz"), emit: regroup + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + + script: + + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + if [[ ${input} == *.gz ]]; then + gunzip -c ${input} > input.tsv + else + mv ${input} input.tsv + fi + STATIC_CONFIG=`python -c "import humann; print(humann.__file__.replace('__init__.py', 'humann.cfg'))"` + cat \$STATIC_CONFIG | sed "s|utility_mapping = .*|utility_mapping = ${utility_db}|g" > humann.cfg + export HUMANN_CONFIG=humann.cfg + humann_config --print + humann_regroup_table \\ + --input input.tsv \\ + --output ${prefix}_regroup.tsv \\ + --groups ${groups} \\ + ${args} + + gzip -n ${prefix}_regroup.tsv + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "stub" | gzip > ${prefix}_regroup.tsv.gz + """ +} diff --git a/modules/local/humann4/regroup/meta.yaml b/modules/local/humann4/regroup/meta.yaml new file mode 100644 index 0000000..b2ca571 --- /dev/null +++ b/modules/local/humann4/regroup/meta.yaml @@ -0,0 +1,45 @@ +name: humann_regroup +description: Regrouping genes to other functional categories +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network, version 4" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann3 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: ["MIT"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: Tab separated abundance file of HUMAnN3 + pattern: "*.{tsv.gz,tsv}" + - groups: + type: value + description: Regroup abundance values to MetaCyc reaction (RXN) abundances + pattern: "{uniref90_rxn,uniref50_rxn}" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - regroup: + type: file + description: Re-grouped compressed tab separated text file + pattern: "*.{tsv.gz}" + +authors: + - "@d4straub" diff --git a/modules/local/humann4/regroup/tests/main.nf.test b/modules/local/humann4/regroup/tests/main.nf.test new file mode 100644 index 0000000..4248f32 --- /dev/null +++ b/modules/local/humann4/regroup/tests/main.nf.test @@ -0,0 +1,47 @@ +nextflow_process { + + name "Test Process HUMANN4_REGROUP" + script "../main.nf" + process "HUMANN4_REGROUP" + tag "modules" + tag "modules_" + tag "humann" + setup { + run("UNTAR", alias: "UNTAR_v3_util") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/utility_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + } + test("humann_regroup sarscov2 - tsv - 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) + ]) + input[1] = "uniref90_rxn" + input[2] = UNTAR_v3_util.out.untar.map{ it[1] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/local/humann4/regroup/tests/main.nf.test.snap b/modules/local/humann4/regroup/tests/main.nf.test.snap new file mode 100644 index 0000000..96e22d0 --- /dev/null +++ b/modules/local/humann4/regroup/tests/main.nf.test.snap @@ -0,0 +1,45 @@ +{ + "humann_regroup sarscov2 - tsv - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "1": [ + [ + "HUMANN4_REGROUP", + "HUMAnN", + "4.0.0.alpha.1" + ] + ], + "regroup": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "versions_humann": [ + [ + "HUMANN4_REGROUP", + "HUMAnN", + "4.0.0.alpha.1" + ] + ] + } + ], + "timestamp": "2026-04-20T23:44:45.066062", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/local/humann4/renorm/environment.yml b/modules/local/humann4/renorm/environment.yml new file mode 100644 index 0000000..fe49246 --- /dev/null +++ b/modules/local/humann4/renorm/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: + - biobakery::humann==4.0.0a1 + - bioconda::metaphlan==4.0.0 + - pip + - pip: + - setuptools diff --git a/modules/local/humann4/renorm/main.nf b/modules/local/humann4/renorm/main.nf new file mode 100644 index 0000000..d0b3fcd --- /dev/null +++ b/modules/local/humann4/renorm/main.nf @@ -0,0 +1,41 @@ +process HUMANN4_RENORM { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container 'ghcr.io/vdblab/biobakery-profiler:4.0.6--4.0.0.alpha.1-final_smaller-pt2' + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path("*_renorm.tsv.gz"), emit: renorm + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + if [[ ${input} == *.gz ]]; then + gunzip -c ${input} > input.tsv + else + mv ${input} input.tsv + fi + + humann_renorm_table \\ + --input input.tsv \\ + --output ${prefix}_renorm.tsv \\ + ${args} + + gzip -n ${prefix}_renorm.tsv + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "stub" | gzip > ${prefix}_renorm.tsv.gz + + """ +} diff --git a/modules/local/humann4/renorm/meta.yaml b/modules/local/humann4/renorm/meta.yaml new file mode 100644 index 0000000..204a916 --- /dev/null +++ b/modules/local/humann4/renorm/meta.yaml @@ -0,0 +1,41 @@ +name: humann_renorm +description: Normalizing RPKs to relative abundance +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network, version 3" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann3 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: ["MIT"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: Tab separated abundance file of HUMAnN3 + pattern: "*.{tsv.gz,tsv}" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - renorm: + type: file + description: Normalized compressed tab separated text file + pattern: "*.{tsv.gz}" + +authors: + - "@d4straub" diff --git a/modules/local/humann4/renorm/tests/main.nf.test b/modules/local/humann4/renorm/tests/main.nf.test new file mode 100644 index 0000000..62c03d0 --- /dev/null +++ b/modules/local/humann4/renorm/tests/main.nf.test @@ -0,0 +1,34 @@ +nextflow_process { + + name "Test Process HUMANN_RENORM" + script "../main.nf" + process "HUMANN4_RENORM" + tag "modules" + tag "modules_" + tag "humann" + + test("humann4_renorm sarscov2 - tsv - 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) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/local/humann4/renorm/tests/main.nf.test.snap b/modules/local/humann4/renorm/tests/main.nf.test.snap new file mode 100644 index 0000000..730ece4 --- /dev/null +++ b/modules/local/humann4/renorm/tests/main.nf.test.snap @@ -0,0 +1,45 @@ +{ + "humann4_renorm sarscov2 - tsv - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_renorm.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "1": [ + [ + "HUMANN4_RENORM", + "HUMAnN", + "4.0.0.alpha.1" + ] + ], + "renorm": [ + [ + { + "id": "test", + "single_end": false + }, + "test_renorm.tsv.gz:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "versions_humann": [ + [ + "HUMANN4_RENORM", + "HUMAnN", + "4.0.0.alpha.1" + ] + ] + } + ], + "timestamp": "2026-04-21T11:51:26.626171", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/cat/fastq/environment.yml b/modules/nf-core/cat/fastq/environment.yml new file mode 100644 index 0000000..9b926b1 --- /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 0000000..8d12a78 --- /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 in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' + : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" + + 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 0000000..6fefd6e --- /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 0000000..21052d9 --- /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 0000000..6375b2a --- /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/diamond/blastx/environment.yml b/modules/nf-core/diamond/blastx/environment.yml new file mode 100644 index 0000000..5dc13ad --- /dev/null +++ b/modules/nf-core/diamond/blastx/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::diamond=2.2.1 diff --git a/modules/nf-core/diamond/blastx/main.nf b/modules/nf-core/diamond/blastx/main.nf new file mode 100644 index 0000000..453170c --- /dev/null +++ b/modules/nf-core/diamond/blastx/main.nf @@ -0,0 +1,117 @@ +process DIAMOND_BLASTX { + tag "${meta.id}" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/diamond:2.2.1--he361c42_0' + : 'quay.io/biocontainers/diamond:2.2.1--he361c42_0'}" + + input: + tuple val(meta), path(fasta) + tuple val(meta2), path(db) + val out_ext + val blast_columns + + output: + tuple val(meta), path('*.blast'), optional: true, emit: blast + tuple val(meta), path('*.xml'), optional: true, emit: xml + tuple val(meta), path('*.txt'), optional: true, emit: txt + tuple val(meta), path('*.daa'), optional: true, emit: daa + tuple val(meta), path('*.sam'), optional: true, emit: sam + tuple val(meta), path('*.tsv'), optional: true, emit: tsv + tuple val(meta), path('*.paf'), optional: true, emit: paf + tuple val(meta), path("*.log"), emit: log + tuple val("${task.process}"), val('diamond'), eval("diamond --version | sed 's/diamond version //g'"), emit: versions_diamond, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def is_compressed = fasta.getExtension() == "gz" ? true : false + def fasta_name = is_compressed ? fasta.getBaseName() : fasta + def columns = blast_columns ? "${blast_columns}" : '' + if (out_ext == 'blast') { + outfmt = 0 + } + else if (out_ext == 'xml') { + outfmt = 5 + } + else if (out_ext == 'txt') { + outfmt = 6 + } + else if (out_ext == 'daa') { + outfmt = 100 + } + else if (out_ext == 'sam') { + outfmt = 101 + } + else if (out_ext == 'tsv') { + outfmt = 102 + } + else if (out_ext == 'paf') { + outfmt = 103 + } + else { + outfmt = 6 + out_ext = 'txt' + log.warn("Unknown output file format provided (${out_ext}): selecting DIAMOND default of tabular BLAST output (txt)") + } + """ + if [ "${is_compressed}" == "true" ]; then + gzip -c -d ${fasta} > ${fasta_name} + fi + + DB=`find -L ./ -name "*.dmnd" | sed 's/\\.dmnd\$//'` + + diamond \\ + blastx \\ + --threads ${task.cpus} \\ + --db \$DB \\ + --query ${fasta_name} \\ + --outfmt ${outfmt} ${columns} \\ + ${args} \\ + --out ${prefix}.${out_ext} \\ + --log + + mv diamond.log ${prefix}.log + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + if (out_ext == 'blast') { + outfmt = 0 + } + else if (out_ext == 'xml') { + outfmt = 5 + } + else if (out_ext == 'txt') { + outfmt = 6 + } + else if (out_ext == 'daa') { + outfmt = 100 + } + else if (out_ext == 'sam') { + outfmt = 101 + } + else if (out_ext == 'tsv') { + outfmt = 102 + } + else if (out_ext == 'paf') { + outfmt = 103 + } + else { + outfmt = 6 + out_ext = 'txt' + log.warn("Unknown output file format provided (${out_ext}): selecting DIAMOND default of tabular BLAST output (txt)") + } + + """ + echo "${args}" + touch ${prefix}.${out_ext} + touch ${prefix}.log + """ +} diff --git a/modules/nf-core/diamond/blastx/meta.yml b/modules/nf-core/diamond/blastx/meta.yml new file mode 100644 index 0000000..019a3e9 --- /dev/null +++ b/modules/nf-core/diamond/blastx/meta.yml @@ -0,0 +1,179 @@ +name: diamond_blastx +description: Queries a DIAMOND database using blastx mode +keywords: + - fasta + - diamond + - blastx + - DNA sequence +tools: + - diamond: + description: Accelerated BLAST compatible local sequence aligner + homepage: https://github.com/bbuchfink/diamond + documentation: https://github.com/bbuchfink/diamond/wiki + tool_dev_url: https://github.com/bbuchfink/diamond + doi: "10.1038/s41592-021-01101-x" + licence: + - "GPL v3.0" + identifier: biotools:diamond +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Input fasta file containing query sequences + pattern: "*.{fa,fasta,fa.gz,fasta.gz}" + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - - meta2: + type: map + description: | + Groovy Map containing db information + e.g. [ id:'test2', single_end:false ] + - db: + type: file + description: File of the indexed DIAMOND database + pattern: "*.dmnd" + ontologies: [] + - out_ext: + type: string + description: | + Specify the type of output file to be generated. `blast` corresponds to + BLAST pairwise format. `xml` corresponds to BLAST xml format. + `txt` corresponds to to BLAST tabular format. `tsv` corresponds to + taxonomic classification format. + pattern: "blast|xml|txt|daa|sam|tsv|paf" + - blast_columns: + type: string + description: | + Optional space separated list of DIAMOND tabular BLAST output keywords + used for in conjunction with the 'txt' out_ext option (--outfmt 6). Options: + qseqid sseqid pident length mismatch gapopen qstart qend sstart send evalue bitscore +output: + blast: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.blast": + type: file + description: File containing blastp hits + pattern: "*.{blast}" + ontologies: + - edam: http://edamontology.org/format_3836 # BLAST XML v2 results format + xml: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.xml": + type: file + description: File containing blastp hits + pattern: "*.{xml}" + ontologies: + - edam: http://edamontology.org/format_2332 # XML + txt: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.txt": + type: file + description: File containing hits in tabular BLAST format. + pattern: "*.{txt}" + ontologies: [] + daa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.daa": + type: file + description: File containing hits DAA format + pattern: "*.{daa}" + ontologies: [] + sam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.sam": + type: file + description: File containing aligned reads in SAM format + pattern: "*.{sam}" + ontologies: + - edam: http://edamontology.org/format_2573 # SAM + tsv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.tsv": + type: file + description: Tab separated file containing taxonomic classification of + hits + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + paf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.paf": + type: file + description: File containing aligned reads in pairwise mapping format + format + pattern: "*.{paf}" + ontologies: [] + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.log": + type: file + description: Log file containing stdout information + pattern: "*.{log}" + ontologies: [] + versions_diamond: + - - ${task.process}: + type: string + description: The name of the process + - diamond: + type: string + description: The name of the tool + - diamond --version | sed 's/diamond version //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 + - diamond: + type: string + description: The name of the tool + - diamond --version | sed 's/diamond version //g': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@spficklin" + - "@jfy133" + - "@mjamy" +maintainers: + - "@spficklin" + - "@jfy133" + - "@mjamy" + - "@vagkaratzas" + - "@sofstam" diff --git a/modules/nf-core/diamond/blastx/tests/main.nf.test b/modules/nf-core/diamond/blastx/tests/main.nf.test new file mode 100644 index 0000000..87011ef --- /dev/null +++ b/modules/nf-core/diamond/blastx/tests/main.nf.test @@ -0,0 +1,82 @@ +nextflow_process { + + name "Test Process DIAMOND_BLASTX" + script "../main.nf" + process "DIAMOND_BLASTX" + tag "modules" + tag "modules_nfcore" + tag "diamond" + tag "diamond/makedb" + tag "diamond/blastx" + + setup { + run("DIAMOND_MAKEDB") { + script "../../makedb/main.nf" + process { + """ + input[0] = [ [id:'test2'], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] ] + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + } + + test("Should search for transcriptome hits against a DIAMOND db and return the default tab separated output file of hits") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/transcriptome.fasta', checkIfExists: true) ] + input[1] = DIAMOND_MAKEDB.out.db + input[2] = 'tfdfdt' // Nonsense file extension to check default case. + input[3] = 'qseqid qlen' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.log.get(0).get(1)).readLines().contains("11 queries aligned.") }, + { assert snapshot( + process.out.txt, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() + } + ) + } + + } + + test("Should search for transcriptome hits against a DIAMOND db and return the daa format output file of hits") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/transcriptome.fasta', checkIfExists: true) ] + input[1] = DIAMOND_MAKEDB.out.db + input[2] = 'daa' + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.daa }, + { assert path(process.out.log.get(0).get(1)).readLines().contains("11 queries aligned.") }, + { assert snapshot(process.out.findAll { key, val -> key.startsWith('versions') }).match() } + ) + } + + } +} diff --git a/modules/nf-core/diamond/blastx/tests/main.nf.test.snap b/modules/nf-core/diamond/blastx/tests/main.nf.test.snap new file mode 100644 index 0000000..b3cf211 --- /dev/null +++ b/modules/nf-core/diamond/blastx/tests/main.nf.test.snap @@ -0,0 +1,46 @@ +{ + "Should search for transcriptome hits against a DIAMOND db and return the daa format output file of hits": { + "content": [ + { + "versions_diamond": [ + [ + "DIAMOND_BLASTX", + "diamond", + "2.2.1" + ] + ] + } + ], + "timestamp": "2026-06-09T15:06:53.562101168", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "Should search for transcriptome hits against a DIAMOND db and return the default tab separated output file of hits": { + "content": [ + [ + [ + { + "id": "test" + }, + "test.txt:md5,33dc682dabfa44c7089abbc8fe8b84e4" + ] + ], + { + "versions_diamond": [ + [ + "DIAMOND_BLASTX", + "diamond", + "2.2.1" + ] + ] + } + ], + "timestamp": "2026-06-09T15:06:47.844654623", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/eggnogmapper/environment.yml b/modules/nf-core/eggnogmapper/environment.yml new file mode 100644 index 0000000..58acb20 --- /dev/null +++ b/modules/nf-core/eggnogmapper/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::eggnog-mapper=2.1.13 diff --git a/modules/nf-core/eggnogmapper/main.nf b/modules/nf-core/eggnogmapper/main.nf new file mode 100644 index 0000000..cff118e --- /dev/null +++ b/modules/nf-core/eggnogmapper/main.nf @@ -0,0 +1,58 @@ +process EGGNOGMAPPER { + tag "$meta.id" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/eggnog-mapper:2.1.13--pyhdfd78af_2': + 'quay.io/biocontainers/eggnog-mapper:2.1.13--pyhdfd78af_2' }" + + input: + tuple val(meta), path(fasta) + tuple val(search_mode), path(db) + path(eggnog_data_dir) + + output: + tuple val(meta), path("*.emapper.annotations") , emit: annotations + tuple val(meta), path("*.emapper.seed_orthologs"), emit: orthologs, optional: true + tuple val(meta), path("*.emapper.hits") , emit: hits , optional: true + tuple val("${task.process}"), val('eggnog-mapper'), eval("emapper.py --version 2>&1 | grep -o 'emapper-[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+' | sed 's/emapper-//'"), topic: versions, emit: versions_eggnogmapper + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def is_compressed = fasta.extension == '.gz' + def fasta_name = is_compressed ? fasta.baseName : "$fasta" + def db_flags = ['diamond': '--dmnd_db', 'novel_fams': '--dmnd_db', 'mmseqs': '--mmseqs_db', 'hmmer': '--database', 'no_search': '--annotate_hits_table', 'cache': '--cache'] + def db_path = (db instanceof Path && db.isDirectory()) ? "${db}/${db.name}" : "$db" + def db_arg = db && db_flags[search_mode] ? "${db_flags[search_mode]} ${db_path}" : '' + def dbmem = task.memory.toMega() > 40000 ? '--dbmem' : '' + """ + if [ "$is_compressed" == "true" ]; then + gzip -c -d $fasta > $fasta_name + fi + + emapper.py \\ + $args \\ + --cpu ${task.cpus} \\ + -i ${fasta_name} \\ + --data_dir ${eggnog_data_dir} \\ + -m ${search_mode} \\ + $db_arg \\ + ${dbmem} \\ + --output ${prefix} + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo $args + + touch ${prefix}.emapper.annotations + touch ${prefix}.emapper.seed_orthologs + touch ${prefix}.emapper.hits + """ +} diff --git a/modules/nf-core/eggnogmapper/meta.yml b/modules/nf-core/eggnogmapper/meta.yml new file mode 100644 index 0000000..7f04642 --- /dev/null +++ b/modules/nf-core/eggnogmapper/meta.yml @@ -0,0 +1,136 @@ +name: "eggnogmapper" +description: Fast genome-wide functional annotation through orthology assignment. +keywords: + - annotation + - functional annotation + - orthology + - genomics + - eggnog +tools: + - "eggnogmapper": + description: | + EggNOG-mapper is a tool for fast functional annotation of novel sequences. + It uses precomputed orthologous groups and phylogenies from the eggNOG database + to transfer functional information from fine-grained orthologs only. + homepage: "https://github.com/eggnogdb/eggnog-mapper" + documentation: "https://github.com/eggnogdb/eggnog-mapper/wiki" + tool_dev_url: "https://github.com/eggnogdb/eggnog-mapper" + doi: "10.1093/molbev/msab293" + licence: + - "AGPL v3" + identifier: "biotools:eggnog-mapper-v2" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - fasta: + type: file + description: Input sequences in FASTA format (plain or gzip-compressed) + pattern: "*.{fasta,faa,fa}(.gz)?" + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - - search_mode: + type: string + description: | + Search mode passed to emapper.py via -m. Determines which backend + is used and which database flag is applied internally. + Supported modes: + - diamond: DIAMOND-based homology search (--dmnd_db) + - novel_fams: DIAMOND search against novel families (--dmnd_db) + - mmseqs: MMseqs2-based search (--mmseqs_db) + - hmmer: HMMER-based search (--database) + - no_search: Skip search step and annotate from a precomputed + *.emapper.seed_orthologs file (--annotate_hits_table) + - cache: Reuse a previously generated hits table (--cache) + enum: [diamond, novel_fams, mmseqs, hmmer, no_search, cache] + - db: + type: file + description: | + Database file, directory, or precomputed results file required by the + selected search_mode. The module automatically assigns the correct + flag depending on search_mode: + - diamond / novel_fams: DIAMOND database (*.dmnd) + - mmseqs: MMseqs2 database directory or prefix + - hmmer: HMM database (*.hmm, *.h3m) + - no_search: Precomputed *.emapper.seed_orthologs file + - cache: Previously generated *.emapper.hits file + This input is mandatory but its expected format depends on search_mode. + pattern: "*" + ontologies: + - edam: http://edamontology.org/format_1370 # HMMER format + - edam: http://edamontology.org/format_3475 # TSV + - eggnog_data_dir: + type: directory + description: | + Directory containing eggnog-mapper database files + (e.g. can be downloaded via download_eggnog_data.py, + found in the eggnog-mapper repository) + pattern: "*" +output: + annotations: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.emapper.annotations": + type: file + description: TSV file with the results from the annotation phase, including + functional annotations, GO terms, KEGG pathways, and COG categories + pattern: "*.emapper.annotations" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + orthologs: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.emapper.seed_orthologs": + type: file + description: TSV file with the results from parsing the hits, linking queries + with their best seed orthologs (includes commented metadata header) + pattern: "*.emapper.seed_orthologs" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + hits: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.emapper.hits": + type: file + description: TSV file with the raw search hits from the Diamond/MMseqs2/HMMER + search phase before annotation + pattern: "*.emapper.hits" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions_eggnogmapper: + - - ${task.process}: + type: string + description: The name of the process + - eggnog-mapper: + type: string + description: The name of the tool + - emapper.py --version 2>&1 | grep -o 'emapper-[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/emapper-//': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - eggnog-mapper: + type: string + description: The name of the tool + - emapper.py --version 2>&1 | grep -o 'emapper-[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/emapper-//': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@vagkaratzas" +maintainers: + - "@vagkaratzas" + - "@gallvp" diff --git a/modules/nf-core/eggnogmapper/tests/main.nf.test b/modules/nf-core/eggnogmapper/tests/main.nf.test new file mode 100644 index 0000000..5b74a12 --- /dev/null +++ b/modules/nf-core/eggnogmapper/tests/main.nf.test @@ -0,0 +1,182 @@ +nextflow_process { + + name "Test Process EGGNOGMAPPER" + script "../main.nf" + process "EGGNOGMAPPER" + + tag "modules" + tag "modules_nfcore" + tag "eggnogmapper" + tag "diamond" + tag "diamond/makedb" + tag "mmseqs" + tag "mmseqs/createdb" + + test("sarscov2 - proteome - diamond") { + setup { + run("DIAMOND_MAKEDB") { + script "../../diamond/makedb/main.nf" + process { + """ + input[0] = [ [id:'dmnd_db'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + } + + when { + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = DIAMOND_MAKEDB.out.db.map { _meta, db -> [ 'diamond', db ] } + eggnog_db = file(params.modules_testdata_base_path + '/delete_me/eggnogmapper/eggnog.db', checkIfExists: true) + eggnog_db.copyTo("${workDir}/tmp/eggnog.db") + input[2] = "${workDir}/tmp/" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.annotations[0][1]).readLines()[3..6], + file(process.out.orthologs[0][1]).readLines()[5..18], + process.out.hits[0][1], + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - proteome - mmseqs") { + setup { + run("MMSEQS_CREATEDB") { + script "../../mmseqs/createdb/main.nf" + process { + """ + input[0] = [ [id:'mmseqs_db'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + """ + } + } + } + + when { + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = MMSEQS_CREATEDB.out.db.map { _meta, db -> [ 'mmseqs', db ] } + eggnog_db = file(params.modules_testdata_base_path + '/delete_me/eggnogmapper/eggnog.db', checkIfExists: true) + eggnog_db.copyTo("${workDir}/tmp/eggnog.db") + input[2] = "${workDir}/tmp/" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.annotations[0][1]).readLines()[3..6], + file(process.out.orthologs[0][1]).readLines().size(), + file(process.out.hits[0][1]).readLines().size(), + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - proteome - no_search") { + setup { + run("DIAMOND_MAKEDB") { + script "../../diamond/makedb/main.nf" + process { + """ + input[0] = [ [id:'dmnd_db'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + run("EGGNOGMAPPER", alias: "EGGNOGMAPPER_SETUP") { + script "../main.nf" + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = DIAMOND_MAKEDB.out.db.map { _meta, db -> [ 'diamond', db ] } + eggnog_db = file(params.modules_testdata_base_path + '/delete_me/eggnogmapper/eggnog.db', checkIfExists: true) + eggnog_db.copyTo("${workDir}/tmp/eggnog.db") + input[2] = "${workDir}/tmp/" + """ + } + } + } + + when { + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = EGGNOGMAPPER_SETUP.out.orthologs.map { _meta, orthologs -> [ 'no_search', orthologs ] } + eggnog_db = file(params.modules_testdata_base_path + '/delete_me/eggnogmapper/eggnog.db', checkIfExists: true) + eggnog_db.copyTo("${workDir}/tmp/eggnog.db") + input[2] = "${workDir}/tmp/" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.annotations[0][1]).readLines()[3..6], + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("sarscov2 - proteome - diamond - stub") { + options '-stub' + setup { + run("DIAMOND_MAKEDB") { + script "../../diamond/makedb/main.nf" + process { + """ + input[0] = [ [id:'dmnd_db'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + } + + when { + process { + """ + input[0] = [ [id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/proteome.fasta', checkIfExists: true) ] + input[1] = DIAMOND_MAKEDB.out.db.map { _meta, db -> [ 'diamond', db ] } + eggnog_db = file(params.modules_testdata_base_path + '/delete_me/eggnogmapper/eggnog.db', checkIfExists: true) + eggnog_db.copyTo("${workDir}/tmp/eggnog.db") + input[2] = "${workDir}/tmp/" + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + + } + +} diff --git a/modules/nf-core/eggnogmapper/tests/main.nf.test.snap b/modules/nf-core/eggnogmapper/tests/main.nf.test.snap new file mode 100644 index 0000000..f522e35 --- /dev/null +++ b/modules/nf-core/eggnogmapper/tests/main.nf.test.snap @@ -0,0 +1,135 @@ +{ + "sarscov2 - proteome - diamond": { + "content": [ + [ + "##", + "#query\tseed_ortholog\tevalue\tscore\teggNOG_OGs\tmax_annot_lvl\tCOG_category\tDescription\tPreferred_name\tGOs\tEC\tKEGG_ko\tKEGG_Pathway\tKEGG_Module\tKEGG_Reaction\tKEGG_rclass\tBRITE\tKEGG_TC\tCAZy\tBiGG_Reaction\tPFAMs", + "ENSSASP00005000002.1\tENSSASP00005000002.1\t0.0\t14179.0\tCOG0498@1|root,COG0498@2|Bacteria,1MUWQ@1224|Proteobacteria,2VHR6@28216|Betaproteobacteria,2KUMA@206389|Rhodocyclales\t1224|Proteobacteria\tE\tthreonine synthase\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-", + "## 12 queries scanned" + ], + [ + "#qseqid\tsseqid\tevalue\tbitscore\tqstart\tqend\tsstart\tsend\tpident\tqcov\tscov", + "ENSSASP00005000002.1\tENSSASP00005000002.1\t0.0\t14179.0\t1\t7096\t1\t7096\t100.0\t100.0\t100.0", + "ENSSASP00005000003.1\tENSSASP00005000003.1\t0.0\t8659.0\t1\t4405\t1\t4405\t100.0\t100.0\t100.0", + "ENSSASP00005000004.1\tENSSASP00005000004.1\t0.0\t2469.0\t1\t1273\t1\t1273\t100.0\t100.0\t100.0", + "ENSSASP00005000005.1\tENSSASP00005000005.1\t2.54e-286\t769.0\t1\t419\t1\t419\t100.0\t100.0\t100.0", + "ENSSASP00005000006.1\tENSSASP00005000006.1\t4.58e-205\t551.0\t1\t275\t1\t275\t100.0\t100.0\t100.0", + "ENSSASP00005000007.1\tENSSASP00005000007.1\t4.9e-160\t433.0\t1\t222\t1\t222\t100.0\t100.0\t100.0", + "ENSSASP00005000008.1\tENSSASP00005000008.1\t5.64e-94\t258.0\t1\t121\t1\t121\t100.0\t100.0\t100.0", + "ENSSASP00005000009.1\tENSSASP00005000009.1\t1.44e-87\t242.0\t1\t121\t1\t121\t100.0\t100.0\t100.0", + "ENSSASP00005000010.1\tENSSASP00005000010.1\t1.14e-47\t137.0\t1\t75\t1\t75\t100.0\t100.0\t100.0", + "ENSSASP00005000011.1\tENSSASP00005000011.1\t3.07e-39\t115.0\t1\t61\t1\t61\t100.0\t100.0\t100.0", + "ENSSASP00005000012.1\tENSSASP00005000012.1\t6.59e-20\t65.5\t1\t43\t1\t43\t100.0\t100.0\t100.0", + "ENSSASP00005000013.1\tENSSASP00005000013.1\t1.07e-25\t79.7\t1\t38\t1\t38\t100.0\t100.0\t100.0", + "## 12 queries scanned" + ], + "test.emapper.hits:md5,9ab2e1810b911f2e6c63f8c0f998ee83", + { + "versions_eggnogmapper": [ + [ + "EGGNOGMAPPER", + "eggnog-mapper", + "2.1.13" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T14:41:08.245249413" + }, + "sarscov2 - proteome - diamond - stub": { + "content": [ + { + "annotations": [ + [ + { + "id": "test" + }, + "test.emapper.annotations:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "hits": [ + [ + { + "id": "test" + }, + "test.emapper.hits:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "orthologs": [ + [ + { + "id": "test" + }, + "test.emapper.seed_orthologs:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_eggnogmapper": [ + [ + "EGGNOGMAPPER", + "eggnog-mapper", + "2.1.13" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T13:49:53.898972887" + }, + "sarscov2 - proteome - mmseqs": { + "content": [ + [ + "##", + "#query\tseed_ortholog\tevalue\tscore\teggNOG_OGs\tmax_annot_lvl\tCOG_category\tDescription\tPreferred_name\tGOs\tEC\tKEGG_ko\tKEGG_Pathway\tKEGG_Module\tKEGG_Reaction\tKEGG_rclass\tBRITE\tKEGG_TC\tCAZy\tBiGG_Reaction\tPFAMs", + "ENSSASP00005000002.1\tENSSASP00005000002.1\t0.0\t12938.0\tCOG0498@1|root,COG0498@2|Bacteria,1MUWQ@1224|Proteobacteria,2VHR6@28216|Betaproteobacteria,2KUMA@206389|Rhodocyclales\t1224|Proteobacteria\tE\tthreonine synthase\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-", + "## 12 queries scanned" + ], + 24, + 12, + { + "versions_eggnogmapper": [ + [ + "EGGNOGMAPPER", + "eggnog-mapper", + "2.1.13" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-27T09:49:08.050484472" + }, + "sarscov2 - proteome - no_search": { + "content": [ + [ + "##", + "#query\tseed_ortholog\tevalue\tscore\teggNOG_OGs\tmax_annot_lvl\tCOG_category\tDescription\tPreferred_name\tGOs\tEC\tKEGG_ko\tKEGG_Pathway\tKEGG_Module\tKEGG_Reaction\tKEGG_rclass\tBRITE\tKEGG_TC\tCAZy\tBiGG_Reaction\tPFAMs", + "ENSSASP00005000002.1\tENSSASP00005000002.1\t0.0\t14179.0\tCOG0498@1|root,COG0498@2|Bacteria,1MUWQ@1224|Proteobacteria,2VHR6@28216|Betaproteobacteria,2KUMA@206389|Rhodocyclales\t1224|Proteobacteria\tE\tthreonine synthase\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-", + "## 12 queries scanned" + ], + { + "versions_eggnogmapper": [ + [ + "EGGNOGMAPPER", + "eggnog-mapper", + "2.1.13" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-27T10:49:12.14219149" + } +} \ No newline at end of file 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 0000000..7770ccd --- /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 0000000..cdc434c --- /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/main.nf b/modules/nf-core/fastqc/main.nf index 23e1663..1085126 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') / 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 c8d9d02..2f6cfef 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -53,13 +53,28 @@ output: description: FastQC report archive pattern: "*_{fastqc.zip}" 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: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${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" @@ -70,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 e9d79a0..66c44da 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 d5db309..c8ee120 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/fmhfunprofiler/environment.yml b/modules/nf-core/fmhfunprofiler/environment.yml new file mode 100644 index 0000000..1a04b8b --- /dev/null +++ b/modules/nf-core/fmhfunprofiler/environment.yml @@ -0,0 +1,6 @@ +--- +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::fmh-funprofiler=1.1.1" diff --git a/modules/nf-core/fmhfunprofiler/main.nf b/modules/nf-core/fmhfunprofiler/main.nf new file mode 100644 index 0000000..ce698ac --- /dev/null +++ b/modules/nf-core/fmhfunprofiler/main.nf @@ -0,0 +1,41 @@ +process FMHFUNPROFILER { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/fmh-funprofiler:1.1.1--pyh106432d_0': + 'quay.io/biocontainers/fmh-funprofiler:1.1.1--pyh106432d_0' }" + + input: + tuple val(meta), path(reads) + path(ko_sketch) + val(ksize) + val(scaled) + + output: + tuple val(meta), path("*.csv"), emit: csv + tuple val("${task.process}"), val('fmh-funprofiler'), eval('python -c "import importlib.metadata; print(importlib.metadata.version(\'fmh-funprofiler\'))"'), topic: versions, emit: versions_fmhfunprofiler + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + funcprofiler \\ + $args \\ + $reads \\ + $ko_sketch \\ + $ksize \\ + $scaled \\ + ${prefix}.csv + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.csv + """ +} diff --git a/modules/nf-core/fmhfunprofiler/meta.yml b/modules/nf-core/fmhfunprofiler/meta.yml new file mode 100644 index 0000000..5de4107 --- /dev/null +++ b/modules/nf-core/fmhfunprofiler/meta.yml @@ -0,0 +1,85 @@ +name: "fmhfunprofiler" +description: Functionally profile metagenomic samples using FracMinHash sketches + against KEGG database references. +keywords: + - metagenomics + - functional profiling + - FracMinHash + - sourmash + - kegg +tools: + - "fmhfunprofiler": + description: "fmh-funprofiler is a pipeline that leverages FracMinHash (implemented + in sourmash) to functionally profile metagenomic samples, offering a faster + and more memory-efficient alternative to alignment-based methods." + homepage: "https://github.com/KoslickiLab/fmh-funprofiler" + documentation: "https://github.com/KoslickiLab/fmh-funprofiler" + tool_dev_url: "https://github.com/KoslickiLab/fmh-funprofiler" + doi: "10.1093/bioinformatics/btae397" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - reads: + type: file + description: Input metagenomic sequences in FASTA or FASTQ format (can be + compressed) + pattern: "*.{fasta,fastq,fa,fq,fasta.gz,fastq.gz,fa.gz,fq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + - ko_sketch: + type: file + description: Sourmash signature reference sketch or Sequence Bloom Tree + (SBT) of KEGG KOs + pattern: "*.{sig,sig.zip,sbt.zip}" + ontologies: [] + - ksize: + type: integer + description: The k-mer size to use for the sketch (typically 7, 11, or 15) + - scaled: + type: integer + description: The FracMinHash scale factor (e.g., 1000) +output: + csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.csv": + type: file + description: The main functional abundance profile matrix detailing KEGG + Orthology (KO) counts + pattern: "*.csv" + ontologies: + - edam: http://edamontology.org/format_3752 + versions_fmhfunprofiler: + - - ${task.process}: + type: string + description: The name of the process + - fmh-funprofiler: + type: string + description: The name of the tool + - 'python -c "import importlib.metadata; print(importlib.metadata.version(''fmh-funprofiler''))"': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - fmh-funprofiler: + type: string + description: The name of the tool + - 'python -c "import importlib.metadata; print(importlib.metadata.version(''fmh-funprofiler''))"': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@miraep8" +maintainers: + - "@miraep8" diff --git a/modules/nf-core/fmhfunprofiler/tests/main.nf.test b/modules/nf-core/fmhfunprofiler/tests/main.nf.test new file mode 100644 index 0000000..1f23e80 --- /dev/null +++ b/modules/nf-core/fmhfunprofiler/tests/main.nf.test @@ -0,0 +1,73 @@ +nextflow_process { + + name "Test Process FMHFUNPROFILER" + script "../main.nf" + process "FMHFUNPROFILER" + + tag "modules" + tag "modules_nfcore" + tag "fmhfunprofiler" + tag "sourmash" + tag "sourmash/sketch" + + setup { + run("SOURMASH_SKETCH") { + script "../../sourmash/sketch/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + test("sarscov2 - fastq - single_end") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + input[1] = SOURMASH_SKETCH.out.signatures.map { meta, sig -> sig } + input[2] = 11 + input[3] = 1000 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("sarscov2 - fastq - single_end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:true ], [] ] + input[1] = [] + input[2] = 11 + input[3] = 1000 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } +} diff --git a/modules/nf-core/fmhfunprofiler/tests/main.nf.test.snap b/modules/nf-core/fmhfunprofiler/tests/main.nf.test.snap new file mode 100644 index 0000000..18c4c53 --- /dev/null +++ b/modules/nf-core/fmhfunprofiler/tests/main.nf.test.snap @@ -0,0 +1,56 @@ +{ + "sarscov2 - fastq - single_end - stub": { + "content": [ + { + "csv": [ + [ + { + "id": "test", + "single_end": true + }, + "test.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_fmhfunprofiler": [ + [ + "FMHFUNPROFILER", + "fmh-funprofiler", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-07-09T10:52:24.354831448", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "sarscov2 - fastq - single_end": { + "content": [ + { + "csv": [ + [ + { + "id": "test", + "single_end": true + }, + "test.csv:md5,16b7196a90c1d2fd3e3109c8d252cd08" + ] + ], + "versions_fmhfunprofiler": [ + [ + "FMHFUNPROFILER", + "fmh-funprofiler", + "1.1.1" + ] + ] + } + ], + "timestamp": "2026-07-09T10:52:11.971686709", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/gunzip/environment.yml b/modules/nf-core/gunzip/environment.yml new file mode 100644 index 0000000..9b926b1 --- /dev/null +++ b/modules/nf-core/gunzip/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/gunzip/main.nf b/modules/nf-core/gunzip/main.nf new file mode 100644 index 0000000..6edffc5 --- /dev/null +++ b/modules/nf-core/gunzip/main.nf @@ -0,0 +1,47 @@ +process GUNZIP { + tag "${archive}" + 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/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("${gunzip}"), emit: gunzip + tuple val("${task.process}"), val('gunzip'), eval('gunzip --version 2>&1 | head -1 | sed "s/^.*(gzip) //; s/ Copyright.*//"'), topic: versions, emit: versions_gunzip + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def nameWithoutGz = archive.extension == 'gz' ? archive.baseName : archive.name + def extension = file(nameWithoutGz).extension + def name = file(nameWithoutGz).baseName + def prefix = task.ext.prefix ?: name + gunzip = prefix + ".${extension}" + """ + # Not calling gunzip itself because it creates files + # with the original group ownership rather than the + # default one for that user / the work directory + gzip \\ + -cd \\ + ${args} \\ + ${archive} \\ + > ${gunzip} + """ + + stub: + def nameWithoutGz = archive.extension == 'gz' ? archive.baseName : archive.name + def extension = file(nameWithoutGz).extension + def name = file(nameWithoutGz).baseName + def prefix = task.ext.prefix ?: name + gunzip = prefix + ".${extension}" + """ + touch ${gunzip} + """ +} diff --git a/modules/nf-core/gunzip/meta.yml b/modules/nf-core/gunzip/meta.yml new file mode 100644 index 0000000..bba6b3b --- /dev/null +++ b/modules/nf-core/gunzip/meta.yml @@ -0,0 +1,68 @@ +name: gunzip +description: Compresses and decompresses files. +keywords: + - gunzip + - compression + - decompression +tools: + - gunzip: + description: | + gzip is a file format and a software application used for file compression and decompression. + documentation: https://www.gnu.org/software/gzip/manual/gzip.html + licence: ["GPL-3.0-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Optional groovy Map containing meta information + e.g. [ id:'test', single_end:false ] + - archive: + type: file + description: File to be compressed/uncompressed + pattern: "*.*" + ontologies: [] +output: + gunzip: + - - meta: + type: file + description: Compressed/uncompressed file + pattern: "*.*" + ontologies: [] + - ${gunzip}: + type: file + description: Compressed/uncompressed file + pattern: "*.*" + ontologies: [] + versions_gunzip: + - - ${task.process}: + type: string + description: The process the versions were collected from + - gunzip: + type: string + description: The tool name + - gunzip --version 2>&1 | head -1 | sed "s/^.*(gzip) //; s/ Copyright.*//": + 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 + - gunzip: + type: string + description: The tool name + - gunzip --version 2>&1 | head -1 | sed "s/^.*(gzip) //; s/ Copyright.*//": + type: eval + description: The expression to obtain the version of the tool + +authors: + - "@joseespinosa" + - "@drpatelh" + - "@jfy133" +maintainers: + - "@joseespinosa" + - "@drpatelh" + - "@jfy133" + - "@gallvp" diff --git a/modules/nf-core/gunzip/tests/main.nf.test b/modules/nf-core/gunzip/tests/main.nf.test new file mode 100644 index 0000000..33cb75a --- /dev/null +++ b/modules/nf-core/gunzip/tests/main.nf.test @@ -0,0 +1,175 @@ +nextflow_process { + + name "Test Process GUNZIP" + script "../main.nf" + process "GUNZIP" + tag "gunzip" + tag "modules_nfcore" + tag "modules" + + test("Should run without failures") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [], + 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("Should run without failures - prefix") { + + config './nextflow.config' + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [ id: 'test' ], + 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("Should run without failures - stub") { + + options '-stub' + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [], + 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("Should decompress file with extension appearing multiple times in filename") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true).copyTo('test.fa.v1.fa.gz') + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.gunzip[0][1]).name == 'test.fa.v1.fa' } + ) + } + + } + + test("Should decompress file with extension appearing multiple times in filename - prefix") { + + config './nextflow.config' + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true).copyTo('test.fa.v1.fa.gz') + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("Should run without failures - prefix - stub") { + + options '-stub' + config './nextflow.config' + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/gunzip/tests/main.nf.test.snap b/modules/nf-core/gunzip/tests/main.nf.test.snap new file mode 100644 index 0000000..980e95a --- /dev/null +++ b/modules/nf-core/gunzip/tests/main.nf.test.snap @@ -0,0 +1,207 @@ +{ + "Should decompress file with extension appearing multiple times in filename - prefix": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.xyz.fa:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ], + "gunzip": [ + [ + { + "id": "test" + }, + "test.xyz.fa:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions_gunzip": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ] + } + ], + "timestamp": "2026-04-15T15:20:52.59447", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "Should run without failures - prefix - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ], + "gunzip": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gunzip": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ] + } + ], + "timestamp": "2026-01-19T17:21:56.633550769", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "Should run without failures - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + "test_1.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ], + "gunzip": [ + [ + [ + + ], + "test_1.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_gunzip": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ] + } + ], + "timestamp": "2026-01-19T17:21:51.435621199", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "Should run without failures": { + "content": [ + { + "0": [ + [ + [ + + ], + "test_1.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ], + "gunzip": [ + [ + [ + + ], + "test_1.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions_gunzip": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ] + } + ], + "timestamp": "2026-01-19T17:21:40.613975821", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "Should run without failures - prefix": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ], + "gunzip": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions_gunzip": [ + [ + "GUNZIP", + "gunzip", + "1.13" + ] + ] + } + ], + "timestamp": "2026-01-19T17:21:46.086880414", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/gunzip/tests/nextflow.config b/modules/nf-core/gunzip/tests/nextflow.config new file mode 100644 index 0000000..dec7764 --- /dev/null +++ b/modules/nf-core/gunzip/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: GUNZIP { + ext.prefix = { "${meta.id}.xyz" } + } +} diff --git a/modules/nf-core/humann3/humann/environment.yml b/modules/nf-core/humann3/humann/environment.yml new file mode 100644 index 0000000..3dc3f34 --- /dev/null +++ b/modules/nf-core/humann3/humann/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::humann=3.6.1 + - bioconda::metaphlan=4.0.6 + - conda-forge::python=3.10.8 diff --git a/modules/nf-core/humann3/humann/main.nf b/modules/nf-core/humann3/humann/main.nf new file mode 100644 index 0000000..6063488 --- /dev/null +++ b/modules/nf-core/humann3/humann/main.nf @@ -0,0 +1,63 @@ + +process HUMANN3_HUMANN { + 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/humann:3.6.1--pyh7cba7a3_0' : + 'quay.io/biocontainers/humann:3.6.1--pyh7cba7a3_0' }" + + input: + tuple val(meta), path(input) + tuple val(meta2), path(profile) + path nucleotide_db + path protein_db + path utility_db + + output: + tuple val(meta), path("*_genefamilies.tsv.gz") , emit: genefamilies + tuple val(meta), path("*_pathabundance.tsv.gz"), emit: pathabundance + tuple val(meta), path("*_pathcoverage.tsv.gz") , emit: pathcoverage, optional: true + tuple val(meta), path("*_reactions.tsv.gz") , emit: reactions, optional: true + tuple val(meta), path("*.log") , emit: log + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + tuple val("${task.process}"), val('MetaPhlAn'), eval("metaphlan --version 2>&1 | sed 's/MetaPhlAn version //'"), emit: versions_metaphlan, topic: versions + tuple val("${task.process}"), val('Python'), eval("python --version 2>&1 | sed 's/Python //'"), emit: versions_python, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def pangenome_string = "--taxonomic-profile ${profile}" + """ + PROTS_DB=`find -L "${protein_db}" -name "*.dmnd" -exec dirname {} \\;` + nuclist=`find -L "${nucleotide_db}" -name "*.ffn.gz" -print -quit ` + NUCS_DB=\$(dirname \$nuclist) + + humann \\ + $args \\ + --threads ${task.cpus} \\ + --input $input \\ + --protein-database \${PROTS_DB} \\ + --nucleotide-database \${NUCS_DB} \\ + --output-basename $prefix \\ + $pangenome_string \\ + --o-log ${prefix}.log \\ + --output . + + gzip -n *.tsv + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}_genefamilies.tsv.gz + echo "" | gzip > ${prefix}_pathabundance.tsv.gz + echo "" | gzip > ${prefix}_pathcoverage.tsv.gz + echo "" | gzip > ${prefix}_reactions.tsv.gz + touch ${prefix}.log + """ +} diff --git a/modules/nf-core/humann3/humann/meta.yml b/modules/nf-core/humann3/humann/meta.yml new file mode 100644 index 0000000..a7025fb --- /dev/null +++ b/modules/nf-core/humann3/humann/meta.yml @@ -0,0 +1,179 @@ +name: humann3_humann +description: Functional analysis of metagenome or metatranscriptome data +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann3 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: + - "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: | + A metagenome (DNA reads) or metatranscriptome (RNA reads) [fastq,fastq.gz,fasta,fasta.gz] + OR pre-computed mappings [sam,bam,blastm8] + OR pre-computed abundance tables [tsv,biom] + pattern: "*.{fastq,fastq.gz,fasta,fasta.gz,sam,bam,blastm8,tsv,biom}" + ontologies: + - edam: http://edamontology.org/format_1930 + - edam: http://edamontology.org/format_3475 + - edam: http://edamontology.org/format_3746 + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - profile: + type: file + description: Pre-computed MetaPhlAn taxonomic profile + pattern: "*.{txt}" + ontologies: [] + - nucleotide_db: + type: directory + description: | + ChocoPhlAn nucleotide database directory (v3: *.ffn.gz, v4: *.fna.gz) + - protein_db: + type: directory + description: | + UniRef protein database directory containing *.dmnd files + - utility_db: + type: directory + description: | + HUMAnN utility mapping database directory +output: + genefamilies: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_genefamilies.tsv.gz": + type: file + description: Compressed gene families abundance table + pattern: "*.{tsv.gz}" + ontologies: [] + pathabundance: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_pathabundance.tsv.gz": + type: file + description: Compressed pathway abundance table + pattern: "*.{tsv.gz}" + ontologies: [] + pathcoverage: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_pathcoverage.tsv.gz": + type: file + description: Compressed pathway coverage table + pattern: "*.{tsv.gz}" + ontologies: [] + reactions: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_reactions.tsv.gz": + type: file + description: Compressed reactions abundance table + pattern: "*.{tsv.gz}" + ontologies: [] + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*.log": + type: file + description: HUMAnN run log file + pattern: "*.{log}" + ontologies: [] + versions_humann: + - - ${task.process}: + type: string + description: The name of the process + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + versions_metaphlan: + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + versions_python: + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | 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 + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | sed 's/Python //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@nickp60" + - "@d4straub" + - "@vinisalazar" +maintainers: + - "@nickp60" + - "@vinisalazar" diff --git a/modules/nf-core/humann3/humann/tests/main.nf.test b/modules/nf-core/humann3/humann/tests/main.nf.test new file mode 100644 index 0000000..280dc2a --- /dev/null +++ b/modules/nf-core/humann3/humann/tests/main.nf.test @@ -0,0 +1,124 @@ +nextflow_process { + + name "Test Process HUMANN3_HUMANN" + script "../main.nf" + process "HUMANN3_HUMANN" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "humann3" + tag "humann3/humann" + tag "metaphlan/metaphlan" + tag "untar" + setup{ + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.modules_testdata_base_path + 'delete_me/metaphlan4_database.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("UNTAR", alias: "UNTAR_v3_nuc") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'data/database/humann/v3/chocophlan_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("UNTAR", alias: "UNTAR_v3_prot") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'data/database/humann/v3/uniref_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("UNTAR", alias: "UNTAR_v3_util") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'data/database/humann/v3/utility_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("METAPHLAN_METAPHLAN", alias: "MPAHUMANN3") { + script "../../../../nf-core/metaphlan/metaphlan/main.nf" + 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] = UNTAR.out.untar.map{ it[1] } + input[2] = false + """ + } + } + } + test("humann3 sarscov2 - fastq") { + when { + process { + """ + input[0]= Channel.of([ + [ id:'test', single_end:false, run_accession:"abc" ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + ]) + input[1] = MPAHUMANN3.out.profile + input[2] = UNTAR_v3_nuc.out.untar.map{ it[1] } + input[3] = UNTAR_v3_prot.out.untar.map{ it[1] } + input[4] = UNTAR_v3_util.out.untar.map{ it[1] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.pathabundance, process.out.pathcoverage, process.out.reactions, process.out.findAll { key, val -> key.startsWith('versions') }).match() } + ) + } + + } + + test("humann3 sarscov2 - fastq - stub") { + + options "-stub" + + when { + process { + """ + input[0]= Channel.of([ + [ id:'test', single_end:false, run_accession:"abc" ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + ]) + input[1] = MPAHUMANN3.out.profile + input[2] = UNTAR_v3_nuc.out.untar.map{ it[1] } + input[3] = UNTAR_v3_prot.out.untar.map{ it[1] } + input[4] = UNTAR_v3_util.out.untar.map{ it[1] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.pathabundance, process.out.pathcoverage, process.out.reactions, process.out.findAll { key, val -> key.startsWith('versions') }).match() } + ) + } + + } +} diff --git a/modules/nf-core/humann3/humann/tests/main.nf.test.snap b/modules/nf-core/humann3/humann/tests/main.nf.test.snap new file mode 100644 index 0000000..81ce7bf --- /dev/null +++ b/modules/nf-core/humann3/humann/tests/main.nf.test.snap @@ -0,0 +1,119 @@ +{ + "humann3 sarscov2 - fastq - stub": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_pathabundance.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_pathcoverage.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_reactions.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + { + "versions_humann": [ + [ + "HUMANN3_HUMANN", + "HUMAnN", + "3.6.1" + ] + ], + "versions_metaphlan": [ + [ + "HUMANN3_HUMANN", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "versions_python": [ + [ + "HUMANN3_HUMANN", + "Python", + "3.10.8" + ] + ] + } + ], + "timestamp": "2026-05-19T18:08:28.27672", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "humann3 sarscov2 - fastq": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_pathabundance.tsv.gz:md5,65f73f474bdb2a7c8b278766ca789a3c" + ] + ], + [ + [ + { + "id": "test", + "single_end": false, + "run_accession": "abc" + }, + "test_pathcoverage.tsv.gz:md5,17c91a2581f34b55179aa4c79c242b1c" + ] + ], + [ + + ], + { + "versions_humann": [ + [ + "HUMANN3_HUMANN", + "HUMAnN", + "3.6.1" + ] + ], + "versions_metaphlan": [ + [ + "HUMANN3_HUMANN", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "versions_python": [ + [ + "HUMANN3_HUMANN", + "Python", + "3.10.8" + ] + ] + } + ], + "timestamp": "2026-05-19T18:08:05.120967", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/humann3/humann/tests/nextflow.config b/modules/nf-core/humann3/humann/tests/nextflow.config new file mode 100644 index 0000000..ff0dbb6 --- /dev/null +++ b/modules/nf-core/humann3/humann/tests/nextflow.config @@ -0,0 +1,3 @@ +params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/funcprofiler/' +} diff --git a/modules/nf-core/humann3/regroup/environment.yml b/modules/nf-core/humann3/regroup/environment.yml new file mode 100644 index 0000000..3dc3f34 --- /dev/null +++ b/modules/nf-core/humann3/regroup/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::humann=3.6.1 + - bioconda::metaphlan=4.0.6 + - conda-forge::python=3.10.8 diff --git a/modules/nf-core/humann3/regroup/main.nf b/modules/nf-core/humann3/regroup/main.nf new file mode 100644 index 0000000..24e8116 --- /dev/null +++ b/modules/nf-core/humann3/regroup/main.nf @@ -0,0 +1,58 @@ +process HUMANN3_REGROUP { + 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/humann:3.6.1--pyh7cba7a3_0' : + 'quay.io/biocontainers/humann:3.6.1--pyh7cba7a3_0' }" + + input: + tuple val(meta), path(input) + val groups + path utility_db + + output: + tuple val(meta), path("*_regroup.tsv.gz"), emit: regroup + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + tuple val("${task.process}"), val('MetaPhlAn'), eval("metaphlan --version 2>&1 | sed 's/MetaPhlAn version //'"), emit: versions_metaphlan, topic: versions + tuple val("${task.process}"), val('Python'), eval("python --version 2>&1 | sed 's/Python //'"), emit: versions_python, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + if [[ $input == *.gz ]]; then + gunzip -c $input > input.tsv + else + cp $input input.tsv + fi + + printf '%s\n' \\ + 'import os, sys' \\ + 'import humann.config as config' \\ + 'config.utility_mapping_database = os.environ["HUMANN_UTILITY_DB"]' \\ + 'from humann.tools.regroup_table import main' \\ + 'sys.exit(main())' \\ + > run_regroup.py + + export HUMANN_UTILITY_DB="${utility_db}" + + python run_regroup.py \\ + --input input.tsv \\ + --output ${prefix}_regroup.tsv \\ + --groups ${groups} \\ + ${args} + + gzip -n ${prefix}_regroup.tsv + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}_regroup.tsv.gz + """ +} diff --git a/modules/nf-core/humann3/regroup/meta.yml b/modules/nf-core/humann3/regroup/meta.yml new file mode 100644 index 0000000..417a34c --- /dev/null +++ b/modules/nf-core/humann3/regroup/meta.yml @@ -0,0 +1,116 @@ +name: humann3_regroup +description: Regrouping genes to other functional categories +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network, version 3" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann3 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: + - "MIT" + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: Tab separated abundance file of HUMAnN3 + pattern: "*.{tsv.gz,tsv}" + - groups: + type: string + description: Regroup abundance values to a functional category (e.g. uniref90_rxn, uniref50_rxn) + pattern: "{uniref90_rxn,uniref50_rxn}" + - utility_db: + type: directory + description: HUMAnN utility mapping database directory + +output: + regroup: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_regroup.tsv.gz": + type: file + description: Re-grouped compressed tab separated text file + pattern: "*.{tsv.gz}" + versions_humann: + - - ${task.process}: + type: string + description: The name of the process + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + versions_metaphlan: + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + versions_python: + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | 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 + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | sed 's/Python //': + type: eval + description: The expression to obtain the version of the tool + +authors: + - "@d4straub" + - "@nickp60" + - "@vinisalazar" +maintainers: + - "@nickp60" + - "@vinisalazar" diff --git a/modules/nf-core/humann3/regroup/tests/main.nf.test b/modules/nf-core/humann3/regroup/tests/main.nf.test new file mode 100644 index 0000000..d052638 --- /dev/null +++ b/modules/nf-core/humann3/regroup/tests/main.nf.test @@ -0,0 +1,73 @@ +nextflow_process { + + name "Test Process HUMANN3_REGROUP" + script "../main.nf" + process "HUMANN3_REGROUP" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "humann3" + tag "humann3/regroup" + tag "untar" + setup { + run("UNTAR", alias: "UNTAR_v3_util") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.pipelines_testdata_base_path + 'data/database/humann/v3/utility_nfDEMO.tar.gz', checkIfExists: true ) + ]) + """ + } + } + } + test("humann3_regroup - tsv") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file( params.modules_testdata_base_path + 'genomics/prokaryotes/metagenome/biobakery/test_genefamilies.tsv', checkIfExists: true ) + ]) + input[1] = "uniref90_level4ec" + input[2] = UNTAR_v3_util.out.untar.map{ it[1] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("humann3_regroup - tsv - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file( params.modules_testdata_base_path + 'genomics/prokaryotes/metagenome/biobakery/test_genefamilies.tsv', checkIfExists: true ) + ]) + input[1] = "uniref90_level4ec" + input[2] = UNTAR_v3_util.out.untar.map{ it[1] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/humann3/regroup/tests/main.nf.test.snap b/modules/nf-core/humann3/regroup/tests/main.nf.test.snap new file mode 100644 index 0000000..187a94e --- /dev/null +++ b/modules/nf-core/humann3/regroup/tests/main.nf.test.snap @@ -0,0 +1,144 @@ +{ + "humann3_regroup - tsv - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "HUMANN3_REGROUP", + "HUMAnN", + "3.6.1" + ] + ], + "2": [ + [ + "HUMANN3_REGROUP", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "3": [ + [ + "HUMANN3_REGROUP", + "Python", + "3.10.8" + ] + ], + "regroup": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_humann": [ + [ + "HUMANN3_REGROUP", + "HUMAnN", + "3.6.1" + ] + ], + "versions_metaphlan": [ + [ + "HUMANN3_REGROUP", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "versions_python": [ + [ + "HUMANN3_REGROUP", + "Python", + "3.10.8" + ] + ] + } + ], + "timestamp": "2026-05-19T18:33:38.31929", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "humann3_regroup - tsv": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,7b00828cbce7a2aa5ece4db335d2fd28" + ] + ], + "1": [ + [ + "HUMANN3_REGROUP", + "HUMAnN", + "3.6.1" + ] + ], + "2": [ + [ + "HUMANN3_REGROUP", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "3": [ + [ + "HUMANN3_REGROUP", + "Python", + "3.10.8" + ] + ], + "regroup": [ + [ + { + "id": "test", + "single_end": false + }, + "test_regroup.tsv.gz:md5,7b00828cbce7a2aa5ece4db335d2fd28" + ] + ], + "versions_humann": [ + [ + "HUMANN3_REGROUP", + "HUMAnN", + "3.6.1" + ] + ], + "versions_metaphlan": [ + [ + "HUMANN3_REGROUP", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "versions_python": [ + [ + "HUMANN3_REGROUP", + "Python", + "3.10.8" + ] + ] + } + ], + "timestamp": "2026-05-19T18:33:27.694488", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/humann3/regroup/tests/nextflow.config b/modules/nf-core/humann3/regroup/tests/nextflow.config new file mode 100644 index 0000000..ff0dbb6 --- /dev/null +++ b/modules/nf-core/humann3/regroup/tests/nextflow.config @@ -0,0 +1,3 @@ +params { + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/funcprofiler/' +} diff --git a/modules/nf-core/humann3/renorm/environment.yml b/modules/nf-core/humann3/renorm/environment.yml new file mode 100644 index 0000000..3dc3f34 --- /dev/null +++ b/modules/nf-core/humann3/renorm/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::humann=3.6.1 + - bioconda::metaphlan=4.0.6 + - conda-forge::python=3.10.8 diff --git a/modules/nf-core/humann3/renorm/main.nf b/modules/nf-core/humann3/renorm/main.nf new file mode 100644 index 0000000..7611a17 --- /dev/null +++ b/modules/nf-core/humann3/renorm/main.nf @@ -0,0 +1,48 @@ +process HUMANN3_RENORM { + 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/humann:3.6.1--pyh7cba7a3_0' : + 'quay.io/biocontainers/humann:3.6.1--pyh7cba7a3_0' }" + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path("*_renorm.tsv.gz"), emit: renorm + tuple val("${task.process}"), val('HUMAnN'), eval("humann --version 2>&1 | sed 's/humann v//'"), emit: versions_humann, topic: versions + tuple val("${task.process}"), val('MetaPhlAn'), eval("metaphlan --version 2>&1 | sed 's/MetaPhlAn version //'"), emit: versions_metaphlan, topic: versions + tuple val("${task.process}"), val('Python'), eval("python --version 2>&1 | sed 's/Python //'"), emit: versions_python, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + if [[ $input == *.gz ]]; then + gunzip -c $input > input.tsv + else + mv $input input.tsv + fi + + humann_renorm_table \\ + --input input.tsv \\ + --output ${prefix}_renorm.tsv \\ + $args + + gzip -n ${prefix}_renorm.tsv + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}_renorm.tsv.gz + + """ +} diff --git a/modules/nf-core/humann3/renorm/meta.yml b/modules/nf-core/humann3/renorm/meta.yml new file mode 100644 index 0000000..465ed44 --- /dev/null +++ b/modules/nf-core/humann3/renorm/meta.yml @@ -0,0 +1,109 @@ +name: humann3_renorm +description: Normalizing RPKs to relative abundance +keywords: + - function + - metagenomics + - metatranscriptomics + - profiling + - community +tools: + - humann: + description: "HUMAnN: The HMP Unified Metabolic Analysis Network, version 3" + homepage: http://huttenhower.sph.harvard.edu/humann + documentation: https://github.com/biobakery/biobakery/wiki/humann3 + tool_dev_url: https://github.com/biobakery/humann + doi: "10.7554/eLife.65088" + licence: + - "MIT" + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - input: + type: file + description: Tab separated abundance file of HUMAnN3 + pattern: "*.{tsv.gz,tsv}" + +output: + renorm: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "*_renorm.tsv.gz": + type: file + description: Normalized compressed tab separated text file + pattern: "*.{tsv.gz}" + versions_humann: + - - ${task.process}: + type: string + description: The name of the process + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + versions_metaphlan: + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + versions_python: + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | 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 + - HUMAnN: + type: string + description: The name of the tool + - humann --version 2>&1 | sed 's/humann v//': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - MetaPhlAn: + type: string + description: The name of the tool + - metaphlan --version 2>&1 | sed 's/MetaPhlAn version //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - Python: + type: string + description: The name of the tool + - python --version 2>&1 | sed 's/Python //': + type: eval + description: The expression to obtain the version of the tool + +authors: + - "@d4straub" + - "@nickp60" + - "@vinisalazar" +maintainers: + - "@nickp60" + - "@vinisalazar" diff --git a/modules/nf-core/humann3/renorm/tests/main.nf.test b/modules/nf-core/humann3/renorm/tests/main.nf.test new file mode 100644 index 0000000..5a00afa --- /dev/null +++ b/modules/nf-core/humann3/renorm/tests/main.nf.test @@ -0,0 +1,35 @@ +nextflow_process { + + name "Test Process HUMANN3_RENORM" + script "../main.nf" + process "HUMANN3_RENORM" + tag "modules" + tag "modules_nfcore" + tag "humann3" + tag "humann3/renorm" + + test("humann3_renorm sarscov2 - tsv - 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) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/humann3/renorm/tests/main.nf.test.snap b/modules/nf-core/humann3/renorm/tests/main.nf.test.snap new file mode 100644 index 0000000..2f25059 --- /dev/null +++ b/modules/nf-core/humann3/renorm/tests/main.nf.test.snap @@ -0,0 +1,73 @@ +{ + "humann3_renorm sarscov2 - tsv - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_renorm.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "HUMANN3_RENORM", + "HUMAnN", + "3.6.1" + ] + ], + "2": [ + [ + "HUMANN3_RENORM", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "3": [ + [ + "HUMANN3_RENORM", + "Python", + "3.10.8" + ] + ], + "renorm": [ + [ + { + "id": "test", + "single_end": false + }, + "test_renorm.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_humann": [ + [ + "HUMANN3_RENORM", + "HUMAnN", + "3.6.1" + ] + ], + "versions_metaphlan": [ + [ + "HUMANN3_RENORM", + "MetaPhlAn", + "4.0.6 (1 Mar 2023)" + ] + ], + "versions_python": [ + [ + "HUMANN3_RENORM", + "Python", + "3.10.8" + ] + ] + } + ], + "timestamp": "2026-05-19T18:07:13.55885", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/metaphlan/metaphlan/environment.yml b/modules/nf-core/metaphlan/metaphlan/environment.yml new file mode 100644 index 0000000..572f03f --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/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: + - bioconda::metaphlan=4.1.1 + - pip + - pip: + - setuptools diff --git a/modules/nf-core/metaphlan/metaphlan/main.nf b/modules/nf-core/metaphlan/metaphlan/main.nf new file mode 100644 index 0000000..953abfc --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/main.nf @@ -0,0 +1,74 @@ +process METAPHLAN_METAPHLAN { + tag "${meta.id}" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/metaphlan:4.1.1--pyhdfd78af_0' + : 'quay.io/biocontainers/metaphlan:4.1.1--pyhdfd78af_0'}" + + input: + tuple val(meta), path(input) + path metaphlan_db_latest + val save_samfile + + output: + tuple val(meta), path("*_profile.txt"), emit: profile + tuple val(meta), path("*.biom"), emit: biom + tuple val(meta), path('*.bowtie2out.txt'), optional: true, emit: bt2out + tuple val(meta), path("*.sam"), optional: true, emit: sam + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def input_type = "${input}" =~ /.*\.(fastq|fq)/ ? "--input_type fastq" : "${input}" =~ /.*\.(fasta|fna|fa)/ ? "--input_type fasta" : "${input}".endsWith(".bowtie2out.txt") ? "--input_type bowtie2out" : "--input_type sam" + def input_data = ("${input_type}".contains("fastq")) && !meta.single_end ? "${input[0]},${input[1]}" : "${input}" + def bowtie2_out = "${input_type}" == "--input_type bowtie2out" || "${input_type}" == "--input_type sam" ? '' : "--bowtie2out ${prefix}.bowtie2out.txt" + def samfile_out = save_samfile ? "-s ${prefix}.sam" : '' + """ + BT2_DB=`find -L "${metaphlan_db_latest}" -name "*rev.1.bt2*" -exec dirname {} \\;` + BT2_DB_INDEX=`find -L ${metaphlan_db_latest} -name "*.rev.1.bt2*" | sed 's/\\.rev.1.bt2.*\$//' | sed 's/.*\\///'` + + metaphlan \\ + --nproc ${task.cpus} \\ + ${input_type} \\ + ${input_data} \\ + ${args} \\ + ${bowtie2_out} \\ + ${samfile_out} \\ + --bowtie2db \$BT2_DB \\ + --index \$BT2_DB_INDEX \\ + --biom ${prefix}.biom \\ + --output_file ${prefix}_profile.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def samfile_cmd = save_samfile ? "touch ${prefix}.sam" : '' + def input_type = "${input}" =~ /.*\.(fastq|fq)/ ? "fastq" : + "${input}" =~ /.*\.(fasta|fna|fa)/? "fasta" : + "${input}".endsWith(".bowtie2out.txt") ? "bowtie2out" : + "sam" + def bowtie2_cmd = "${input_type}" == "bowtie2out" || "${input_type}" == "sam" ? '' : "touch ${prefix}.bowtie2out.txt" + + """ + touch ${prefix}.biom + touch ${prefix}_profile.txt + ${samfile_cmd} + ${bowtie2_cmd} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') + END_VERSIONS + """ +} diff --git a/modules/nf-core/metaphlan/metaphlan/meta.yml b/modules/nf-core/metaphlan/metaphlan/meta.yml new file mode 100644 index 0000000..8bc6c07 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/meta.yml @@ -0,0 +1,105 @@ +name: metaphlan_metaphlan +description: MetaPhlAn is a tool for profiling the composition of microbial communities + from metagenomic shotgun sequencing data. +keywords: + - metagenomics + - classification + - fastq + - fasta + - sam +tools: + - metaphlan: + description: Identify clades (phyla to species) present in the metagenome obtained + from a microbiome sample and their relative abundance + homepage: https://huttenhower.sph.harvard.edu/metaphlan/ + documentation: https://github.com/biobakery/MetaPhlAn + doi: "10.1038/s41587-023-01688-w" + licence: ["MIT License"] + identifier: biotools:metaphlan +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: Metaphlan can classify the metagenome from a variety of input data + types, including FASTQ files (single-end and paired-end), FASTA, bowtie2-produced + SAM files (produced from alignments to the MetaPHlAn marker database) and + intermediate bowtie2 alignment files (bowtie2out) + pattern: "*.{fastq.gz, fasta, fasta.gz, sam, bowtie2out.txt}" + ontologies: [] + - metaphlan_db_latest: + type: file + description: | + Directory containing pre-downloaded and uncompressed MetaPhlAn database downloaded from: http://cmprod1.cibio.unitn.it/biobakery4/metaphlan_databases/. + Note that you will also need to specify `--index` and the database version name (e.g. 'mpa_vJan21_TOY_CHOCOPhlAnSGB_202103') in your module.conf ext.args for METAPHLAN_METAPHLAN! + pattern: "*/" + ontologies: [] + - save_samfile: + type: boolean + description: | + Whether to save the SAM file produced by MetaPhlAn of read alignments to MetaPhlAn database gene sequences +output: + profile: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*_profile.txt": + type: file + description: Tab-separated output file of the predicted taxon relative abundances + pattern: "*.{txt}" + ontologies: [] + biom: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.biom": + type: file + description: General-use format for representing biological sample by observation + contingency tables + pattern: "*.{biom}" + ontologies: + - edam: http://edamontology.org/format_3746 # BIOM format + bt2out: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bowtie2out.txt": + type: file + description: Intermediate Bowtie2 output produced from mapping the metagenome + against the MetaPHlAn marker database ( not compatible with `bowtie2out` + files generated with MetaPhlAn versions below 3 ) + pattern: "*.{bowtie2out.txt}" + ontologies: [] + sam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.sam": + type: file + description: SAM file produced by MetaPPhlAn of read alignments to MetaPhlAn database gene sequences + pattern: "*.{sam}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@MGordon09" + - "@LilyAnderssonLee" +maintainers: + - "@MGordon09" + - "@LilyAnderssonLee" diff --git a/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test new file mode 100644 index 0000000..606f060 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test @@ -0,0 +1,171 @@ +nextflow_process { + name "Test Process METAPHLAN_METAPHLAN" + script "../main.nf" + config "./nextflow.config" + + process "METAPHLAN_METAPHLAN" + tag "modules" + tag "modules_nfcore" + tag "untar" + tag "metaphlan" + tag "metaphlan/metaphlan" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.modules_testdata_base_path + 'delete_me/metaphlan4_database.tar.gz', checkIfExists: true ) + ]) + """ + } + } + } + + test("sarscov2 - illumina single end [fastq]") { + + + 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 ) + ]) + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.profile[0][1]).readLines()[2..5], + path(process.out.biom[0][1]).readLines().last().contains('Biological Observation Matrix'), + process.out.bt2out, + process.out.versions + ).match() + } + ) + } + } + + test("sarscov2 - illumina pair end [fastq]") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz',checkIfExists: true ), + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz',checkIfExists: true ) ] + ]) + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.profile[0][1]).readLines()[2..5], + path(process.out.biom[0][1]).readLines().last().contains('Biological Observation Matrix'), + process.out.bt2out, + process.out.versions + ).match() + } + ) + } + } + + test("sarscov2 - illumina single end [fasta]") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta',checkIfExists: true ) + ]) + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.profile[0][1]).readLines()[2..5], + path(process.out.biom[0][1]).readLines().last().contains('Biological Observation Matrix'), + process.out.bt2out, + process.out.versions + ).match() + } ) + } + } + + test("sarscov2 - illumina pair end [fastq] - save sam") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz',checkIfExists: true ), + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz',checkIfExists: true )] + ]) + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.profile[0][1]).readLines()[2..5], + path(process.out.biom[0][1]).readLines().last().contains('Biological Observation Matrix'), + process.out.bt2out, + sam(process.out.sam.get(0).get(1)).getFileType(), + process.out.versions + ).match() + } + ) + } + } + + test("sarscov2 - illumina pair end [fastq] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz',checkIfExists: true ), + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz',checkIfExists: true )] + ]) + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } +} diff --git a/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test.snap b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test.snap new file mode 100644 index 0000000..a5b0f9a --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test.snap @@ -0,0 +1,192 @@ +{ + "sarscov2 - illumina pair end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_profile.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.biom:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2out.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ], + "biom": [ + [ + { + "id": "test", + "single_end": false + }, + "test.biom:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bt2out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2out.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "profile": [ + [ + { + "id": "test", + "single_end": false + }, + "test_profile.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + + ], + "versions": [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + } + ], + "timestamp": "2026-02-16T10:17:01.145927415", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - illumina pair end [fastq] - save sam": { + "content": [ + [ + "#196 reads processed", + "#SampleID\tMetaphlan_Analysis", + "#clade_name\tNCBI_tax_id\trelative_abundance\tadditional_species", + "UNCLASSIFIED\t-1\t100.0\t" + ], + true, + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2out.txt:md5,8c1bc21e1d8484b5551bf46331d61bd8" + ] + ], + "SAM", + [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + ], + "timestamp": "2025-08-22T07:33:29.981757425", + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + } + }, + "sarscov2 - illumina single end [fastq]": { + "content": [ + [ + "#100 reads processed", + "#SampleID\tMetaphlan_Analysis", + "#clade_name\tNCBI_tax_id\trelative_abundance\tadditional_species", + "UNCLASSIFIED\t-1\t100.0\t" + ], + true, + [ + [ + { + "id": "test", + "single_end": true + }, + "test.bowtie2out.txt:md5,ef46a9c6a8ce9cae26fbfd5527116fd5" + ] + ], + [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + ], + "timestamp": "2024-08-27T10:33:32.269571148", + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + } + }, + "sarscov2 - illumina single end [fasta]": { + "content": [ + [ + "#4 reads processed", + "#SampleID\tMetaphlan_Analysis", + "#clade_name\tNCBI_tax_id\trelative_abundance\tadditional_species", + "UNCLASSIFIED\t-1\t100.0\t" + ], + true, + [ + [ + { + "id": "test", + "single_end": true + }, + "test.bowtie2out.txt:md5,d99d05d6b011c647adf816f10fc6acbe" + ] + ], + [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + ], + "timestamp": "2024-08-27T10:34:10.262604527", + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + } + }, + "sarscov2 - illumina pair end [fastq]": { + "content": [ + [ + "#196 reads processed", + "#SampleID\tMetaphlan_Analysis", + "#clade_name\tNCBI_tax_id\trelative_abundance\tadditional_species", + "UNCLASSIFIED\t-1\t100.0\t" + ], + true, + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2out.txt:md5,8c1bc21e1d8484b5551bf46331d61bd8" + ] + ], + [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + ], + "timestamp": "2024-08-27T10:33:51.829732777", + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/metaphlan/metaphlan/tests/nextflow.config b/modules/nf-core/metaphlan/metaphlan/tests/nextflow.config new file mode 100644 index 0000000..e64f0f9 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/nextflow.config @@ -0,0 +1,10 @@ +docker { + fixOwnership = true + runOptions = '--platform=linux/amd64' +} + +process { + withName: UNTAR { + ext.args2 = "--no-same-owner" + } +} diff --git a/modules/nf-core/mifaser/environment.yml b/modules/nf-core/mifaser/environment.yml new file mode 100644 index 0000000..62896ba --- /dev/null +++ b/modules/nf-core/mifaser/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::mifaser=1.64 diff --git a/modules/nf-core/mifaser/main.nf b/modules/nf-core/mifaser/main.nf new file mode 100644 index 0000000..ea54520 --- /dev/null +++ b/modules/nf-core/mifaser/main.nf @@ -0,0 +1,50 @@ +process MIFASER { + 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/mifaser:1.64--pyh106432d_0' : + 'quay.io/biocontainers/mifaser:1.64--pyh106432d_0' }" + + input: + tuple val(meta), path(reads) + path(db) + + output: + tuple val(meta), path("*multi_ec.tsv"), emit: multi_ec + tuple val(meta), path("*analysis.tsv"), emit: analysis + tuple val(meta), path("*ec_count.tsv"), emit: ec_counts + tuple val("${task.process}"), val('mi-faser'), eval("mifaser --version 2>&1 | sed 's/* v//'"), emit: versions_mifaser, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def input_flag = meta.single_end ? "-f" : "-l" + """ + mifaser \\ + ${args} \\ + ${input_flag} ${reads} \\ + --threads 1 \\ + --cpu ${task.cpus} \\ + --databasefolder \$PWD/${db} \\ + --outputfolder mifaser-${prefix}/ + + for suf in multi_ec.tsv analysis.tsv ec_count.tsv; do + mv mifaser-${prefix}/\${suf} ${prefix}_\${suf} + done + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo ${args} + for suf in multi_ec.tsv analysis.tsv ec_count.tsv; do + touch ${prefix}_\${suf} + done + """ +} diff --git a/modules/nf-core/mifaser/meta.yml b/modules/nf-core/mifaser/meta.yml new file mode 100644 index 0000000..932e416 --- /dev/null +++ b/modules/nf-core/mifaser/meta.yml @@ -0,0 +1,91 @@ +name: "mifaser" +description: Functional annotation of metagenomic reads by assigning enzyme + commission (EC) numbers +keywords: + - metagenomics + - functional annotation + - EC numbers + - fastq +tools: + - "mifaser": + description: "mi-faser: microsecond functional annotation of sequences, a massive + scalability upgrade" + homepage: "https://sourceforge.net/projects/mifaser/" + documentation: "https://sourceforge.net/projects/mifaser/" + tool_dev_url: "https://sourceforge.net/projects/mifaser/" + doi: "10.1093/nar/gkx1209" + licence: + - "NPOSL-3.0" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:true ]` + - reads: + type: file + description: | + Single-end or paired-end FASTQ files. Use meta.single_end to indicate input type. + pattern: "*.{fastq,fastq.gz,fq,fq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" + - db: + type: directory + description: Path to the mi-faser database folder +output: + multi_ec: + - - meta: + type: map + description: Groovy Map containing sample information + - "*multi_ec.tsv": + type: file + description: TSV file with multi-EC functional assignments per read + pattern: "*multi_ec.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 + analysis: + - - meta: + type: map + description: Groovy Map containing sample information + - "*analysis.tsv": + type: file + description: TSV file with per-sample functional analysis summary + pattern: "*analysis.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 + ec_counts: + - - meta: + type: map + description: Groovy Map containing sample information + - "*ec_count.tsv": + type: file + description: TSV file with EC number counts + pattern: "*ec_count.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 + versions_mifaser: + - - "${task.process}": + type: string + description: Process name + - "mi-faser": + type: string + description: Tool name + - "mifaser --version 2>&1 | sed 's/* v//'": + type: eval + description: mifaser version string +topics: + versions: + - - "${task.process}": + type: string + description: Process name + - "mi-faser": + type: string + description: Tool name + - "mifaser --version 2>&1 | sed 's/* v//'": + type: eval + description: mifaser version string +authors: + - "@nickp60" +maintainers: + - "@nickp60" diff --git a/modules/nf-core/mifaser/tests/main.nf.test b/modules/nf-core/mifaser/tests/main.nf.test new file mode 100644 index 0000000..954ba2b --- /dev/null +++ b/modules/nf-core/mifaser/tests/main.nf.test @@ -0,0 +1,73 @@ +nextflow_process { + + name "Test Process MIFASER" + script "../main.nf" + process "MIFASER" + tag "modules" + tag "modules_nfcore" + tag "mifaser" + tag "untar" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( + 'https://github.com/nf-core/test-datasets/raw/refs/heads/funcprofiler/data/database/mifaser/GS-24-all.tar.gz', + checkIfExists: true + ) + ]) + """ + } + } + } + + test("sarscov2 - single-end fastq") { + 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) ] + ] + input[1] = UNTAR.out.untar.map { it[1] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.multi_ec, + process.out.analysis, + process.out.ec_counts, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("sarscov2 - single-end fastq - 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) ] + ] + input[1] = UNTAR.out.untar.map{ meta, dir -> dir.resolve("database/mifaser/GS-24-all") } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/mifaser/tests/main.nf.test.snap b/modules/nf-core/mifaser/tests/main.nf.test.snap new file mode 100644 index 0000000..b14ab23 --- /dev/null +++ b/modules/nf-core/mifaser/tests/main.nf.test.snap @@ -0,0 +1,126 @@ +{ + "sarscov2 - single-end fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_multi_ec.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_analysis.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test_ec_count.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + "MIFASER", + "mi-faser", + "mifaser 1.64 (07/21/25)" + ] + ], + "analysis": [ + [ + { + "id": "test", + "single_end": true + }, + "test_analysis.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ec_counts": [ + [ + { + "id": "test", + "single_end": true + }, + "test_ec_count.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "multi_ec": [ + [ + { + "id": "test", + "single_end": true + }, + "test_multi_ec.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_mifaser": [ + [ + "MIFASER", + "mi-faser", + "mifaser 1.64 (07/21/25)" + ] + ] + } + ], + "timestamp": "2026-05-15T14:21:18.968578", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "sarscov2 - single-end fastq": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test_multi_ec.tsv:md5,08ad0cac1771a190e63cd76a3b3ab686" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_analysis.tsv:md5,722399e3bfd7af4273b36779a111db8a" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_ec_count.tsv:md5,195e3e0db1dd8b603a7e8d91e85e480d" + ] + ], + { + "versions_mifaser": [ + [ + "MIFASER", + "mi-faser", + "mifaser 1.64 (07/21/25)" + ] + ] + } + ], + "timestamp": "2026-05-15T14:21:10.040918", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} diff --git a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt new file mode 100644 index 0000000..2a91c22 --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt @@ -0,0 +1,1526 @@ + +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.5.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.5.20-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.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.5-py314hd8ed1ab_100.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.8.1-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.18.0-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/noarch/idna-3.15-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.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.19.1-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-7_h4a7cf45_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-7_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.8.1-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_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-7_h47877c9_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-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.33-pthreads_h94d23a6_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.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.42.1-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.2.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.35-pyhdfd78af_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.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.6-hdb14827_0.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.6-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.2-h35e630c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-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.41.0-pyh58ad624_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.41.0-py310h49dadd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.41.0-py310hcbd6021_0.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.13.4-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-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.5-habeac84_100_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.5-h4df99d1_100.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.5.9-py314h5bd0f2a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-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.53.1-hbc0de68_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.2-pyhcf101f3_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-pyhcf101f3_2.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.7.0-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-4.1.0-pyhcf101f3_0.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.5.0-py314h680f03e_0.conda +noarch: generic +sha256: a1c97297e867776760489537bc5ae36fa83a154be30e3b79385a39ca4cb058fe +md5: 1133126d840e75287d83947be3fc3e71 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7533 +timestamp: 1778594057496 +- 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.5.20-hbd8a1cb_0.conda +sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b +md5: 489b8e97e666c93f68fdb35c3c9b957f +depends: +- __unix +license: ISC +size: 129868 +timestamp: 1779289852439 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +sha256: 645655a3510e38e625da136595f3f16f2130c3263630cc3bc8f60f619ddbe490 +md5: 9fefff2f745ea1cc2ef15211a20c054a +depends: +- python >=3.10 +license: ISC +size: 134201 +timestamp: 1779285131141 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 +md5: a9167b9571f3baa9d448faa2139d1089 +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58872 +timestamp: 1775127203018 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +sha256: 99ab8ef815c4520cce3a7482c2513f377c14348206857661d84c76a55e030f97 +md5: 003767c47f1f0a474c4de268b57839c3 +depends: +- __unix +- python +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 104631 +timestamp: 1779108494556 +- 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.5-py314hd8ed1ab_100.conda +noarch: generic +sha256: 777882d2685f368417f31bbe1b28f73687fc6c8f6a5768bda20ffeefa6b07f5b +md5: a749029ce5d0632a913db19d17f944ab +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236682725 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.8.1-hecca717_0.conda +sha256: 29a10599d56d93bd750914888ebe6822d47722070762b4647b34d12df9f4476e +md5: d0757fd84af06f065eba49d39af6c546 +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat 2.8.1 hecca717_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 148238 +timestamp: 1779278694477 +- 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.18.0-h27c8c51_0.conda +sha256: e798086d8a65d55dc4c51f5746705639c9a5f2eeb0b8fc50e6152cfc0d69a4e8 +md5: 06965b2f9854d0b15e0443ee81fe83dc +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat >=2.8.1,<3.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- libgcc >=14 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 280882 +timestamp: 1779421631622 +- 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/noarch/idna-3.15-pyhcf101f3_0.conda +sha256: 3d25f9f6f7ab3e1ce6429fc8c8aae0335cf446692e715068488536d220cc43de +md5: 1b9083b7f00609605d1483dbc6071a81 +depends: +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 62642 +timestamp: 1779294335905 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +sha256: 43e2a5497cad1598ff88a3e69f69bc88b7b8f141fa63c60eab5db296317318b8 +md5: ffc17e785d64e12fc311af9184221839 +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +size: 34766 +timestamp: 1779714582554 +- 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.19.1-h0c24ade_0.conda +sha256: eb89c6c39f2f6a93db55723dbb2f6bba8c8e63e6312bf1abf13e6e9ff45849c8 +md5: f92f984b558e6e6204014b16d212b271 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.4.1,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 251086 +timestamp: 1778079286384 +- 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-7_h4a7cf45_openblas.conda +build_number: 7 +sha256: 081c850f99bc355821fac9c6e3727d40b3f8ce3beb50a5437cf03726b611ff39 +md5: 955b44e8b00b7f7ef4ce0130cef12394 +depends: +- libopenblas >=0.3.33,<0.3.34.0a0 +- libopenblas >=0.3.33,<1.0a0 +constrains: +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapack 3.11.0 7*_openblas +- liblapacke 3.11.0 7*_openblas +- mkl <2027 +license: BSD-3-Clause +license_family: BSD +size: 18716 +timestamp: 1778489854108 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-7_h0358290_openblas.conda +build_number: 7 +sha256: 956ae0bb1ec8b0c3663d75b151aceb0521b54e513bf97f621a035f9c87037970 +md5: 0675639dc24cb0032f199e7ff68e4633 +depends: +- libblas 3.11.0 7_h4a7cf45_openblas +constrains: +- liblapacke 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapack 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18675 +timestamp: 1778489861559 +- 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.8.1-hecca717_0.conda +sha256: 363018b25fdb5534c79783d912bd4b685a3547f4fc5996357ad548899b0ee8e7 +md5: 93764a5ca80616e9c10106cdaec92f74 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- expat 2.8.1.* +license: MIT +license_family: MIT +size: 77294 +timestamp: 1779278686680 +- 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_19.conda +sha256: 8e0a3b5e41272e5678499b5dfc4cddb673f9e935de01eb0767ce857001229f46 +md5: 57736f29cc2b0ec0b6c2952d3f101b6a +depends: +- __glibc >=2.17,<3.0.a0 +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_19 +- libgomp 15.2.0 he0feb66_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1041084 +timestamp: 1778269013026 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda +sha256: 9dcf54adfaa5e861123c2da4f2f0451a685464ea7e5a41ad91cf67b31d658d98 +md5: 331ee9b72b9dff570d56b1302c5ab37d +depends: +- libgcc 15.2.0 he0feb66_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27694 +timestamp: 1778269016987 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda +sha256: 561a42758ef25b9ce308c4e2cf56daee4f06138385a17e29a492cd928e00be6f +md5: 42bf7eca1a951735fa06c0e3c0d5c8e6 +depends: +- libgfortran5 15.2.0 h68bc16d_19 +constrains: +- libgfortran-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27655 +timestamp: 1778269042954 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda +sha256: 057978bb69fea29ed715a9b98adf71015c31baecc4aeb2bfc20d4fd5d83579d4 +md5: 85072b0ad177c966294f129b7c04a2d5 +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: 2483673 +timestamp: 1778269025089 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda +sha256: 5abe4ab9d93f6c9757d654f1969ae2267d4505315c1f2f8fe705fd60af084f1b +md5: faac990cb7aedc7f3a2224f2c9b0c26c +depends: +- __glibc >=2.17,<3.0.a0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 603817 +timestamp: 1778268942614 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda +sha256: 10056646c28115b174de81a44e23e3a0a3b95b5347d2e6c45cc6d49d35294256 +md5: 6178c6f2fb254558238ef4e6c56fb782 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 633831 +timestamp: 1775962768273 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-7_h47877c9_openblas.conda +build_number: 7 +sha256: 96962084921f197c9ad13fb7f8b324f2351d50ff3d8d962148751ad532f54a01 +md5: 6569b4f273740e25dc0dc7e3232c2a6c +depends: +- libblas 3.11.0 7_h4a7cf45_openblas +constrains: +- liblapacke 3.11.0 7*_openblas +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +license: BSD-3-Clause +license_family: BSD +size: 18694 +timestamp: 1778489869038 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda +sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d +md5: b88d90cad08e6bc8ad540cb310a761fb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- xz 5.8.3.* +license: 0BSD +size: 113478 +timestamp: 1775825492909 +- 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.33-pthreads_h94d23a6_0.conda +sha256: 3d9aa85648e5e18a6d66db98b8c4317cc426721ad7a220aa86330d1ccedc8903 +md5: 2d3278b721e40468295ca755c3b84070 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.33,<0.3.34.0a0 +license: BSD-3-Clause +license_family: BSD +size: 5931919 +timestamp: 1776993658641 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda +sha256: 377cfe037f3eeb3b1bf3ad333f724a64d32f315ee1958581fc671891d63d3f89 +md5: eba48a68a1a2b9d3c0d9511548db85db +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: zlib-acknowledgement +size: 317729 +timestamp: 1776315175087 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda +sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d +md5: 7dc38adcbf71e6b38748e919e16e0dce +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: blessing +size: 954962 +timestamp: 1777986471789 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda +sha256: dff1058c76ec6b8759e41cefa2508162d00e4a5e6721aa68ec3fd10094e702dc +md5: 5794b3bdc38177caf969dabd3af08549 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc 15.2.0 he0feb66_19 +constrains: +- libstdcxx-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5852044 +timestamp: 1778269036376 +- 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.42.1-h5347b49_0.conda +sha256: 3f0edf1280e2f6684a986f821eaa3e123d2694a00b31b96ca0d4a4c12c129231 +md5: 7d0a66598195ef00b6efc55aefc7453b +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 40163 +timestamp: 1779118517630 +- 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.2.0-pyhd8ed1ab_0.conda +sha256: 0c4c35376fe920714390d46e4b8d31c876d65f18e1655899e0763ec25f2a902f +md5: 6d03368f2b2b0a5fb6839df53b2eb5e0 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 69017 +timestamp: 1778169663339 +- 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.35-pyhdfd78af_1.conda +sha256: e86033aa55a9e915e2d0957e770bdb81e3feb26a227d1adb17f9d6c528da6a71 +md5: cdb20309681ba3ce8f52c110e214d4f3 +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +- pyaml-env +- pydantic >=2.7.1 +- python >=3.9,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard >=4 +license: GPL-3.0-or-later +license_family: GPL3 +size: 4282188 +timestamp: 1779465338806 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +sha256: 70f43d62450927d51673eecd8823e14f5b3cfebdb43cda1d502eba97162bab42 +md5: 6687827c332121727ce383919e1ec8c2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 284323 +timestamp: 1778929680962 +- 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.6-hdb14827_0.conda +sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 +md5: fc21868a1a5aacc937e7a18747acb8a5 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: X11 AND BSD-3-Clause +size: 918956 +timestamp: 1777422145199 +- 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.6-py314h2b28147_0.conda +sha256: bc61ae892973751a6b0e6ecea57ed6d7053224bddcb007165d6ceb1d7344ad47 +md5: f49b5f950379e0b97c35ca97682f7c6a +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- liblapack >=3.9.0,<4.0a0 +- python_abi 3.14.* *_cp314 +- libblas >=3.9.0,<4.0a0 +- libcblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8928909 +timestamp: 1779169198391 +- 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.2-h35e630c_0.conda +sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb +md5: da1b85b6a87e141f5140bb9924cecab0 +depends: +- __glibc >=2.17,<3.0.a0 +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3167099 +timestamp: 1775587756857 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 +md5: 4c06a92e74452cfa53623a81592e8934 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 91574 +timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda +sha256: 123d8a7c16c88658b4f29e9f115a047598c941708dade74fbaff373a32dbec5e +md5: 76c4757c0ec9d11f969e8eb44899307b +depends: +- python +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libtiff >=4.7.1,<4.8.0a0 +- openjpeg >=2.5.4,<3.0a0 +- libxcb >=1.17.0,<2.0a0 +- libwebp-base >=1.6.0,<2.0a0 +- zlib-ng >=2.3.3,<2.4.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- python_abi 3.14.* *_cp314 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- lcms2 >=2.18,<3.0a0 +- tk >=8.6.13,<8.7.0a0 +license: HPND +size: 1082797 +timestamp: 1775060059882 +- 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.41.0-pyh58ad624_0.conda +sha256: 70fc56877c4a095ee658d61924d8019768fbae4a48437058d181fc94b0a7c4d8 +md5: 25a883fed9f1f3f21ff317a3e7c92ac4 +depends: +- polars-runtime-32 ==1.41.0 +- 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.41.0 +- polars-runtime-64 ==1.41.0 +- polars-runtime-compat ==1.41.0 +license: MIT +size: 539656 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.41.0-py310h49dadd8_0.conda +noarch: python +sha256: e51ee3fe5259f2e115b2f78f8fbe3554e419c7c82b0c110878e12a5ff95ce3ab +md5: 7682765a1588e5ac887c99736d297c93 +depends: +- python +- __glibc >=2.17,<3.0.a0 +- libstdcxx >=14 +- libgcc >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 42578921 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.41.0-py310hcbd6021_0.conda +noarch: python +sha256: 29c3831c92394af11d9f7d04882dda9479ffbb76a3d36ba155d52159d67805fa +md5: cb0b620c9914a07a9022cb8b183ea9ee +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 +size: 41864944 +timestamp: 1779630722548 +- 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.13.4-pyhcf101f3_0.conda +sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f +md5: 729843edafc0899b3348bd3f19525b9d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- annotated-types >=0.6.0 +- pydantic-core ==2.46.4 +- python +license: MIT +license_family: MIT +size: 346511 +timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda +sha256: 802e216c39f1359aed60823b6e11d8ccd812b0ae1c81ae5ac1c81f99446409ab +md5: 0c96993dbeadf3a277cf757b9f1c9412 +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: 1895020 +timestamp: 1778084229247 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 +md5: 16c18772b340887160c79a6acc022db0 +depends: +- python >=3.10 +license: BSD-2-Clause +license_family: BSD +size: 893031 +timestamp: 1774796815820 +- 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.5-habeac84_100_cp314.conda +build_number: 100 +sha256: 55eed9bf2a3f6e90311276f0834737fe7c2d9ec3e5e2e557507858df4c7521e6 +md5: da92e59ff92f2d5ede4f612af20f583f +depends: +- __glibc >=2.17,<3.0.a0 +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-64 >=2.36.1 +- libexpat >=2.8.0,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.3,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.53.1,<4.0a0 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- openssl >=3.5.6,<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: 36745188 +timestamp: 1779236923603 +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.5-h4df99d1_100.conda +sha256: 41dd7da285d71d519257fa7dacb1cae060d5ebfaa5f92cba5994899d2978e943 +md5: 41954747ba952ec4b01e16c2c9e8d8ff +depends: +- cpython 3.14.5.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236703009 +- 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.5.9-py314h5bd0f2a_0.conda +sha256: c7a4aca4977c15c82d053b06cbc676460974c1b25757cfeea8a9a2497ac911f8 +md5: 9dd235b6ac69a0198080dac39f9891aa +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: 413611 +timestamp: 1778374155646 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da +md5: 4a85203c1d80c1059086ae860836ffb9 +depends: +- python >=3.10 +- certifi >=2023.5.7 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.26,<3 +- python +constrains: +- chardet >=3.0.2,<8 +license: Apache-2.0 +license_family: APACHE +size: 68709 +timestamp: 1778851103479 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +sha256: 3d6ba2c0fcdac3196ba2f0615b4104e532525ffa1335b50a2878be5ff488814a +md5: 0242025a3c804966bf71aa04eee82f66 +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: 208577 +timestamp: 1775991661559 +- 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.53.1-hbc0de68_0.conda +sha256: d167fa92781bcdcd3b9aaa6bb1cd50c5b108f6190c170098a118b5cf5df2f881 +md5: 8e0b8654ead18e50af552e54b5a08a61 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libsqlite 3.53.1 h0c1763c_0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 205399 +timestamp: 1777986477546 +- 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.2-pyhcf101f3_0.conda +sha256: 59d7851d32fddb5b510272e6557aa982edeb927d349648dac27f5bf01d18bb26 +md5: 4460f039b7dedf15f7df086446ca75ae +depends: +- typing_extensions >=4.14.0 +- python >=3.10 +- importlib-metadata >=3.6 +- python +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 38297 +timestamp: 1778779291237 +- 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-pyhcf101f3_2.conda +sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a +md5: 53f5409c5cfd6c5a66417d68e3f0a864 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +- python +license: MIT +license_family: MIT +size: 20935 +timestamp: 1777105465795 +- 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.7.0-pyhd8ed1ab_0.conda +sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 +md5: cbb88288f74dbe6ada1c6c7d0a97223e +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: 103560 +timestamp: 1778188657149 +- 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-4.1.0-pyhcf101f3_0.conda +sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 +md5: ba3dcdc8584155c97c648ae9c044b7a3 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24190 +timestamp: 1779159948016 +- 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_arm64-bd-5c84a5000a226ab5_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt new file mode 100644 index 0000000..3d5b93d --- /dev/null +++ b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt @@ -0,0 +1,1476 @@ + +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.5.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.5.20-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.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.5-py314hd8ed1ab_100.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.8.1-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.18.0-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/noarch/idna-3.15-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.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.19.1-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-7_haddc8a3_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-7_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.8.1-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_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-7_h88aeb00_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-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.33-pthreads_h9d3fd7e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.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.42.1-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.2.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.35-pyhdfd78af_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.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.6-hf8d1292_0.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.6-py314he1698a1_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.2-h546c87b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-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.41.0-pyh58ad624_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.41.0-py310h32c7c23_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.41.0-py310hc0e61be_0.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.13.4-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.4-py314h451b6cc_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-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.5-hfd9ac0a_100_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.5-h4df99d1_100.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.5.9-py314h51f160d_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-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.53.1-he8854b5_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.2-pyhcf101f3_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-pyhcf101f3_2.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.7.0-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-4.1.0-pyhcf101f3_0.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.5.0-py314h680f03e_0.conda +noarch: generic +sha256: a1c97297e867776760489537bc5ae36fa83a154be30e3b79385a39ca4cb058fe +md5: 1133126d840e75287d83947be3fc3e71 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7533 +timestamp: 1778594057496 +- 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.5.20-hbd8a1cb_0.conda +sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b +md5: 489b8e97e666c93f68fdb35c3c9b957f +depends: +- __unix +license: ISC +size: 129868 +timestamp: 1779289852439 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +sha256: 645655a3510e38e625da136595f3f16f2130c3263630cc3bc8f60f619ddbe490 +md5: 9fefff2f745ea1cc2ef15211a20c054a +depends: +- python >=3.10 +license: ISC +size: 134201 +timestamp: 1779285131141 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 +md5: a9167b9571f3baa9d448faa2139d1089 +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58872 +timestamp: 1775127203018 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +sha256: 99ab8ef815c4520cce3a7482c2513f377c14348206857661d84c76a55e030f97 +md5: 003767c47f1f0a474c4de268b57839c3 +depends: +- __unix +- python +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 104631 +timestamp: 1779108494556 +- 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.5-py314hd8ed1ab_100.conda +noarch: generic +sha256: 777882d2685f368417f31bbe1b28f73687fc6c8f6a5768bda20ffeefa6b07f5b +md5: a749029ce5d0632a913db19d17f944ab +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236682725 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.8.1-hfae3067_0.conda +sha256: a9cd5eb1700e11cc39acc36630a2d72a4e317943bd7c5695cd8804419f04ff42 +md5: 89f0247b3cea528d8ad1a6664a313153 +depends: +- libexpat 2.8.1 hfae3067_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 140114 +timestamp: 1779278679081 +- 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.18.0-hba86a56_0.conda +sha256: 1805f4ab3d9e1734a5a17abccc2cb0fdade51d4d5f29bdc410600ea0115ec050 +md5: b660d59a9d0fb3297327418624acaec3 +depends: +- libexpat >=2.8.1,<3.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- libgcc >=14 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 293348 +timestamp: 1779421661332 +- 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/noarch/idna-3.15-pyhcf101f3_0.conda +sha256: 3d25f9f6f7ab3e1ce6429fc8c8aae0335cf446692e715068488536d220cc43de +md5: 1b9083b7f00609605d1483dbc6071a81 +depends: +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 62642 +timestamp: 1779294335905 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +sha256: 43e2a5497cad1598ff88a3e69f69bc88b7b8f141fa63c60eab5db296317318b8 +md5: ffc17e785d64e12fc311af9184221839 +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +size: 34766 +timestamp: 1779714582554 +- 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.19.1-h9d5b58d_0.conda +sha256: 1e5f68e4b36a0e1a278c6dc026bc3d7775518a15832cbc9d7fc1c0e4c47784b1 +md5: b1f8bee3c53a6d2c103fb4a1ae44f5c4 +depends: +- libgcc >=14 +- libjpeg-turbo >=3.1.4.1,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 296899 +timestamp: 1778079402392 +- 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-7_haddc8a3_openblas.conda +build_number: 7 +sha256: f27ba323c2f1e1731b5e880fe520f178f55047f25be94f77e649605b2343c066 +md5: e8d07b777f6ff1fab69665336561910b +depends: +- libopenblas >=0.3.33,<0.3.34.0a0 +- libopenblas >=0.3.33,<1.0a0 +constrains: +- liblapack 3.11.0 7*_openblas +- libcblas 3.11.0 7*_openblas +- mkl <2027 +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18696 +timestamp: 1778489796402 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-7_hd72aa62_openblas.conda +build_number: 7 +sha256: c8f0192362966df0828419f042d6f94c079e5df00ad6bd05b5e84c12b42f8cc7 +md5: 90ac57b82c055faa9be25031864b7d8f +depends: +- libblas 3.11.0 7_haddc8a3_openblas +constrains: +- liblapack 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18664 +timestamp: 1778489802790 +- 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.8.1-hfae3067_0.conda +sha256: 1fc392b997c6ee2bd3226a7cd870d0edbcbb367e25f9f18dd4a7025fced6efc0 +md5: 513dd884361dfb8a554298ed69b58823 +depends: +- libgcc >=14 +constrains: +- expat 2.8.1.* +license: MIT +license_family: MIT +size: 77140 +timestamp: 1779278671302 +- 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_19.conda +sha256: 4592b096e553f67799ae70d4b6167eeda3ec74587d68c7aecbf4e7b1df136681 +md5: f35b3f52d0a2ec4ffe3c89ba135cdb9a +depends: +- _openmp_mutex >=4.5 +constrains: +- libgomp 15.2.0 h8acb6b2_19 +- libgcc-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 622462 +timestamp: 1778268755949 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda +sha256: 1137f93f477f56199ded24117430045a0c02cbe8b10031beac3b9ad2138539d3 +md5: 770cf892e5530f43e63cadc673e85653 +depends: +- libgcc 15.2.0 h8acb6b2_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27738 +timestamp: 1778268759211 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda +sha256: e5ad94be72634233510b33ba792a3339921bd468f0b8bc6961ea05eded251d9b +md5: c7a5b5decf969ead5ecada83654164cf +depends: +- libgfortran5 15.2.0 h1b7bec0_19 +constrains: +- libgfortran-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27728 +timestamp: 1778268784621 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda +sha256: af8e9bdcaa77f133a8ee4c1ef57ef564d9c45aa262abf9f5ef9b50eb99d96407 +md5: 779dbb494de6d3d6477cab52eb34285a +depends: +- libgcc >=15.2.0 +constrains: +- libgfortran 15.2.0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1487244 +timestamp: 1778268767295 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda +sha256: 2370ef0ffcbae5bede3c4bf136add4abc257245eb91f724c99bb4a43116c5a83 +md5: c5e8a379c4a2ec2aea4ba22758c001d9 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 587387 +timestamp: 1778268674393 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda +sha256: e97ec2af5f09f8f6ea8ecd550055c95ae80fae22015fcfadaa94eafe025c9ccc +md5: a85ba48648f6868016f2741fd9170250 +depends: +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 693143 +timestamp: 1775962625956 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-7_h88aeb00_openblas.conda +build_number: 7 +sha256: 20b38a0156200ac65f597bf0a93914c565435f2cc58b1042581854231a99ac35 +md5: 5899cbd743cc74fd655c1ed2af7120f3 +depends: +- libblas 3.11.0 7_haddc8a3_openblas +constrains: +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18685 +timestamp: 1778489809140 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda +sha256: d61962b9cd54c3554361550203c64d5b65b71e3058a285b66e4b04b9769f0a5c +md5: 76298a9e6d71ee6e832a8d0d7373b261 +depends: +- libgcc >=14 +constrains: +- xz 5.8.3.* +license: 0BSD +size: 126102 +timestamp: 1775828008518 +- 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.33-pthreads_h9d3fd7e_0.conda +sha256: b018ecfb05e75a8eea3f21f6b5c5c2a54b5178bdcf19e2e2df2735740214a8c8 +md5: 58a66cd95e9692f08abe89f55a6f3f12 +depends: +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.33,<0.3.34.0a0 +license: BSD-3-Clause +license_family: BSD +size: 5121336 +timestamp: 1776993423004 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda +sha256: 483eaa53da40a6a3e558709d9f7b1ca388735364ae21a1ba58cf942514649c92 +md5: f51503ac45a4888bce71af9027a2ecc9 +depends: +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: zlib-acknowledgement +size: 341202 +timestamp: 1776315188425 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda +sha256: ad03b7d8e4d08001f0df88ee7a56108bb35bae4795a42b9a04cc1abfa822bd07 +md5: 2ec1119217d8f0d086e9a62f3cb0e5ea +depends: +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: blessing +size: 955361 +timestamp: 1777986487553 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda +sha256: 1dadc45e599f510dd5f97141dddcdbb9844d9f1430c1f3a38075cf1c58f87b4e +md5: 543fbc8d71f2a0baf04cf88ce96cb8bb +depends: +- libgcc 15.2.0 h8acb6b2_19 +constrains: +- libstdcxx-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5546559 +timestamp: 1778268777463 +- 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.42.1-h1022ec0_0.conda +sha256: 1628839b062e98b2192857d4da8496ac9ac6b0dbb77aa040c34efc9192c440ee +md5: 0f42f9fedd2a32d798de95a7f65c456f +depends: +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 43453 +timestamp: 1779118526838 +- 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.2.0-pyhd8ed1ab_0.conda +sha256: 0c4c35376fe920714390d46e4b8d31c876d65f18e1655899e0763ec25f2a902f +md5: 6d03368f2b2b0a5fb6839df53b2eb5e0 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 69017 +timestamp: 1778169663339 +- 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.35-pyhdfd78af_1.conda +sha256: e86033aa55a9e915e2d0957e770bdb81e3feb26a227d1adb17f9d6c528da6a71 +md5: cdb20309681ba3ce8f52c110e214d4f3 +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +- pyaml-env +- pydantic >=2.7.1 +- python >=3.9,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard >=4 +license: GPL-3.0-or-later +license_family: GPL3 +size: 4282188 +timestamp: 1779465338806 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +sha256: 70f43d62450927d51673eecd8823e14f5b3cfebdb43cda1d502eba97162bab42 +md5: 6687827c332121727ce383919e1ec8c2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 284323 +timestamp: 1778929680962 +- 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.6-hf8d1292_0.conda +sha256: 369db85c5cd8d99dde364ce70725d76511d9c8199e5b820c740414091bf5bcca +md5: b2a43456aa56fe80c2477a5094899eff +depends: +- libgcc >=14 +license: X11 AND BSD-3-Clause +size: 960036 +timestamp: 1777422174534 +- 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.6-py314he1698a1_0.conda +sha256: 04af718b911f8a3a0095481c7e283aa081a175fe626eccbc2c5644bcb2aba9a1 +md5: 8b173772deea177b45d2a133b509b3f7 +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- python_abi 3.14.* *_cp314 +- libblas >=3.9.0,<4.0a0 +- liblapack >=3.9.0,<4.0a0 +- libcblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8002900 +timestamp: 1779169206742 +- 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.2-h546c87b_0.conda +sha256: 348cb74c1530ac241215d047ef65d134cf797af935c97a68655319362b7e6a01 +md5: 3b129669089e4d6a5c6871dbb4669b99 +depends: +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3706406 +timestamp: 1775589602258 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 +md5: 4c06a92e74452cfa53623a81592e8934 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 91574 +timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py314hac3e5ec_0.conda +sha256: 96b26c2657275ffe84ab510edf0865e21999d791485d12794edd4a71b837beb6 +md5: 87d58d103b47c4a8567b3d7666647684 +depends: +- python +- libgcc >=14 +- python 3.14.* *_cp314 +- openjpeg >=2.5.4,<3.0a0 +- libxcb >=1.17.0,<2.0a0 +- libwebp-base >=1.6.0,<2.0a0 +- zlib-ng >=2.3.3,<2.4.0a0 +- python_abi 3.14.* *_cp314 +- lcms2 >=2.18,<3.0a0 +- tk >=8.6.13,<8.7.0a0 +- libtiff >=4.7.1,<4.8.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +license: HPND +size: 1062080 +timestamp: 1775060067775 +- 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.41.0-pyh58ad624_0.conda +sha256: 70fc56877c4a095ee658d61924d8019768fbae4a48437058d181fc94b0a7c4d8 +md5: 25a883fed9f1f3f21ff317a3e7c92ac4 +depends: +- polars-runtime-32 ==1.41.0 +- 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.41.0 +- polars-runtime-64 ==1.41.0 +- polars-runtime-compat ==1.41.0 +license: MIT +size: 539656 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.41.0-py310h32c7c23_0.conda +noarch: python +sha256: d903b774ec09189e164207328aac157eee82fed8cc5c9ace46aeb5d1c15cb5b3 +md5: 8c08c506ed1ea8ce0ca37af5e918c58d +depends: +- python +- libgcc >=14 +- libstdcxx >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 38704429 +timestamp: 1779630794932 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.41.0-py310hc0e61be_0.conda +noarch: python +sha256: 101696adff43a654146376c62ef9611bf7946b95fa46f604fe247d77eefc6267 +md5: 65b73e4260677ee5162bdbb252e28e06 +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 38651498 +timestamp: 1779630714016 +- 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.13.4-pyhcf101f3_0.conda +sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f +md5: 729843edafc0899b3348bd3f19525b9d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- annotated-types >=0.6.0 +- pydantic-core ==2.46.4 +- python +license: MIT +license_family: MIT +size: 346511 +timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.4-py314h451b6cc_0.conda +sha256: 1a7c6b18e404c13c4d959888ecb48a9ed9de0e41be2872932b83a35278088df0 +md5: 9c3ace6aba6df14b943256095ac1281e +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: 1780773 +timestamp: 1778084251775 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 +md5: 16c18772b340887160c79a6acc022db0 +depends: +- python >=3.10 +license: BSD-2-Clause +license_family: BSD +size: 893031 +timestamp: 1774796815820 +- 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.5-hfd9ac0a_100_cp314.conda +build_number: 100 +sha256: d37bad5447365346166c72950ea8f49689aa49cecc1b0623d00458427627b8df +md5: d956e09feb806f5974675ce92ad81d45 +depends: +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-aarch64 >=2.36.1 +- libexpat >=2.8.0,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.3,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.53.1,<4.0a0 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- openssl >=3.5.6,<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: 37510439 +timestamp: 1779236267040 +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.5-h4df99d1_100.conda +sha256: 41dd7da285d71d519257fa7dacb1cae060d5ebfaa5f92cba5994899d2978e943 +md5: 41954747ba952ec4b01e16c2c9e8d8ff +depends: +- cpython 3.14.5.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236703009 +- 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.5.9-py314h51f160d_0.conda +sha256: 05ef55f09f31eabd0a205f6b065e13fc746675f41924620977692ef0ffe5aad8 +md5: 34ed7bc9febeca70f55b757ca09c354d +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: 409780 +timestamp: 1778374195988 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da +md5: 4a85203c1d80c1059086ae860836ffb9 +depends: +- python >=3.10 +- certifi >=2023.5.7 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.26,<3 +- python +constrains: +- chardet >=3.0.2,<8 +license: Apache-2.0 +license_family: APACHE +size: 68709 +timestamp: 1778851103479 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +sha256: 3d6ba2c0fcdac3196ba2f0615b4104e532525ffa1335b50a2878be5ff488814a +md5: 0242025a3c804966bf71aa04eee82f66 +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: 208577 +timestamp: 1775991661559 +- 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.53.1-he8854b5_0.conda +sha256: 27467e4bfb0681546f149718c33b806fec078185fbaa6a4d17d440bc8f56185c +md5: 46009bdca2315a99e0a3a7d0ba1af3b9 +depends: +- libgcc >=14 +- libsqlite 3.53.1 h022381a_0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 209964 +timestamp: 1777986493350 +- 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.2-pyhcf101f3_0.conda +sha256: 59d7851d32fddb5b510272e6557aa982edeb927d349648dac27f5bf01d18bb26 +md5: 4460f039b7dedf15f7df086446ca75ae +depends: +- typing_extensions >=4.14.0 +- python >=3.10 +- importlib-metadata >=3.6 +- python +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 38297 +timestamp: 1778779291237 +- 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-pyhcf101f3_2.conda +sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a +md5: 53f5409c5cfd6c5a66417d68e3f0a864 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +- python +license: MIT +license_family: MIT +size: 20935 +timestamp: 1777105465795 +- 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.7.0-pyhd8ed1ab_0.conda +sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 +md5: cbb88288f74dbe6ada1c6c7d0a97223e +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: 103560 +timestamp: 1778188657149 +- 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-4.1.0-pyhcf101f3_0.conda +sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 +md5: ba3dcdc8584155c97c648ae9c044b7a3 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24190 +timestamp: 1779159948016 +- 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/environment.yml b/modules/nf-core/multiqc/environment.yml index 812fc4c..7a970e2 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.29 + - bioconda::multiqc=1.35 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 0ac3c36..c4bc715 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,24 +1,21 @@ process MULTIQC { + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.29--pyhdfd78af_0' : - 'biocontainers/multiqc:1.29--pyhdfd78af_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e346f4f6080eadf1253505e6ff09ef004454fc18e8d672006fd7b222cc412e/data' + : 'community.wave.seqera.io/library/multiqc:1.35--c17fb751507e9dfc'}" 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 ce30eb7..27ce18d 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,74 +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: - type: file - description: | - List of reports / files recognised by MultiQC, for example the html and zip output of FastQC - ontologies: [] - - multiqc_config: - type: file - description: Optional config yml for MultiQC - pattern: "*.{yml,yaml}" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML - - extra_multiqc_config: - type: file - description: Second optional config yml for MultiQC. Will override common sections - in multiqc_config. - pattern: "*.{yml,yaml}" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML - - multiqc_logo: - type: file - description: Optional logo file for MultiQC - pattern: "*.{png}" - ontologies: [] - - replace_names: - type: file - description: | - Optional two-column sample renaming file. First column a set of - patterns, second column a set of corresponding replacements. Passed via - MultiQC's `--replace-names` option. - pattern: "*.{tsv}" - ontologies: - - edam: http://edamontology.org/format_3475 # TSV - - 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 # TSV -output: - report: - - "*multiqc_report.html": + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - multiqc_files: type: file - description: MultiQC report file - pattern: "multiqc_report.html" + description: | + List of reports / files recognised by MultiQC, for example the html and zip output of FastQC ontologies: [] - data: - - "*_data": - type: directory - description: MultiQC data dir - pattern: "multiqc_data" - plots: - - "*_plots": + - multiqc_config: + type: file + description: Optional config yml for MultiQC + pattern: "*.{yml,yaml}" + ontologies: + - edam: http://edamontology.org/format_3750 + - multiqc_logo: type: file - description: Plots created by MultiQC - pattern: "*_data" + description: Optional logo file for MultiQC + pattern: "*.{png}" ontologies: [] - versions: - - versions.yml: + - replace_names: + type: file + description: | + Optional two-column sample renaming file. First column a set of + patterns, second column a set of corresponding replacements. Passed via + MultiQC's `--replace-names` option. + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 + - sample_names: type: file - description: File containing software versions - pattern: "versions.yml" + description: | + Optional TSV file with headers, passed to the MultiQC --sample_names + argument. + pattern: "*.{tsv}" ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - edam: http://edamontology.org/format_3475 +output: + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*.html": + type: file + description: MultiQC report file + pattern: ".html" + ontologies: [] + data: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*_data": + type: directory + description: MultiQC data dir + pattern: "multiqc_data" + plots: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*_plots": + type: file + description: Plots created by MultiQC + pattern: "*_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" @@ -90,3 +107,27 @@ maintainers: - "@bunop" - "@drpatelh" - "@jfy133" +containers: + conda: + linux/amd64: + lock_file: modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt + linux/arm64: + lock_file: modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt + docker: + linux/amd64: + name: community.wave.seqera.io/library/multiqc:1.35--c17fb751507e9dfc + build_id: bd-c17fb751507e9dfc_1 + scan_id: sc-3b1b3932f9846892_1 + linux/arm64: + name: community.wave.seqera.io/library/multiqc:1.35--5c84a5000a226ab5 + build_id: bd-5c84a5000a226ab5_1 + scan_id: sc-0d39df41e9737bbd_1 + singularity: + linux/amd64: + name: oras://community.wave.seqera.io/library/multiqc:1.35--c680f2aea25ccec2 + build_id: bd-c680f2aea25ccec2_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e346f4f6080eadf1253505e6ff09ef004454fc18e8d672006fd7b222cc412e/data + linux/arm64: + name: oras://community.wave.seqera.io/library/multiqc:1.35--c0468833d65b2f81 + build_id: bd-c0468833d65b2f81_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/e4/e48aa28aebc881254a499b24c3e1ce77b8df1b85a5432699ed6f72eb17ac7fb5/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 0000000..b30b135 --- /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 33316a7..4cbdb95 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 88e9057..4489921 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,c1fe644a37468f6dae548d98bc72c2c1" - ] + { + "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.35" + ] + ] + } ], + "timestamp": "2026-03-17T16:15:42.577775492", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" - }, - "timestamp": "2025-05-22T11:50:41.182332996" + "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,c1fe644a37468f6dae548d98bc72c2c1" - ] + { + "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.35" + ] + ] + } ], + "timestamp": "2026-03-17T16:21:17.072841555", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" - }, - "timestamp": "2025-05-22T11:51:22.448739369" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, - "multiqc_versions_config": { + "sarscov2 single-end [fastqc] - stub": { "content": [ - [ - "versions.yml:md5,c1fe644a37468f6dae548d98bc72c2c1" - ] + { + "data": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "plots": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "report": [ + [ + { + "id": "FASTQC" + }, + "multiqc_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.35" + ] + ] + } ], + "timestamp": "2026-02-26T15:14:39.789193051", "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" - }, - "timestamp": "2025-05-22T11:51:06.198928424" + "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.35" + ] + ] + } + ], + "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.35" + ] + ] + } + ], + "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 c537a6a..374dfef 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 bea6c0d..0000000 --- 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/rgi/bwt/environment.yml b/modules/nf-core/rgi/bwt/environment.yml new file mode 100644 index 0000000..5e32a82 --- /dev/null +++ b/modules/nf-core/rgi/bwt/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::rgi=6.0.8 + - bioconda::kma=1.6.11 diff --git a/modules/nf-core/rgi/bwt/main.nf b/modules/nf-core/rgi/bwt/main.nf new file mode 100644 index 0000000..c93b601 --- /dev/null +++ b/modules/nf-core/rgi/bwt/main.nf @@ -0,0 +1,82 @@ +process RGI_BWT { + tag "${meta.id}" + label 'process_medium' + + 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/3f/3f452c8e124ee58ab6b26442d15401c57d471cb753f53921570dc484df4e7620/data' +: 'community.wave.seqera.io/library/rgi_kma:e905ecb8305e2609' }" + + input: + tuple val(meta), path(reads, arity: '1..2') + path card + path wildcard + + output: + tuple val(meta), path("*.json"), emit: json + tuple val(meta), path("*.txt"), emit: tsv + tuple val(meta), path("temp/"), emit: tmp + tuple val("${task.process}"), val('rgi'), eval("rgi main --version"), emit: versions_rgi, topic: versions + tuple val("${task.process}"), val('rgi-database'), eval("echo \$DB_VERSION"), emit: versions_db , topic: versions + tuple val("${task.process}"), val('kma'), eval("kma -v"), emit: versions_kma, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + // This customizes the command: rgi load + def args = task.ext.args ?: '' + // This customizes the command: rgi main + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def read_one = reads[0] + def read_two_cmd = reads.size() > 1 ? "--read_two ${reads[1]}" : "" + def load_wildcard = "" + + if (wildcard) { + load_wildcard = """ \\ + --wildcard_annotation ${wildcard}/wildcard_database_v\$DB_VERSION.fasta \\ + --wildcard_annotation_all_models ${wildcard}/wildcard_database_v\$DB_VERSION\\_all.fasta \\ + --wildcard_index ${wildcard}/wildcard/index-for-model-sequences.txt \\ + --amr_kmers ${wildcard}/wildcard/all_amr_61mers.txt \\ + --kmer_database ${wildcard}/wildcard/61_kmer_db.json \\ + --kmer_size 61 + """ + } + + """ + DB_VERSION=\$(ls ${card}/card_database_*_all.fasta | sed "s/${card}\\/card_database_v\\([0-9].*[0-9]\\).*/\\1/") + + rgi \\ + load \\ + ${args} \\ + --local \\ + --card_json ${card}/card.json \\ + --debug \\ + --card_annotation ${card}/card_database_v\$DB_VERSION.fasta \\ + --card_annotation_all_models ${card}/card_database_v\$DB_VERSION\\_all.fasta \\ + ${load_wildcard} + + rgi \\ + bwt \\ + ${args2} \\ + --local \\ + --threads ${task.cpus} \\ + --output_file ${prefix} \\ + --read_one ${read_one} \\ + ${read_two_cmd} + + mkdir temp/ + for FILE in *.xml *.fsa *.{nhr,nin,nsq} *.draft *.potentialGenes *{variant,rrna,protein,predictedGenes,overexpression,homolog}.json; do [[ -e \$FILE ]] && mv \$FILE temp/; done + + """ + + stub: + """ + mkdir -p temp + touch test.json + touch test.txt + + DB_VERSION=stub_version + """ +} diff --git a/modules/nf-core/rgi/bwt/meta.yml b/modules/nf-core/rgi/bwt/meta.yml new file mode 100644 index 0000000..240e417 --- /dev/null +++ b/modules/nf-core/rgi/bwt/meta.yml @@ -0,0 +1,158 @@ +name: rgi_bwt +description: Predict antibiotic resistance from protein or nucleotide data +keywords: + - bacteria + - fasta + - antibiotic resistance +tools: + - rgi: + description: This tool provides a preliminary annotation of your DNA sequence(s) based upon the data available in The Comprehensive Antibiotic Resistance Database (CARD). Hits to genes tagged with Antibiotic Resistance ontology terms will be highlighted. As CARD expands to include more pathogens, genomes, plasmids, and ontology terms this tool will grow increasingly powerful in providing first-pass detection of antibiotic resistance associated genes. See license at CARD website. + homepage: https://card.mcmaster.ca + documentation: https://github.com/arpcard/rgi + tool_dev_url: https://github.com/arpcard/rgi + doi: "10.1093/nar/gkz935" + licence: + - "https://card.mcmaster.ca/about" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: Single-end or paired-end nucleotide sequences in FASTQ or FASTA format + pattern: "*.{fastq,fastq.gz,fq,fq.gz,fasta,fasta.gz,fa,fa.gz,fna,fna.gz,faa,faa.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + - card: + type: directory + description: Directory containing the CARD database. This is expected to be the unarchived but otherwise unaltered download folder (see RGI documentation for download instructions). + pattern: "*/" + - wildcard: + type: directory + description: Directory containing the WildCARD database (optional). This is expected to be the unarchived but otherwise unaltered download folder (see RGI documentation for download instructions). + pattern: "*/" +output: + json: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.json": + type: file + description: JSON formatted file with RGI results + pattern: "*.{json}" + ontologies: + - edam: http://edamontology.org/format_3464 + tsv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.txt": + type: file + description: Tab-delimited file with RGI results + pattern: "*.{txt}" + ontologies: [] + tmp: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - temp/: + type: directory + description: Directory containing various intermediate files + pattern: "temp/" + versions_rgi: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rgi: + type: string + description: The tool name + - rgi main --version: + type: eval + description: The version string returned by the command + versions_db: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rgi-database: + type: string + description: The tool name + - echo \$DB_VERSION: + type: eval + description: The CARD database version string + versions_kma: + - - ${task.process}: + type: string + description: The process the versions were collected from + - kma: + type: string + description: The name of the tool + - kma -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 + - rgi: + type: string + description: The tool name + - rgi main --version: + type: eval + description: The version string returned by the command + - - ${task.process}: + type: string + description: The process the versions were collected from + - rgi-database: + type: string + description: The tool name + - echo \$DB_VERSION: + type: eval + description: The CARD database version string + - - ${task.process}: + type: string + description: The process the versions were collected from + - kma: + type: string + description: The name of the tool + - kma -v: + type: eval + description: The expression to obtain the version of the tool +authors: + - "@vinisalazar" +maintainers: + - "@nickp60" + - "@vinisalazar" +containers: + docker: + linux/amd64: + name: community.wave.seqera.io/library/rgi_kma:e905ecb8305e2609 + build_id: bd-e905ecb8305e2609_1 + scan_id: sc-99ef62328a33452b_1 + linux/arm64: + name: community.wave.seqera.io/library/rgi_kma:fab5219836c1d880 + build_id: bd-fab5219836c1d880_1 + scan_id: sc-721854d12f10e7f7_1 + singularity: + linux/amd64: + name: oras://community.wave.seqera.io/library/rgi_kma:06c9375141c15d16 + build_id: bd-06c9375141c15d16_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/3f/3f452c8e124ee58ab6b26442d15401c57d471cb753f53921570dc484df4e7620/data + linux/arm64: + name: oras://community.wave.seqera.io/library/rgi_kma:a6eaadaaffbeaf85 + build_id: bd-a6eaadaaffbeaf85_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e83b71b5dae10e1d771490c36f49d314718888c3cc8214350eb7f149090f0e/data + conda: + linux/amd64: + lock_file: modules/nf-core/rgi/bwt/.conda-lock/linux_amd64-bd-e905ecb8305e2609_1.txt + linux/arm64: + lock_file: modules/nf-core/rgi/bwt/.conda-lock/linux_arm64-bd-fab5219836c1d880_1.txt diff --git a/modules/nf-core/rgi/bwt/tests/main.nf.test b/modules/nf-core/rgi/bwt/tests/main.nf.test new file mode 100644 index 0000000..a2a2dde --- /dev/null +++ b/modules/nf-core/rgi/bwt/tests/main.nf.test @@ -0,0 +1,105 @@ +nextflow_process { + + name "Test Process RGI_BWT" + script "../main.nf" + process "RGI_BWT" + topics "versions" + tag "modules" + tag "modules_nfcore" + tag "rgi" + tag "rgi/bwt" + tag "rgi/cardannotation" + tag "untar" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = [ + [ ], + file(params.modules_testdata_base_path + 'genomics/prokaryotes/metagenome/rgi/card-data.tar.bz2', checkIfExists: true) + ] + """ + } + } + + run("RGI_CARDANNOTATION") { + script "modules/nf-core/rgi/cardannotation" + process { + """ + input[0] = UNTAR.out.untar.map{ it[1] } + """ + } + } + } + + test("rgi/bwt - minigut - test_fastq_gz") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + '../../mag/test_data/test_minigut_R1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + '../../mag/test_data/test_minigut_R2.fastq.gz', checkIfExists: true), + ] + ] + input[1] = RGI_CARDANNOTATION.out.db + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { + def outDir = file(process.out.tsv[0][1][0]).parentFile + + def mappingFile = outDir.listFiles().find { + it.name.endsWith(".gene_mapping_data.txt") + } + + assert mappingFile != null : "No .gene_mapping_data.txt file found in ${outDir}" + + def sortedLines = mappingFile.readLines().sort() + + assert snapshot([output: sortedLines], + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() + + }, + ) + } + } + + test("rgi/bwt - minigut - test_fastq_gz - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + '../../mag/test_data/test_minigut_R1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + '../../mag/test_data/test_minigut_R2.fastq.gz', checkIfExists: true), + ] + ] + input[1] = RGI_CARDANNOTATION.out.db + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/rgi/bwt/tests/main.nf.test.snap b/modules/nf-core/rgi/bwt/tests/main.nf.test.snap new file mode 100644 index 0000000..46e8eab --- /dev/null +++ b/modules/nf-core/rgi/bwt/tests/main.nf.test.snap @@ -0,0 +1,158 @@ +{ + "rgi/bwt - minigut - test_fastq_gz - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "3": [ + [ + "RGI_BWT", + "rgi", + "6.0.8" + ] + ], + "4": [ + [ + "RGI_BWT", + "rgi-database", + "stub_version" + ] + ], + "5": [ + [ + "RGI_BWT", + "kma", + "KMA-1.6.11" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tmp": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_db": [ + [ + "RGI_BWT", + "rgi-database", + "stub_version" + ] + ], + "versions_kma": [ + [ + "RGI_BWT", + "kma", + "KMA-1.6.11" + ] + ], + "versions_rgi": [ + [ + "RGI_BWT", + "rgi", + "6.0.8" + ] + ] + } + ], + "timestamp": "2026-07-08T14:46:07.17825", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "rgi/bwt - minigut - test_fastq_gz": { + "content": [ + { + "output": [ + "ARO Term\tARO Accession\tReference Model Type\tReference DB\tAlleles with Mapped Reads\tReference Allele(s) Identity to CARD Reference Protein (%)\tResistomes & Variants: Observed in Genome(s)\tResistomes & Variants: Observed in Plasmid(s)\tResistomes & Variants: Observed Pathogen(s)\tCompletely Mapped Reads\tMapped Reads with Flanking Sequence\tAll Mapped Reads\tAverage Percent Coverage\tAverage Length Coverage (bp)\tAverage MAPQ (Completely Mapped Reads)\tNumber of Mapped Baits\tNumber of Mapped Baits with Reads\tAverage Number of reads per Bait\tNumber of reads per Bait Coefficient of Variation (%)\tNumber of reads mapping to baits and mapping to complete gene\tNumber of reads mapping to baits and mapping to complete gene (%)\tMate Pair Linkage (# reads)\tReference Length\tAMR Gene Family\tDrug Class\tResistance Mechanism", + "Escherichia coli acrA\t3004043\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t51.00\t0.00\t51.00\t100.00\t1194.00\t188.71\t0\t0\t0\t0\tN/A\tN/A\t\t1194\tresistance-nodulation-cell division (RND) antibiotic efflux pump\tfluoroquinolone antibiotic; cephalosporin; glycylcycline; penicillin beta-lactam; tetracycline antibiotic; rifamycin antibiotic; phenicol antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "Escherichia coli emrE\t3004039\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t23.00\t0.00\t23.00\t100.00\t333.00\t175.96\t0\t0\t0\t0\tN/A\tN/A\t\t333\tsmall multidrug resistance (SMR) antibiotic efflux pump\tmacrolide antibiotic\tantibiotic efflux", + "LptD\t3005059\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tKlebsiella pneumoniae\t38.00\t0.00\t38.00\t44.57\t1047.00\t131.34\t0\t0\t0\t0\tN/A\tN/A\t\t2349\tATP-binding cassette (ABC) antibiotic efflux pump\tcarbapenem; peptide antibiotic; aminocoumarin antibiotic; rifamycin antibiotic\tantibiotic efflux", + "acrB\t3000216\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t133.00\t0.00\t133.00\t100.00\t3150.00\t191.36\t0\t0\t0\t0\tN/A\tN/A\t\t3150\tresistance-nodulation-cell division (RND) antibiotic efflux pump\tfluoroquinolone antibiotic; cephalosporin; glycylcycline; penicillin beta-lactam; tetracycline antibiotic; rifamycin antibiotic; phenicol antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "kdpE\t3003841\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t45.00\t0.00\t45.00\t100.00\t678.00\t175.80\t0\t0\t0\t0\tN/A\tN/A\t\t678\tkdpDE\taminoglycoside antibiotic\tantibiotic efflux", + "leuO\t3003843\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t55.00\t0.00\t55.00\t100.00\t945.00\t173.55\t0\t0\t0\t0\tN/A\tN/A\t\t945\tmajor facilitator superfamily (MFS) antibiotic efflux pump\tnucleoside antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "rmtH\t3003198\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tKlebsiella pneumoniae\t4.00\t0.00\t4.00\t6.59\t50.00\t79.00\t0\t0\t0\t0\tN/A\tN/A\t\t759\t16S rRNA methyltransferase (G1405)\taminoglycoside antibiotic\tantibiotic target alteration", + "tet(Q)\t3000191\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tBacteroides fragilis\t138.00\t0.00\t138.00\t100.00\t1974.00\t179.62\t0\t0\t0\t0\tN/A\tN/A\t\t1974\ttetracycline-resistant ribosomal protection protein\ttetracycline antibiotic\tantibiotic target protection" + ] + }, + { + "versions_db": [ + [ + "RGI_BWT", + "rgi-database", + "4.0.1" + ] + ], + "versions_kma": [ + [ + "RGI_BWT", + "kma", + "KMA-1.6.11" + ] + ], + "versions_rgi": [ + [ + "RGI_BWT", + "rgi", + "6.0.8" + ] + ] + } + ], + "timestamp": "2026-07-08T16:46:41.850311", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/rgi/cardannotation/environment.yml b/modules/nf-core/rgi/cardannotation/environment.yml new file mode 100644 index 0000000..b6b2d34 --- /dev/null +++ b/modules/nf-core/rgi/cardannotation/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::rgi=6.0.5 diff --git a/modules/nf-core/rgi/cardannotation/main.nf b/modules/nf-core/rgi/cardannotation/main.nf new file mode 100644 index 0000000..776f3c2 --- /dev/null +++ b/modules/nf-core/rgi/cardannotation/main.nf @@ -0,0 +1,61 @@ +process RGI_CARDANNOTATION { + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/rgi:6.0.5--pyh05cac1d_0' + : 'quay.io/biocontainers/rgi:6.0.5--pyh05cac1d_0'}" + + input: + path card + + output: + path ("card_database_processed"), emit: db + env 'RGI_VERSION', emit: tool_version + env 'DB_VERSION', emit: db_version + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + + """ + rgi card_annotation \\ + -i ${card}/card.json \\ + ${args} + + DB_VERSION=\$(ls card_database_*_all.fasta | sed "s/card_database_v\\([0-9].*[0-9]\\).*/\\1/") + + mkdir card_database_processed + mv card*.fasta card_database_processed + cp ${card}/* card_database_processed + + RGI_VERSION=\$(rgi main --version) + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + rgi: \$(echo \$RGI_VERSION) + rgi-database: \$(echo \$DB_VERSION) + END_VERSIONS + """ + + stub: + """ + touch card.fasta + touch card_all.fasta + + mkdir card_database_processed + mv card*.fasta card_database_processed + + RGI_VERSION=\$(rgi main --version) + DB_VERSION=stub_version + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + rgi: \$(echo \$RGI_VERSION) + rgi-database: \$(echo \$DB_VERSION) + END_VERSIONS + """ +} diff --git a/modules/nf-core/rgi/cardannotation/meta.yml b/modules/nf-core/rgi/cardannotation/meta.yml new file mode 100644 index 0000000..6810661 --- /dev/null +++ b/modules/nf-core/rgi/cardannotation/meta.yml @@ -0,0 +1,53 @@ +name: rgi_cardannotation +description: Preprocess the CARD database for RGI to predict antibiotic resistance + from protein or nucleotide data +keywords: + - bacteria + - fasta + - antibiotic resistance +tools: + - rgi: + description: This module preprocesses the downloaded Comprehensive Antibiotic + Resistance Database (CARD) which can then be used as input for RGI. + homepage: https://card.mcmaster.ca + documentation: https://github.com/arpcard/rgi + tool_dev_url: https://github.com/arpcard/rgi + doi: "10.1093/nar/gkz935" + licence: ["https://card.mcmaster.ca/about"] + identifier: "" +input: + - card: + type: directory + description: Directory containing the CARD database + pattern: "*/" +output: + db: + - card_database_processed: + type: directory + description: Directory containing the processed CARD database files + pattern: "*/" + tool_version: + - RGI_VERSION: + type: string + description: The version of the tool in string format (useful for downstream + tools such as hAMRronization) + db_version: + - DB_VERSION: + type: string + description: The version of the used database in string format (useful for downstream + tools such as hAMRronization) + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@rpetit3" + - "@jfy133" + - "@jasmezz" +maintainers: + - "@rpetit3" + - "@jfy133" + - "@jasmezz" diff --git a/modules/nf-core/rgi/cardannotation/tests/main.nf.test b/modules/nf-core/rgi/cardannotation/tests/main.nf.test new file mode 100644 index 0000000..fa51142 --- /dev/null +++ b/modules/nf-core/rgi/cardannotation/tests/main.nf.test @@ -0,0 +1,66 @@ +nextflow_process { + + name "Test Process RGI_CARDANNOTATION" + script "../main.nf" + process "RGI_CARDANNOTATION" + + tag "modules" + tag "modules_nfcore" + tag "rgi" + tag "rgi/cardannotation" + tag "untar" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + file('https://card.mcmaster.ca/latest/data', checkIfExists: true).copyTo('data.tar.gz') + + input[0] = [ + [ ], + file("data.tar.gz") + ] + """ + } + } + } + + test("rgi/cardannotation") { + + when { + process { + """ + input[0] = UNTAR.out.untar.map{ it[1] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("rgi/cardannotation - stub") { + + options "-stub" + + when { + process { + """ + input[0] = UNTAR.out.untar.map{ it[1] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/rgi/cardannotation/tests/main.nf.test.snap b/modules/nf-core/rgi/cardannotation/tests/main.nf.test.snap new file mode 100644 index 0000000..2d1391b --- /dev/null +++ b/modules/nf-core/rgi/cardannotation/tests/main.nf.test.snap @@ -0,0 +1,120 @@ +{ + "rgi/cardannotation - stub": { + "content": [ + { + "0": [ + [ + "card.fasta:md5,d41d8cd98f00b204e9800998ecf8427e", + "card_all.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "6.0.5" + ], + "2": [ + "stub_version" + ], + "3": [ + "versions.yml:md5,c42c7e6566b41df0310a5a4c1fd8f949" + ], + "db": [ + [ + "card.fasta:md5,d41d8cd98f00b204e9800998ecf8427e", + "card_all.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "db_version": [ + "stub_version" + ], + "tool_version": [ + "6.0.5" + ], + "versions": [ + "versions.yml:md5,c42c7e6566b41df0310a5a4c1fd8f949" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-09-03T10:10:40.229702375" + }, + "rgi/cardannotation": { + "content": [ + { + "0": [ + [ + "CARD-Download-README.txt:md5,b57364cc1a5fab0541e13a01fabe5dea", + "PMID.tsv:md5,e3ce79c4b5dcf0a9e3117ed683f96e54", + "aro_categories.tsv:md5,6f9c4b0410b9e2b3cf5867a2a3f1db07", + "aro_categories_index.tsv:md5,d5fbc673c0de6601b07c8016b3909f8e", + "aro_index.tsv:md5,0f183c7869876fa32c8f86aade0df7b5", + "card.json:md5,72156d00155f69e637664bfb5d3b5395", + "card_database_v4.0.1.fasta:md5,5ead0b239c312ebb068a3b5aa9676b2d", + "card_database_v4.0.1_all.fasta:md5,f389ce15fac30e9ab394ca8a49f6451f", + "nucleotide_fasta_protein_homolog_model.fasta:md5,696d1aa4f04bd08fc4bdeea33ab9db43", + "nucleotide_fasta_protein_knockout_model.fasta:md5,d8224ce019ad69a041d83ccf7877b4e0", + "nucleotide_fasta_protein_overexpression_model.fasta:md5,80a1e7957c79d311446e06c6dd49db8e", + "nucleotide_fasta_protein_variant_model.fasta:md5,7450e559045c9d1d8f13c73054c64f4c", + "nucleotide_fasta_rRNA_gene_variant_model.fasta:md5,bd53f46d630f652c9f6b7584c2126e1f", + "protein_fasta_protein_homolog_model.fasta:md5,36ea300133fd7c5a45de2fee4c5050bf", + "protein_fasta_protein_knockout_model.fasta:md5,f16667df70d1a5f910d3ae45f5250c3d", + "protein_fasta_protein_overexpression_model.fasta:md5,723e8762be5c96aed8c379a6499cecee", + "protein_fasta_protein_variant_model.fasta:md5,8c02d8fc84c9a90953f8534355244019", + "shortname_antibiotics.tsv:md5,9a4ba742fd8a3a49c7f50744001a4129", + "shortname_pathogens.tsv:md5,5211712be4f4c3306cbe4052cafae1d7", + "snps.txt:md5,529d4fdb74c8940c0930ec1a7a6d4980" + ] + ], + "1": [ + "6.0.5" + ], + "2": [ + "4.0.1" + ], + "3": [ + "versions.yml:md5,bbd7b05923d280ece1cc3c426aa98ea9" + ], + "db": [ + [ + "CARD-Download-README.txt:md5,b57364cc1a5fab0541e13a01fabe5dea", + "PMID.tsv:md5,e3ce79c4b5dcf0a9e3117ed683f96e54", + "aro_categories.tsv:md5,6f9c4b0410b9e2b3cf5867a2a3f1db07", + "aro_categories_index.tsv:md5,d5fbc673c0de6601b07c8016b3909f8e", + "aro_index.tsv:md5,0f183c7869876fa32c8f86aade0df7b5", + "card.json:md5,72156d00155f69e637664bfb5d3b5395", + "card_database_v4.0.1.fasta:md5,5ead0b239c312ebb068a3b5aa9676b2d", + "card_database_v4.0.1_all.fasta:md5,f389ce15fac30e9ab394ca8a49f6451f", + "nucleotide_fasta_protein_homolog_model.fasta:md5,696d1aa4f04bd08fc4bdeea33ab9db43", + "nucleotide_fasta_protein_knockout_model.fasta:md5,d8224ce019ad69a041d83ccf7877b4e0", + "nucleotide_fasta_protein_overexpression_model.fasta:md5,80a1e7957c79d311446e06c6dd49db8e", + "nucleotide_fasta_protein_variant_model.fasta:md5,7450e559045c9d1d8f13c73054c64f4c", + "nucleotide_fasta_rRNA_gene_variant_model.fasta:md5,bd53f46d630f652c9f6b7584c2126e1f", + "protein_fasta_protein_homolog_model.fasta:md5,36ea300133fd7c5a45de2fee4c5050bf", + "protein_fasta_protein_knockout_model.fasta:md5,f16667df70d1a5f910d3ae45f5250c3d", + "protein_fasta_protein_overexpression_model.fasta:md5,723e8762be5c96aed8c379a6499cecee", + "protein_fasta_protein_variant_model.fasta:md5,8c02d8fc84c9a90953f8534355244019", + "shortname_antibiotics.tsv:md5,9a4ba742fd8a3a49c7f50744001a4129", + "shortname_pathogens.tsv:md5,5211712be4f4c3306cbe4052cafae1d7", + "snps.txt:md5,529d4fdb74c8940c0930ec1a7a6d4980" + ] + ], + "db_version": [ + "4.0.1" + ], + "tool_version": [ + "6.0.5" + ], + "versions": [ + "versions.yml:md5,bbd7b05923d280ece1cc3c426aa98ea9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-09-03T10:10:17.719519729" + } +} \ No newline at end of file diff --git a/modules/nf-core/seqkit/fq2fa/environment.yml b/modules/nf-core/seqkit/fq2fa/environment.yml new file mode 100644 index 0000000..09abb79 --- /dev/null +++ b/modules/nf-core/seqkit/fq2fa/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::seqkit=2.13.0 diff --git a/modules/nf-core/seqkit/fq2fa/main.nf b/modules/nf-core/seqkit/fq2fa/main.nf new file mode 100644 index 0000000..0722455 --- /dev/null +++ b/modules/nf-core/seqkit/fq2fa/main.nf @@ -0,0 +1,40 @@ +process SEQKIT_FQ2FA { + tag "${meta.id}" + 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/4f/4fe272ab9a519cf418160471a485b5ef50ea3f571a8e4555a826f70a4d8243ae/data' + : 'community.wave.seqera.io/library/seqkit:2.13.0--05c0a96bf9fb2751'}" + + input: + tuple val(meta), path(fastq) + + output: + tuple val(meta), path("*.fa.gz"), emit: fasta + tuple val("${task.process}"), val('seqkit'), eval("seqkit version | sed 's/^.*v//'"), emit: versions_seqkit, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + seqkit \\ + fq2fa \\ + ${args} \\ + -j ${task.cpus} \\ + -o ${prefix}.fa.gz \\ + ${fastq} + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo ${args} + + echo "" | gzip > ${prefix}.fa.gz + """ +} diff --git a/modules/nf-core/seqkit/fq2fa/meta.yml b/modules/nf-core/seqkit/fq2fa/meta.yml new file mode 100644 index 0000000..92bf7cd --- /dev/null +++ b/modules/nf-core/seqkit/fq2fa/meta.yml @@ -0,0 +1,63 @@ +name: "seqkit_fq2fa" +description: Convert FASTQ to FASTA format +keywords: + - fastq + - fasta + - convert +tools: + - "seqkit": + description: "Cross-platform and ultrafast toolkit for FASTA/Q file manipulation, + written by Wei Shen." + homepage: "https://github.com/shenwei356/seqkit" + documentation: "https://bioinf.shenwei.me/seqkit/" + doi: "10.1371/journal.pone.0163962" + licence: ["MIT"] + identifier: biotools:seqkit + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - fastq: + type: file + description: Sequence file in fastq format + pattern: "*.{fastq,fq}.gz" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ +output: + fasta: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - "*.fa.gz": + type: file + description: Sequence file in fasta format + pattern: "*.{fasta,fa}.gz" + ontologies: [] + versions_seqkit: + - - ${task.process}: + type: string + description: The name of the process + - seqkit: + type: string + description: The name of the tool + - seqkit version | sed 's/^.*v//': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - seqkit: + type: string + description: The name of the tool + - seqkit version | sed 's/^.*v//': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@d-jch" diff --git a/modules/nf-core/seqkit/fq2fa/tests/main.nf.test b/modules/nf-core/seqkit/fq2fa/tests/main.nf.test new file mode 100644 index 0000000..b20ac23 --- /dev/null +++ b/modules/nf-core/seqkit/fq2fa/tests/main.nf.test @@ -0,0 +1,53 @@ +nextflow_process { + + name "Test Process SEQKIT_FQ2FA" + script "../main.nf" + process "SEQKIT_FQ2FA" + + tag "modules" + tag "modules_nfcore" + tag "seqkit" + tag "seqkit/fq2fa" + + test("sarscov2 - bam") { + 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) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("sarscov2 - bam - stub") { + options '-stub' + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } +} diff --git a/modules/nf-core/seqkit/fq2fa/tests/main.nf.test.snap b/modules/nf-core/seqkit/fq2fa/tests/main.nf.test.snap new file mode 100644 index 0000000..ea4763d --- /dev/null +++ b/modules/nf-core/seqkit/fq2fa/tests/main.nf.test.snap @@ -0,0 +1,56 @@ +{ + "sarscov2 - bam - stub": { + "content": [ + { + "fasta": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fa.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_seqkit": [ + [ + "SEQKIT_FQ2FA", + "seqkit", + "2.13.0" + ] + ] + } + ], + "timestamp": "2026-06-15T10:19:21.836507096", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + }, + "sarscov2 - bam": { + "content": [ + { + "fasta": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fa.gz:md5,f0c5c9110ce19e9ebbc9a6b6baf9e105" + ] + ], + "versions_seqkit": [ + [ + "SEQKIT_FQ2FA", + "seqkit", + "2.13.0" + ] + ] + } + ], + "timestamp": "2026-06-12T17:24:20.019577498", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/untar/environment.yml b/modules/nf-core/untar/environment.yml new file mode 100644 index 0000000..9b926b1 --- /dev/null +++ b/modules/nf-core/untar/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/untar/main.nf b/modules/nf-core/untar/main.nf new file mode 100644 index 0000000..bf2c056 --- /dev/null +++ b/modules/nf-core/untar/main.nf @@ -0,0 +1,75 @@ +process UNTAR { + tag "${archive}" + 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/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 + 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 args2 = task.ext.args2 ?: '' + prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) + + """ + 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 \\ + -xavf \\ + ${args} \\ + ${archive} \\ + ${args2} + else + tar \\ + -C ${prefix} \\ + -xavf \\ + ${args} \\ + ${archive} \\ + ${args2} + fi + + """ + + stub: + 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 + if [[ \$(tar -taf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then + for i in `tar -tf ${archive}`; + do + if [[ \$(echo "\${i}" | grep -E "/\$") == "" ]]; + then + touch \${i} + else + mkdir -p \${i} + fi + done + else + for i in `tar -tf ${archive}`; + do + if [[ \$(echo "\${i}" | grep -E "/\$") == "" ]]; + then + touch ${prefix}/\${i} + else + mkdir -p ${prefix}/\${i} + fi + done + fi + """ +} diff --git a/modules/nf-core/untar/meta.yml b/modules/nf-core/untar/meta.yml new file mode 100644 index 0000000..571d807 --- /dev/null +++ b/modules/nf-core/untar/meta.yml @@ -0,0 +1,73 @@ +name: untar +description: Extract files from tar, tar.gz, tar.bz2, tar.xz archives +keywords: + - untar + - uncompress + - extract +tools: + - untar: + description: | + Extract tar, tar.gz, tar.bz2, tar.xz files. + documentation: https://www.gnu.org/software/tar/manual/ + licence: ["GPL-3.0-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - archive: + type: file + 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: + 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 ] + pattern: "*/" + 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" + - "@matthdsm" + - "@jfy133" +maintainers: + - "@joseespinosa" + - "@drpatelh" + - "@matthdsm" + - "@jfy133" diff --git a/modules/nf-core/untar/tests/main.nf.test b/modules/nf-core/untar/tests/main.nf.test new file mode 100644 index 0000000..fde8db1 --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test @@ -0,0 +1,97 @@ +nextflow_process { + + name "Test Process UNTAR" + script "../main.nf" + process "UNTAR" + tag "modules" + tag "modules_nfcore" + tag "untar" + + test("test_untar") { + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, + ) + } + } + + test("test_untar_onlyfiles") { + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'generic/tar/hello.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, + ) + } + } + + test("test_untar - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.untar, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() }, + ) + } + } + + test("test_untar_onlyfiles - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'generic/tar/hello.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { 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 new file mode 100644 index 0000000..51a414d --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test.snap @@ -0,0 +1,118 @@ +{ + "test_untar_onlyfiles": { + "content": [ + [ + [ + [ + + ], + [ + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" + ] + ] + ], + { + "versions_untar": [ + [ + "UNTAR", + "untar", + "1.34" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-28T17:49:32.000491" + }, + "test_untar_onlyfiles - stub": { + "content": [ + [ + [ + [ + + ], + [ + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + { + "versions_untar": [ + [ + "UNTAR", + "untar", + "1.34" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-28T17:49:58.812479" + }, + "test_untar - stub": { + "content": [ + [ + [ + [ + + ], + [ + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + { + "versions_untar": [ + [ + "UNTAR", + "untar", + "1.34" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-28T17:49:48.119456" + }, + "test_untar": { + "content": [ + [ + [ + [ + + ], + [ + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" + ] + ] + ], + { + "versions_untar": [ + [ + "UNTAR", + "untar", + "1.34" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-28T17:49:17.252494" + } +} \ No newline at end of file diff --git a/nextflow.config b/nextflow.config index db43105..7dd69d8 100644 --- a/nextflow.config +++ b/nextflow.config @@ -1,4 +1,5 @@ /* +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nf-core/funcprofiler Nextflow config file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -9,15 +10,9 @@ // Global default params, used in configs params { - // TODO nf-core: Specify your pipeline's command line flags // Input options input = null - // References - genome = null - igenomes_base = 's3://ngi-igenomes/igenomes/' - igenomes_ignore = false - // MultiQC options multiqc_config = null multiqc_title = null @@ -32,7 +27,6 @@ params { email_on_fail = null plaintext_email = false monochrome_logs = false - hook_url = null help = false help_full = false show_hidden = false @@ -49,8 +43,32 @@ params { // Schema validation default options validate_params = true + // Databases + databases = null + save_untarred_databases = false + + // FASTQ preprocessing + skip_preprocessing_qc = false + + // RGI + run_rgi = false + // Humann + run_humann_v3 = false + run_humann_v4 = false + // fmhfunprofiler + run_fmhfunprofiler = false + // mi-faser + run_mifaser = false + run_diamond = false + // eggnogmapper + run_eggnogmapper = false + } +// 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' @@ -89,9 +107,20 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - docker.runOptions = '-u $(id -u):$(id -g)' + docker.runOptions = '-u $(id -u):$(id -g) --platform linux/x86_64' } - 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 { @@ -148,18 +177,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 - ] - } - } gpu { docker.runOptions = '-u $(id -u):$(id -g) --gpus all' apptainer.runOptions = '--nv' @@ -177,8 +194,7 @@ includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !pa // Load nf-core/funcprofiler custom profiles from different institutions. -// TODO nf-core: Optionally, you can add a pipeline-specific nf-core config at https://github.com/nf-core/configs -// includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/pipeline/funcprofiler.config" : "/dev/null" +includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/pipeline/funcprofiler.config" : "/dev/null" // Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile // Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled @@ -189,9 +205,6 @@ podman.registry = 'quay.io' singularity.registry = 'quay.io' charliecloud.registry = 'quay.io' -// Load igenomes.config if required -includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config' - // Export these variables to prevent local Python/R libraries from conflicting with those in the container // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. @@ -236,61 +249,56 @@ dag { manifest { name = 'nf-core/funcprofiler' contributors = [ - // TODO nf-core: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0 [ name: 'Nick Waters', - affiliation: '', + affiliation: 'MSKCC', email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + github: 'nickp60', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') orcid: '' ], + [ + name: 'Vini Salazar', + affiliation: 'University of Melbourne', + email: '', + github: 'vinisalazar', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '' + ], + [ + name: 'Mirae B', + affiliation: 'MSKCC', + email: '', + github: 'miraep8', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '' + ], + [ + name: 'Yixuan Yang', + affiliation: 'NC State', + email: '', + github: 'Yixuan39', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '' + ] ] homePage = 'https://github.com/nf-core/funcprofiler' description = """Read-based functional profiling of microbiome sequencing data""" mainScript = 'main.nf' defaultBranch = 'main' - nextflowVersion = '!>=24.10.5' - version = '1.0.0dev' + nextflowVersion = '!>=25.10.4' + version = '1.0.0' doi = '' } // Nextflow plugins plugins { - id 'nf-schema@2.4.2' // 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/funcprofiler -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/funcprofiler ${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/funcprofiler/blob/main/CITATIONS.md -""" - } - summary { - beforeText = validation.help.beforeText - afterText = validation.help.afterText - } } - // Load modules.config for DSL2 module specific options includeConfig 'conf/modules.config' diff --git a/nextflow_schema.json b/nextflow_schema.json index 5c45ecf..e48421b 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,7 +10,7 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": ["input", "outdir"], + "required": ["input", "databases", "outdir"], "properties": { "input": { "type": "string", @@ -20,9 +20,26 @@ "mimetype": "text/csv", "pattern": "^\\S+\\.csv$", "description": "Path to comma-separated file containing information about the samples in the experiment.", - "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/funcprofiler/usage#samplesheet-input).", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 6 columns ( `sample`, `run_accession`, `instrument_platform`, `fastq_1`, `fastq_2`, `fasta`), and a header row. We utilize the same input style as nf-core/taxprofiler, with 2 main difference: long-read platforms are not supported, nor is `fasta` input. Otherwise, see [usage docs](https://nf-co.re/taxprofiler/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" }, + "databases": { + "type": "string", + "mimetype": "text/csv", + "format": "file-path", + "exists": true, + "schema": "assets/schema_database.json", + "pattern": "^\\S+\\.csv$", + "fa_icon": "fas fa-database", + "description": "Path to comma-separated file containing information about databases and profiling parameters for each taxonomic profiler", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 5 columns (`tool`, `db_name`, `db_entity`, `db_params`, `db_path`), and a header row. See [usage docs](https://nf-co.re/funcprofiler/dev/usage#full-database-sheet).\n\nProfilers will only be executed if a corresponding database are supplied. \n\n As with taxprofiler, we recommend storing this database sheet somewhere centrally and accessible by others members of your lab/institutions, as this file will likely be regularly reused." + }, + "save_untarred_databases": { + "type": "boolean", + "fa_icon": "fas fa-database", + "description": "Specify to save decompressed user-supplied TAR archives of databases", + "help_text": "If input databases are supplied as gzipped TAR archives, in some cases you may want to move and re-use these for future runs. Specifying this parameter will save these to `--outdir results/` under a directory called `untar`." + }, "outdir": { "type": "string", "format": "directory-path", @@ -43,42 +60,57 @@ } } }, - "reference_genome_options": { - "title": "Reference genome options", + "preprocessing_qc_options": { + "title": "Preprocessing QC options", "type": "object", - "fa_icon": "fas fa-dna", - "description": "Reference genome related files and options required for the workflow.", + "description": "", + "default": "", "properties": { - "genome": { - "type": "string", - "description": "Name of iGenomes reference.", - "fa_icon": "fas fa-book", - "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details." + "skip_preprocessing_qc": { + "type": "boolean", + "description": "Skip quality control step when preprocessing", + "help_text": "When True, this won't perform any of the quality control steps in preprocessing, such as discarding low-quality reads." + } + } + }, + "profiling_options": { + "title": "Profiling options", + "type": "object", + "description": "", + "default": "", + "properties": { + "run_fmhfunprofiler": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with fmhfunprofiler; Requires database to be present CSV file passed to --databases" }, - "fasta": { - "type": "string", - "format": "file-path", - "exists": true, - "mimetype": "text/plain", - "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", - "description": "Path to FASTA genome file.", - "help_text": "This parameter is *mandatory* if `--genome` is not specified. If you don't have a BWA index available this will be generated for you automatically. Combine with `--save_reference` to save BWA index for future runs.", - "fa_icon": "far fa-file-code" + "run_humann_v3": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with HUMAnN3. Requires `humann_v3`-tagged database to be present CSV file passed to --databases" }, - "igenomes_ignore": { + "run_humann_v4": { "type": "boolean", - "description": "Do not load the iGenomes reference config.", - "fa_icon": "fas fa-ban", - "hidden": true, - "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`." + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with HUMAnN4. Requires `humann_v4`-tagged database to be present CSV file passed to --databases" }, - "igenomes_base": { - "type": "string", - "format": "directory-path", - "description": "The base path to the igenomes reference files", - "fa_icon": "fas fa-ban", - "hidden": true, - "default": "s3://ngi-igenomes/igenomes/" + "run_diamond": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on translated alignment with DIAMOND blastx. Requires a .dmnd database to be present in the CSV file passed to --databases" + }, + "run_rgi": { + "type": "boolean", + "description": "Turn on profiling with RGI. Requires database to be present CSV file passed to --databases" + }, + "run_mifaser": { + "type": "boolean", + "description": "Turn on profiling with mi-faser. Requires database to be present CSV file passed to --databases" + }, + "run_eggnogmapper": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on functional annotation with EggNOG-mapper. Requires `eggnogmapper`-tagged database entries in the CSV file passed to --databases" } } }, @@ -180,13 +212,6 @@ "fa_icon": "fas fa-palette", "hidden": true }, - "hook_url": { - "type": "string", - "description": "Incoming hook URL for messaging service", - "fa_icon": "fas fa-people-group", - "help_text": "Incoming hook URL for messaging service. Currently, MS Teams and Slack are supported.", - "hidden": true - }, "multiqc_config": { "type": "string", "format": "file-path", @@ -224,6 +249,18 @@ "fa_icon": "far calendar", "description": "Suffix to add to the trace report filename. Default is the date and time in the format yyyy-MM-dd_HH-mm-ss.", "hidden": true + }, + "help": { + "type": ["boolean", "string"], + "description": "Display the help message." + }, + "help_full": { + "type": "boolean", + "description": "Display the full detailed help message." + }, + "show_hidden": { + "type": "boolean", + "description": "Display hidden parameters in the help message (only works when --help or --help_full are provided)." } } } @@ -233,7 +270,10 @@ "$ref": "#/$defs/input_output_options" }, { - "$ref": "#/$defs/reference_genome_options" + "$ref": "#/$defs/preprocessing_qc_options" + }, + { + "$ref": "#/$defs/profiling_options" }, { "$ref": "#/$defs/institutional_config_options" diff --git a/nf-test.config b/nf-test.config index 3a1fff5..d712a84 100644 --- a/nf-test.config +++ b/nf-test.config @@ -1,20 +1,23 @@ config { // location for all nf-test tests - testsDir "." + testsDir = "." // nf-test directory including temporary files for each test - workDir System.getenv("NFT_WORKDIR") ?: ".nf-test" + workDir = System.getenv("NFT_WORKDIR") ?: ".nf-test" // location of an optional nextflow.config file specific for executing tests - configFile "tests/nextflow.config" + configFile = "tests/nextflow.config" // ignore tests coming from the nf-core/modules repo - ignore 'modules/nf-core/**/tests/*', 'subworkflows/nf-core/**/tests/*' + ignore = [ + 'modules/nf-core/**/tests/*', + 'subworkflows/nf-core/**/tests/*', + ] // run all test with defined profile(s) from the main nextflow.config - profile "test" + profile = "test" - // list of filenames or patterns that should be trigger a full test run + // list of filenames or patterns that should be trigger a full test run triggers 'nextflow.config', 'nf-test.config', 'conf/test.config', 'tests/nextflow.config', 'tests/.nftignore' // load the necessary plugins diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 41333a3..cf527df 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -1,6 +1,6 @@ { "@context": [ - "https://w3id.org/ro/crate/1.1/context", + "https://w3id.org/ro/crate/1.2/context", { "GithubService": "https://w3id.org/ro/terms/test#GithubService", "JenkinsService": "https://w3id.org/ro/terms/test#JenkinsService", @@ -21,9 +21,9 @@ { "@id": "./", "@type": "Dataset", - "creativeWorkStatus": "InProgress", - "datePublished": "2025-08-13T15:15:55+00:00", - "description": "

\n \n \n \"nf-core/funcprofiler\"\n \n

\n\n[![GitHub Actions CI Status](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/funcprofiler/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/funcprofiler/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/funcprofiler/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/funcprofiler)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23funcprofiler-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/funcprofiler)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/funcprofiler** is a bioinformatics pipeline that ...\n\n\n\n\n1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\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\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/funcprofiler \\\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/funcprofiler/usage) and the [parameter documentation](https://nf-co.re/funcprofiler/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/funcprofiler/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/funcprofiler/output).\n\n## Credits\n\nnf-core/funcprofiler was originally written by Nick Waters.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\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 `#funcprofiler` channel](https://nfcore.slack.com/channels/funcprofiler) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\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", + "creativeWorkStatus": "Stable", + "datePublished": "2026-07-30T19:50:02+00:00", + "description": "

\n \n \n \"nf-core/funcprofiler\"\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/funcprofiler)\n[![GitHub Actions CI Status](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/funcprofiler/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/funcprofiler/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/funcprofiler/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/funcprofiler/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.10.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.1.0-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.1.0)\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/funcprofiler)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23funcprofiler-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/funcprofiler)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/funcprofiler** is a bioinformatics pipeline for read-based functional profiling of microbiome sequencing data. It accepts short-read (Illumina) and long-read (Oxford Nanopore) FASTQ files and runs one or more functional profilers against user-supplied databases, producing gene family abundances, pathway abundances, pathway coverages, and antimicrobial resistance profiles.\n\n### Pipeline Summary\n\n![](./assets/pipeline_light.svg)\n\nSupported profilers and current status:\n\n1. [**HUMANn v3**](https://huttenhower.sph.harvard.edu/humann/) \u2014 functional profiling via MetaPhlAn + HUMANn 3 (`--run_humann_v3`)\n2. [**HUMANn v4**](https://docs.google.com/document/d/1rCx5JkuO7wCKWrL8_-UJx_FkopJAfcDFtZktgPspak0/edit?tab=t.0#heading=h.i5hn0zprhwld) \u2014 functional profiling via MetaPhlAn + HUMANn 4 (`--run_humann_v4`)\n3. [**FMH FunProfiler**](https://github.com/KoslickiLab/fmh-funprofiler) \u2014 sketch-based functional profiling (`--run_fmhfunprofiler`)\n4. [**RGI**](https://github.com/arpcard/rgi) \u2014 antimicrobial resistance gene identification (`--run_rgi`, available)\n5. [**mifaser**](https://bromberglab.org/project/mifaser/) \u2014 functional profiling via mifaser (`--run_mifaser`, available)\n6. [**DIAMOND**](https://github.com/bbuchfink/diamond) \u2014 alignment with DIAMOND blastx (`--run_diamond`, work in progress / beta)\n7. [**eggNOG-mapper**](https://github.com/eggnogdb/eggnog-mapper) \u2014 functional annotation, orthology assignments and domain prediction (`--run_eggnogmapper`, work in progress / beta)\n\n> [!WARNING]\n> DIAMOND and eggNOG-mapper support is currently in beta and should be treated as work in progress. These modules are still being validated in the full pipeline, including database handling, output behavior, and downstream reporting. Use them with caution, expect potential issues, and independently review results before using them for production analyses or interpretation.\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:\n\n`samplesheet.csv`:\n\n```csv\nsample,run_accession,instrument_platform,fastq_1,fastq_2,fasta\nSAMPLE1,RUN1,ILLUMINA,/path/to/sample1_R1.fastq.gz,/path/to/sample1_R2.fastq.gz,\nSAMPLE2,RUN1,OXFORD_NANOPORE,/path/to/sample2.fastq.gz,,\n```\n\nEach row represents a sequencing run. Multiple rows with the same `sample` and different `run_accession` values will be merged before profiling.\n\nThen prepare a databases sheet \u2014 see [docs/usage.md](docs/usage.md) for the full format. Here is an abbreviated example for running HUMANn (which requires 4 databases):\n\n`databases.csv`\n\n```csv\ntool,db_name,db_entity,db_params,db_type,db_path\nhumann_v3,uniref90_v3,humann_metaphlan,,,/data/databases/metaphlan_db\nhumann_v3,uniref90_v3,humann_nucleotide,,,/data/databases/chocophlan\nhumann_v3,uniref90_v3,humann_protein,,,/data/databases/uniref90_diamond\nhumann_v3,uniref90_v3,humann_utility,,,/data/databases/utility_mapping\n```\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/funcprofiler \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \\\n --databases databases.csv \\\n --run_humann_v3\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/funcprofiler/usage) and the [parameter documentation](https://nf-co.re/funcprofiler/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/funcprofiler/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/funcprofiler/output).\n\n## Credits\n\nnf-core/funcprofiler was written by Nick Waters, Vini Salazar, Yixuan Yang, Mirae Baichoo.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- Matthias H\u00f6rtenhuber\n- James Fellows Yates\n- Jonas Scheid\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 `#funcprofiler` channel](https://nfcore.slack.com/channels/funcprofiler) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" @@ -43,6 +43,9 @@ { "@id": "modules/" }, + { + "@id": "modules/local/" + }, { "@id": "modules/nf-core/" }, @@ -99,7 +102,7 @@ }, "mentions": [ { - "@id": "#43d93482-10b4-4a4a-9aae-56cf094b0489" + "@id": "#bccf036e-0172-463f-b1a5-fdc12f3630b5" } ], "name": "nf-core/funcprofiler" @@ -112,7 +115,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" @@ -126,13 +129,22 @@ "SoftwareSourceCode", "ComputationalWorkflow" ], - "creator": [ + "author": [ + { + "@id": "#02abcbb1-966b-4c2b-9848-c2ef3c65726e" + }, { - "@id": "#nickp60@users.noreply.github.com" + "@id": "#865c248f-67f4-474a-9f1e-8f4ff51cffab" + }, + { + "@id": "#f74f489b-c4bb-4bb1-8e43-fdde330df31c" + }, + { + "@id": "#3f3b690c-5064-46b9-82c3-50d9a35a4502" } ], "dateCreated": "", - "dateModified": "2025-08-13T11:15:55Z", + "dateModified": "2026-07-30T15:50:02Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -143,7 +155,16 @@ ], "maintainer": [ { - "@id": "#nickp60@users.noreply.github.com" + "@id": "#02abcbb1-966b-4c2b-9848-c2ef3c65726e" + }, + { + "@id": "#865c248f-67f4-474a-9f1e-8f4ff51cffab" + }, + { + "@id": "#f74f489b-c4bb-4bb1-8e43-fdde330df31c" + }, + { + "@id": "#3f3b690c-5064-46b9-82c3-50d9a35a4502" } ], "name": [ @@ -157,10 +178,10 @@ }, "url": [ "https://github.com/nf-core/funcprofiler", - "https://nf-co.re/funcprofiler/dev/" + "https://nf-co.re/funcprofiler/1.0.0/" ], "version": [ - "1.0.0dev" + "1.0.0" ] }, { @@ -173,14 +194,14 @@ "url": { "@id": "https://www.nextflow.io/" }, - "version": "!>=24.10.5" + "version": "!>=25.10.4" }, { - "@id": "#43d93482-10b4-4a4a-9aae-56cf094b0489", + "@id": "#bccf036e-0172-463f-b1a5-fdc12f3630b5", "@type": "TestSuite", "instance": [ { - "@id": "#d1cf13a7-6e4d-4a5b-9196-57c7109be07f" + "@id": "#15f3c233-a5e2-45c5-9c3b-ac22528d9fea" } ], "mainEntity": { @@ -189,7 +210,7 @@ "name": "Test suite for nf-core/funcprofiler" }, { - "@id": "#d1cf13a7-6e4d-4a5b-9196-57c7109be07f", + "@id": "#15f3c233-a5e2-45c5-9c3b-ac22528d9fea", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/funcprofiler", "resource": "repos/nf-core/funcprofiler/actions/workflows/nf-test.yml", @@ -231,6 +252,11 @@ "@type": "Dataset", "description": "Modules used by the pipeline" }, + { + "@id": "modules/local/", + "@type": "Dataset", + "description": "Pipeline-specific modules" + }, { "@id": "modules/nf-core/", "@type": "Dataset", @@ -318,10 +344,36 @@ "url": "https://nf-co.re/" }, { - "@id": "#nickp60@users.noreply.github.com", + "@id": "#02abcbb1-966b-4c2b-9848-c2ef3c65726e", + "@type": "Person", + "affiliation": "MSKCC", + "email": "nickp60@gmail.com", + "name": "Nick Waters", + "url": "https://github.com/nickp60" + }, + { + "@id": "#865c248f-67f4-474a-9f1e-8f4ff51cffab", + "@type": "Person", + "affiliation": "University of Melbourne", + "email": "17276653+vinisalazar@users.noreply.github.com", + "name": "Vini Salazar", + "url": "https://github.com/vinisalazar" + }, + { + "@id": "#f74f489b-c4bb-4bb1-8e43-fdde330df31c", + "@type": "Person", + "affiliation": "MSKCC", + "email": "miraep8@gmail.com", + "name": "Mirae B", + "url": "https://github.com/miraep8" + }, + { + "@id": "#3f3b690c-5064-46b9-82c3-50d9a35a4502", "@type": "Person", - "email": "nickp60@users.noreply.github.com", - "name": "Nick Waters" + "affiliation": "NC State", + "email": "yyang55@ncsu.edu", + "name": "Yixuan Yang", + "url": "https://github.com/Yixuan39" } ] } \ No newline at end of file diff --git a/subworkflows/local/dataprep/main.nf b/subworkflows/local/dataprep/main.nf new file mode 100644 index 0000000..971ac2a --- /dev/null +++ b/subworkflows/local/dataprep/main.nf @@ -0,0 +1,95 @@ +include { CAT_FASTQ as MERGE_RUNS } from '../../../modules/nf-core/cat/fastq/main' +include { CAT_FASTQ } from '../../../modules/nf-core/cat/fastq/main' + + +workflow DATAPREP { + take: + samplesheet // [meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta] + + main: + + // Step 1: Validate inputs and set meta fields + ch_validated = samplesheet.map { meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta -> + + // Error checks + if (instrument_platform == "OXFORD_NANOPORE" | instrument_platform == "PACBIO_SMRT") { + error("ERROR: Long read data is not supported!") + } + if (fasta) { + error("ERROR: inputs must be in fastq format, not fasta!") + } + if (!fastq_1) { + error("ERROR: Please check input samplesheet: entry `fastq_1` doesn't exist!") + } + + // Set single_end based on presence of fastq_2 + meta.single_end = !fastq_2 + + // Store additional metadata + meta.run_accession = run_accession + meta.instrument_platform = instrument_platform + + // Return tuple of meta and reads + def reads = fastq_2 ? [fastq_1, fastq_2] : [fastq_1] + return [meta, reads] + } + + // Step 2: Group by meta.id and merge runs if needed + ch_grouped = ch_validated + .map { meta, reads -> + // Create grouping key and new meta without run_accession for grouping + def group_key = meta.id + [group_key, meta, reads] + } + .groupTuple(by: 0) + .map { group_key, meta_list, reads_list -> + // Take the first meta as template (they should all have same id) + def meta = meta_list[0] + // Remove run_accession since we're merging runs + meta = meta - meta.subMap('run_accession') + + // Flatten all reads into a single list + def all_reads = reads_list.flatten() + + [meta, all_reads] + } + .branch { meta, reads -> + merge: (meta.single_end && reads.size() > 1) || (!meta.single_end && reads.size() > 2) + return [meta, reads] + skip: true + return [meta, reads] + } + + // Merge reads for samples that need it + ch_merged = MERGE_RUNS(ch_grouped.merge).reads + + // Combine merged and non-merged samples + ch_reads = ch_merged.mix(ch_grouped.skip) + + // Step 3: Create concatenated single-file version for tools that need it + ch_for_concat = ch_reads + .map { meta, reads -> + // Mark as single_end for CAT_FASTQ to concatenate R1 and R2 into one file + def meta_concat = meta.clone() + meta_concat.single_end = true + [meta_concat, reads] + } + .branch { meta, reads -> + concat: reads.size() > 1 + return [meta, reads] + skip: true + return [meta, reads] + } + + // Concatenate all reads into single file per sample + ch_concatenated = CAT_FASTQ(ch_for_concat.concat).reads + .mix(ch_for_concat.skip) + .map { meta, reads -> + // Ensure reads is always a list + [meta, [reads].flatten()] + } + + emit: + reads = ch_reads // Paired-end reads (R1, R2) or single-end + reads_concat = ch_concatenated // All reads concatenated into single file +} diff --git a/subworkflows/local/dataprep/meta.yml b/subworkflows/local/dataprep/meta.yml new file mode 100644 index 0000000..915faa4 --- /dev/null +++ b/subworkflows/local/dataprep/meta.yml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "dataprep" +description: | + Validate the input samplesheet and prepare read channels for profiling. Sets + `single_end`, `run_accession` and `instrument_platform` on the meta map, merges + multiple runs belonging to the same sample, and produces an additional channel + in which read pairs are concatenated into a single file for tools that cannot + take paired input. +keywords: + - samplesheet + - fastq + - merging + - concatenation + - metagenome +components: + - cat/fastq +input: + - samplesheet: + type: file + description: | + Channel of validated samplesheet rows. Long-read (`OXFORD_NANOPORE`) + platforms and FASTA input are rejected, and `fastq_1` is required. + Structure: [ val(meta), val(run_accession), val(instrument_platform), path(fastq_1), path(fastq_2), path(fasta) ] + pattern: "*.{fq,fastq}{,.gz}" +output: + - reads: + type: file + description: | + Channel of reads per sample, with runs merged where a sample has more + than one. Paired-end samples carry two files, single-end samples one. + Structure: [ val(meta), [ path(reads) ] ] + pattern: "*.{fq,fastq}{,.gz}" + - reads_concat: + type: file + description: | + Channel of the same reads concatenated into a single file per sample, + with `single_end` forced to `true`, for tools that accept only one FASTQ. + Structure: [ val(meta), [ path(reads) ] ] + pattern: "*.{fq,fastq}{,.gz}" +authors: + - "@nickp60" +maintainers: + - "@nickp60" diff --git a/subworkflows/local/dataprep/tests/main.nf.test b/subworkflows/local/dataprep/tests/main.nf.test new file mode 100644 index 0000000..f597916 --- /dev/null +++ b/subworkflows/local/dataprep/tests/main.nf.test @@ -0,0 +1,68 @@ +nextflow_workflow { + + name "Test Subworkflow DATAPREP" + script "../main.nf" + workflow "DATAPREP" + + tag "subworkflows" + tag "subworkflows_" + tag "subworkflows/dataprep" + tag "cat_fastq" + + + test("paired-end runmerged") { + + when { + // params { + // pipelines_testdata_base_path = '/Users/Watersn/GitHub/nf-core-funcprofiler' + // } + workflow { + """ + input[0] = Channel.fromList( + [ + [["id": "2612"],"ERR5766176",'ILLUMINA', + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_2.fastq.gz'),''], + [["id": "2612"], "ERR5766176_B","ILLUMINA", + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_B_1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_B_2.fastq.gz'),''], + + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + then { + assert workflow.success + def items = workflow.out.reads_concat.toList() + assert items.size() == 2, "run merging appears to have failed" + + items.each { meta, reads -> + // Check exactly 1 file per sample for concat channel + def fileList = reads instanceof List ? reads : [reads] + assert fileList.size() == 1, + "Expected exactly 1 fastq file for ${meta.id}, got ${fileList}" + + } + + def pe_items = workflow.out.reads.toList() + + pe_items.each { meta, reads -> + // Check exactly 1 file per sample for concat channel + def fileList = reads instanceof List ? reads : [reads] + assert fileList.size() == 2, + "Expected exactly 2 fastq files for ${meta.id}, got ${fileList}" + + } + + assertAll( + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/dataprep/tests/main.nf.test.snap b/subworkflows/local/dataprep/tests/main.nf.test.snap new file mode 100644 index 0000000..8b9fa61 --- /dev/null +++ b/subworkflows/local/dataprep/tests/main.nf.test.snap @@ -0,0 +1,105 @@ +{ + "paired-end runmerged": { + "content": [ + { + "0": [ + [ + { + "id": "2612", + "single_end": false, + "instrument_platform": "ILLUMINA" + }, + [ + "2612_1.merged.fastq.gz:md5,e38f6e7ad98fc7b848b4967bde945d13", + "2612_2.merged.fastq.gz:md5,5f40e29533a8f88521954301b836dbd8" + ] + ], + [ + { + "id": "minigut", + "single_end": false, + "instrument_platform": "ILLUMINA" + }, + [ + "/nf-core/test-datasets/mag/test_data/test_minigut_R1.fastq.gz", + "/nf-core/test-datasets/mag/test_data/test_minigut_R2.fastq.gz" + ] + ] + ], + "1": [ + [ + { + "id": "2612", + "single_end": true, + "instrument_platform": "ILLUMINA" + }, + [ + "2612.merged.fastq.gz:md5,270bf4c4d9707c6afc970fe5622cc673" + ] + ], + [ + { + "id": "minigut", + "single_end": true, + "instrument_platform": "ILLUMINA" + }, + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129" + ] + ] + ], + "reads": [ + [ + { + "id": "2612", + "single_end": false, + "instrument_platform": "ILLUMINA" + }, + [ + "2612_1.merged.fastq.gz:md5,e38f6e7ad98fc7b848b4967bde945d13", + "2612_2.merged.fastq.gz:md5,5f40e29533a8f88521954301b836dbd8" + ] + ], + [ + { + "id": "minigut", + "single_end": false, + "instrument_platform": "ILLUMINA" + }, + [ + "/nf-core/test-datasets/mag/test_data/test_minigut_R1.fastq.gz", + "/nf-core/test-datasets/mag/test_data/test_minigut_R2.fastq.gz" + ] + ] + ], + "reads_concat": [ + [ + { + "id": "2612", + "single_end": true, + "instrument_platform": "ILLUMINA" + }, + [ + "2612.merged.fastq.gz:md5,270bf4c4d9707c6afc970fe5622cc673" + ] + ], + [ + { + "id": "minigut", + "single_end": true, + "instrument_platform": "ILLUMINA" + }, + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129" + ] + ] + ] + } + ], + "timestamp": "2026-04-18T00:05:15.049339", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/dbprep/main.nf b/subworkflows/local/dbprep/main.nf new file mode 100644 index 0000000..4344403 --- /dev/null +++ b/subworkflows/local/dbprep/main.nf @@ -0,0 +1,60 @@ +include { UNTAR } from '../../../modules/nf-core/untar/main' + +workflow DBPREP { + take: + databases + + main: + + // Validate and decompress databases + ch_dbs_for_untar = databases.branch { db_meta, db_path -> + untar: db_path.name.endsWith(".tar.gz") | db_path.name.endsWith(".tar.bz2") | db_path.name.endsWith(".tar") | db_path.name.endsWith(".tar.xz") + skip: true + } + // Filter the channel to untar only those databases for tools that are selected to be run by the user. + // Also, to ensure only untar once per file, group together all databases of one file + ch_inputdb_untar = ch_dbs_for_untar.untar + .filter { db_meta, db_path -> + params["run_${db_meta.tool}"] + } + .groupTuple(by: 1) + .map { meta, dbfile -> + def new_meta = ['id': dbfile.baseName] + ['meta': meta] + [new_meta, dbfile] + } + + // Untar the databases + UNTAR(ch_inputdb_untar) + // Spread out the untarred and shared databases + ch_outputdb_from_untar = UNTAR.out.untar + .map { meta, db -> + [meta.meta, db] + } + .transpose(by: 0) + + ch_semifinal_dbs = ch_dbs_for_untar.skip + .mix(ch_outputdb_from_untar) + .map { db_meta, db -> + def corrected_db_params = db_meta.db_params ? [db_params: db_meta.db_params] : [db_params: '-'] + [db_meta + corrected_db_params, db] + } + + ch_grouped_dbs = ch_semifinal_dbs + .map { meta, path -> + def entity = meta.db_entity ?: 'main' + [[tool: meta.tool, db_name: meta.db_name, db_params: meta.db_params], [entity, path]] + } + .groupTuple() + .map { groupKey, groupTuples -> + def grouped_dbs = groupTuples.collect { tuple -> + [ + db_entity: tuple[0], + db_path: tuple[1], + ] + } + return [groupKey, grouped_dbs] + } + + emit: + dbs = ch_grouped_dbs +} diff --git a/subworkflows/local/dbprep/meta.yml b/subworkflows/local/dbprep/meta.yml new file mode 100644 index 0000000..89e987e --- /dev/null +++ b/subworkflows/local/dbprep/meta.yml @@ -0,0 +1,36 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "dbprep" +description: | + Prepare the databases declared in the database sheet. Archives are decompressed + once per file and only for tools the user has enabled, then all entities + belonging to the same database are grouped so that each profiler receives a + single entry per database name and parameter combination. +keywords: + - database + - untar + - decompression + - metagenome +components: + - untar +input: + - databases: + type: file + description: | + Channel of database entries from the database sheet. `meta.tool` selects + which profiler the database belongs to, `meta.db_entity` names the part + of a multi-file database, and `meta.db_params` carries tool-specific + arguments. Entries ending in `.tar`, `.tar.gz`, `.tar.bz2` or `.tar.xz` + are decompressed, the rest are passed through untouched. + Structure: [ val(meta), path(database) ] + pattern: "*.{tar,tar.gz,tar.bz2,tar.xz}" +output: + - dbs: + type: file + description: | + Channel of databases grouped by tool, name and parameters. The second + element is a list of maps, each holding the entity name and its path. + Structure: [ val(meta), [ [ db_entity: val(entity), db_path: path(db) ] ] ] +authors: + - "@nickp60" +maintainers: + - "@nickp60" diff --git a/subworkflows/local/dbprep/tests/main.nf.test b/subworkflows/local/dbprep/tests/main.nf.test new file mode 100644 index 0000000..76adb84 --- /dev/null +++ b/subworkflows/local/dbprep/tests/main.nf.test @@ -0,0 +1,59 @@ +nextflow_workflow { + + name "Test Subworkflow DBPREP" + script "../main.nf" + workflow "DBPREP" + + tag "subworkflows" + tag "subworkflows_" + tag "subworkflows/dbprep" + test("leave untarred alone") { + + when { + workflow { + """ + // Test that non-taredfiles don't get mutilated + input[0] = Channel.of([ + [ tool:'test', db_name:'test_dontuntar' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + ]) + """ + } + } + then { + assert workflow.success + assertAll( + { assert snapshot( + workflow.out + ).match() } + ) + } + } + test("untar test db") { + + when { + workflow { + """ + input[0] = Channel.of( + [ + [id: 'testfmh', + tool: 'fmhfunprofiler', + db_name: 'fmhfunprofiler1000', + db_entity: '', + db_params: '11 1000' + ], + file(params.modules_testdata_base_path + 'funcprofiler/data/database/fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip') + ]) + """ + } + } + then { + assert workflow.success + assertAll( + { assert snapshot( + workflow.out + ).match() } + ) + } + } +} diff --git a/subworkflows/local/dbprep/tests/main.nf.test.snap b/subworkflows/local/dbprep/tests/main.nf.test.snap new file mode 100644 index 0000000..c4ada7d --- /dev/null +++ b/subworkflows/local/dbprep/tests/main.nf.test.snap @@ -0,0 +1,84 @@ +{ + "untar test db": { + "content": [ + { + "0": [ + [ + { + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "11 1000" + }, + [ + { + "db_entity": "main", + "db_path": "/nf-core/test-datasets/modules/data/funcprofiler/data/database/fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip" + } + ] + ] + ], + "dbs": [ + [ + { + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "11 1000" + }, + [ + { + "db_entity": "main", + "db_path": "/nf-core/test-datasets/modules/data/funcprofiler/data/database/fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip" + } + ] + ] + ] + } + ], + "timestamp": "2026-04-17T14:42:38.677532", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "leave untarred alone": { + "content": [ + { + "0": [ + [ + { + "tool": "test", + "db_name": "test_dontuntar", + "db_params": "-" + }, + [ + { + "db_entity": "main", + "db_path": "/nf-core/test-datasets/modules/data/genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam" + } + ] + ] + ], + "dbs": [ + [ + { + "tool": "test", + "db_name": "test_dontuntar", + "db_params": "-" + }, + [ + { + "db_entity": "main", + "db_path": "/nf-core/test-datasets/modules/data/genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam" + } + ] + ] + ] + } + ], + "timestamp": "2026-04-17T14:42:33.150258", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/profile/main.nf b/subworkflows/local/profile/main.nf new file mode 100644 index 0000000..25fc46b --- /dev/null +++ b/subworkflows/local/profile/main.nf @@ -0,0 +1,302 @@ +// +// Run profiling +// + +include { MIFASER } from '../../../modules/nf-core/mifaser/main' +include { HUMANN3_HUMANN } from '../../../modules/nf-core/humann3/humann/main' +include { HUMANN4 } from '../../../modules/local/humann4/humann/main' +include { HUMANN3_REGROUP } from '../../../modules/nf-core/humann3/regroup/main' +include { HUMANN4_REGROUP } from '../../../modules/local/humann4/regroup/main' +include { FMHFUNPROFILER } from '../../../modules/nf-core/fmhfunprofiler/main' +include { + METAPHLAN_METAPHLAN as MPAHUMANN3 ; + METAPHLAN_METAPHLAN as MPAHUMANN4 +} from '../../../modules/nf-core/metaphlan/metaphlan/main' +include { DIAMOND_BLASTX } from '../../../modules/nf-core/diamond/blastx/main' +include { RGI_BWT } from '../../../modules/nf-core/rgi/bwt/main' +include { RGI_CARDANNOTATION } from '../../../modules/nf-core/rgi/cardannotation/main' +include { EGGNOGMAPPER } from '../../../modules/nf-core/eggnogmapper/main' +include { SEQKIT_FQ2FA } from '../../../modules/nf-core/seqkit/fq2fa/main' +include { GUNZIP } from '../../../modules/nf-core/gunzip/main' + +workflow PROFILE { + take: + reads // [ [ meta ], [ reads ] ] + reads_concat // [ [ meta ], [ reads ] ] + databases // [ [ meta ], path ] + + main: + // These are count tables + ch_raw_profiles = channel.empty() + + /* + COMBINE READS WITH POSSIBLE DATABASES + */ + // Each tool as a slightly different input structure and generally separate + // input channels for reads vs databases. We restructure the channel tuple + // for each tool and make liberal use of multiMap to keep reads/databases + // channel element order in sync with each other + + // PAIRED-END READ TOOLS + ch_input_for_rgi = prepareInputs(reads, databases, 'rgi', false) + ch_input_for_eggnogmapper = prepareInputs(reads_concat, databases, 'eggnogmapper', true) + + // CONCAT READ TOOLS + ch_input_for_fmhfunprofiler = prepareInputs(reads_concat, databases, 'fmhfunprofiler', true) + ch_input_for_diamond = prepareInputs(reads_concat, databases, 'diamond', true) + ch_input_for_humann_v3 = prepareInputs(reads_concat, databases, 'humann_v3', true) + ch_input_for_humann_v4 = prepareInputs(reads_concat, databases, 'humann_v4', true) + ch_input_for_mifaser = prepareInputs(reads_concat, databases, 'mifaser', true) + + if (params.run_fmhfunprofiler) { + // this tool needs the db_params at runtime, so it takes a [[meta], path] tuple instead of just a path + getDbPath(ch_input_for_fmhfunprofiler.db, "main", true) + .multiMap { db_meta, db_path -> + def args = db_meta.db_params.split(" ") + + if (args.size() != 2) { + throw new IllegalArgumentException("fmh-funcprofiler's db_params must be configured with 2 ints (kmer and sketch db args) , but got ${args.size()}: ${db_meta.db_params}") + } + db_path: db_path + kmer: args[0] + sketch: args[1] + } + .set { fmh_db } + FMHFUNPROFILER( + ch_input_for_fmhfunprofiler.reads, + fmh_db.db_path, + fmh_db.kmer, + fmh_db.sketch, + ) + ch_raw_profiles = ch_raw_profiles.mix(FMHFUNPROFILER.out.csv) + } + if (params.run_mifaser) { + ch_input_for_mifaser = prepareInputs(reads_concat, databases, 'mifaser', true) + MIFASER(ch_input_for_mifaser.reads, getDbPath(ch_input_for_mifaser.db, 'main')) + ch_raw_profiles = ch_raw_profiles.mix(MIFASER.out.ec_counts) + } + + if (params.run_humann_v3) { + MPAHUMANN3( + ch_input_for_humann_v3.reads, + getDbPath(ch_input_for_humann_v3.db, 'humann_metaphlan'), + false, + ) + // JOIN the original reads with the profile output + ch_humann3_input = ch_input_for_humann_v3.reads.join(MPAHUMANN3.out.profile, by: 0) + // Join on meta map + HUMANN3_HUMANN( + ch_humann3_input.map { it -> [it[0], it[1]] }, + ch_humann3_input.map { it -> [it[0], it[2]] }, + getDbPath(ch_input_for_humann_v3.db, 'humann_nucleotide'), + getDbPath(ch_input_for_humann_v3.db, 'humann_protein'), + getDbPath(ch_input_for_humann_v3.db, 'humann_utility'), + ) + HUMANN3_REGROUP(HUMANN3_HUMANN.out.genefamilies, "uniref90_level4ec", getDbPath(ch_input_for_humann_v3.db, 'humann_utility')) + ch_raw_profiles = ch_raw_profiles.mix(MPAHUMANN3.out.profile) + ch_raw_profiles = ch_raw_profiles + .mix(HUMANN3_HUMANN.out.pathabundance) + .mix(HUMANN3_HUMANN.out.genefamilies) + .mix(HUMANN3_HUMANN.out.pathcoverage) + .mix(HUMANN3_REGROUP.out.regroup) + } + if (params.run_humann_v4) { + MPAHUMANN4( + ch_input_for_humann_v4.reads, + getDbPath(ch_input_for_humann_v4.db, 'humann_metaphlan'), + false, + ) + ch_humann4_input = ch_input_for_humann_v4.reads.join(MPAHUMANN4.out.profile, by: 0) + // Join on meta map + + HUMANN4( + ch_humann4_input.map { it -> [it[0], it[1]] }, + ch_humann4_input.map { it -> [it[0], it[2]] }, + getDbPath(ch_input_for_humann_v4.db, 'humann_nucleotide'), + getDbPath(ch_input_for_humann_v4.db, 'humann_protein'), + getDbPath(ch_input_for_humann_v4.db, 'humann_utility'), + ) + HUMANN4_REGROUP(HUMANN4.out.genefamilies, "uniclust90_level4ec", getDbPath(ch_input_for_humann_v4.db, 'humann_utility')) + ch_raw_profiles = ch_raw_profiles + .mix(HUMANN4.out.pathabundance) + .mix(HUMANN4.out.genefamilies) + .mix(HUMANN4.out.reactions) + .mix(HUMANN4_REGROUP.out.regroup) + } + + if (params.run_diamond) { + // 'txt' selects --outfmt 6 (tabular alignments). Do not use 'tsv': that is + // --outfmt 102, DIAMOND's taxonomic classification format, which requires a + // database built with --taxonmap/--taxonnodes and reports taxa rather than hits. + DIAMOND_BLASTX(ch_input_for_diamond.reads, getDbPath(ch_input_for_diamond.db, "main", true), 'txt', '') + ch_raw_profiles = ch_raw_profiles.mix(DIAMOND_BLASTX.out.txt) + } + + if (params.run_rgi) { + RGI_CARDANNOTATION(getDbPath(ch_input_for_rgi.db, "main")) + RGI_BWT(ch_input_for_rgi.reads, RGI_CARDANNOTATION.out.db, []) + ch_raw_profiles = ch_raw_profiles.mix(RGI_BWT.out.tsv) + } + if (params.run_eggnogmapper) { + SEQKIT_FQ2FA(ch_input_for_eggnogmapper.reads) + GUNZIP(SEQKIT_FQ2FA.out.fasta) + // EGGNOGMAPPER takes the search database as [ search_mode, db ]: the mode picks the + // flag emapper.py is given, and 'diamond' is what a .dmnd database needs. + EGGNOGMAPPER( + GUNZIP.out.gunzip, + getDbPath(ch_input_for_eggnogmapper.db, "eggnogmapper_db").map { db -> ['diamond', db] }, + getDbPath(ch_input_for_eggnogmapper.db, "eggnogmapper_data_dir"), + ) + ch_raw_profiles = ch_raw_profiles.mix(EGGNOGMAPPER.out.annotations) + } + + emit: + profiles = ch_raw_profiles // channel: [ val(meta), path(profile) ] + // Software versions are published to the `versions` topic by each module +} + + +// due to https://github.com/askimed/nf-test/issues/309 +workflow TEST_PREPAREINPUTS_WRAPPER { + take: + reads + databases + tool_name + singleFqTool + + main: + testresult = prepareInputs(reads, databases, tool_name, singleFqTool) + + emit: + reads = testresult.reads + db = testresult.db +} + + +// Custom Functions + +/** +* Combine profiles with their original database, then separate into two channels. +* +* The channel elements are assumed to be tuples one of [ meta, profile ], and the +* database to be of [db_key, meta, database_file]. +* +* @param ch_profile A channel containing a meta and the profiling report of a given profiler +* @param ch_database A channel containing a key, the database meta, and the database file/folders itself +* @return A multiMap'ed output channel with two sub channels, one with the profile and the other with the db +*/ +def sanitizeId(str) { + return str + .toString() + // underscores to hyphens, spaces to hyphens, drop special chars, collapse hyphens + .replaceAll(/_/, '-') + .replaceAll(/\s+/, '-') + .replaceAll(/[^\w\-.]/, '') + .replaceAll(/-+/, '-') +} +def prepareInputs(pairedreads, databases, tool_name, singleFqTool = false) { + /* + COMBINE READS WITH DATABASES - GROUPED BY TOOL, VERSION, AND PARAMS + + Input: + - pairedreads: channel of [meta, [reads]] + - databases: channel of [meta_db, file] + - tool_name: string - filter databases to only this tool (e.g., 'humann_v3', 'rgi') + - singleFqTool: boolean - if true, reads need concatenation for PE samples + + Output: + - channel of [meta_sample, reads, meta_db_grouped, db_files_map] + where each sample has entries for the specified tool + */ + // Step 1: Filter databases to only the requested tool, then group by db_name and db_params + def ch_dbs_grouped = databases + .flatMap { meta_db, file_list -> + // Flatten: emit one tuple per file object + file_list.collect { file_obj -> + // Merge the file object's db_entity into the metadata + def meta_with_entity = meta_db + [db_entity: file_obj.db_entity] + [meta_with_entity, file_obj] + } + } + .filter { meta_db, file -> + meta_db.tool == tool_name + } + .map { meta_db, file -> + // Create grouping key: [tool, db_name, db_params] + def group_key = [meta_db.tool, meta_db.db_name ?: '', meta_db.db_params ?: ''] + [group_key, meta_db, file] + } + // Group all files for same tool+db_name+db_params + .groupTuple() + .map { group_key, meta_db_list, files -> + def tool = group_key[0] + def db_name = group_key[1] + def db_params = group_key[2] + + // Convert files list to Map keyed by db_entity for deterministic snapshots + // Map structure: entity_name -> db_path (entity is already in the key) + def files_map = [:] + [meta_db_list, files] + .transpose() + .each { meta_db, file -> + // Store only the path + files_map[meta_db.db_entity] = file.db_path + } + + // Create consolidated metadata with db_entities as a Set + def meta_db_grouped = [id: sanitizeId("${tool}--${db_name}--${db_params}"), tool: tool, db_name: db_name, db_params: db_params, db_entities: files_map.keySet() as Set, num_files: files_map.size()] + + // Return files as map + [meta_db_grouped, files_map.toSorted()] + } + // Step 2: Combine reads with ALL grouped databases (cartesian product) + // Each sample will get one entry per unique db_name+db_params combination for this tool + def reads_with_dbs = pairedreads + .combine(ch_dbs_grouped) + .map { meta_sample, reads, meta_db, db_files_map -> + // Flatten reads to ensure consistent list format + def flat_reads = [reads].flatten() + + // Return: [meta_sample, reads_list, meta_db, db_files_map] + [meta_sample, flat_reads, meta_db, db_files_map] + } + + // Step 3: Validate and add metadata based on tool type + def result = reads_with_dbs + .map { meta, reads, db_meta, db_files -> + def expected = meta.single_end | singleFqTool ? 1 : 2 + if (reads.size() != expected) { + error("PE-aware tool (${!singleFqTool}) '${db_meta.tool}': expected ${expected} read file(s) for sample ${meta.id} (single_end=${meta.single_end}), got ${reads.size()}") + } + [meta, reads, db_meta, db_files] + } + .multiMap { it -> + // Carry the database identity into the read meta so that ext.args, ext.prefix + // and publishDir can key on it, as nf-core/taxprofiler does. Only a subset is + // merged: meta_db also holds an id, which must not overwrite the sample id. + reads: [it[0] + it[2].subMap('tool', 'db_name', 'db_params'), it[1]] + db: [it[2], it[3]] + } + return result +} + +def getDbPath(groupeddb, entity = 'main', asTuple = false) { + // Extract the relevant database file path by entity key from the files map + def dbpath = groupeddb.map { meta_db, files_map -> + // files_map is now a Map[entity -> db_path], so direct lookup + if (!files_map.containsKey(entity)) { + error("No entity '${entity}' file found in database ${meta_db.id}") + } + + def db_path = files_map[entity] + // Direct access to path + + if (asTuple) { + return [meta_db, db_path] + } + else { + return db_path + } + } + return dbpath +} diff --git a/subworkflows/local/profile/meta.yml b/subworkflows/local/profile/meta.yml new file mode 100644 index 0000000..d69de4d --- /dev/null +++ b/subworkflows/local/profile/meta.yml @@ -0,0 +1,61 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "profile" +description: | + Run the enabled read-based functional profilers. Reads are combined with every + database matching the tool, so a sample is profiled once per database name and + parameter combination. Tools that take paired input read from `reads`, tools + that take a single FASTQ read from `reads_concat`, and each profiler runs only + when its `run_` parameter is set. +keywords: + - microbiome + - metagenome + - fastq + - functional profiling +components: + - fmhfunprofiler + - mifaser + - humann3/humann + - humann3/regroup + - humann4 + - humann4/regroup + - metaphlan/metaphlan + - diamond/blastx + - rgi/bwt + - rgi/cardannotation + - eggnogmapper + - seqkit/fq2fa + - gunzip +input: + - reads: + type: file + description: | + Channel of paired-end (or single-end) reads, used by the profilers that + accept a read pair. + Structure: [ val(meta), [ path(reads) ] ] + pattern: "*.{fq,fastq}{,.gz}" + - reads_concat: + type: file + description: | + Channel of reads concatenated into a single file per sample, used by the + profilers that accept only one FASTQ. + Structure: [ val(meta), [ path(reads) ] ] + pattern: "*.{fq,fastq}{,.gz}" + - databases: + type: file + description: | + Channel of grouped databases as emitted by the `dbprep` subworkflow. + Structure: [ val(meta), [ [ db_entity: val(entity), db_path: path(db) ] ] ] +output: + - profiles: + type: file + description: | + Channel of the tabular profiles produced by each enabled tool. The meta + map identifies the sample, the tool and the database used. + Structure: [ val(meta), path(profile) ] + pattern: "*.{tsv,csv,txt}" +# Software versions are published to the `versions` topic by each module rather +# than emitted as a channel. +authors: + - "@nickp60" +maintainers: + - "@nickp60" diff --git a/subworkflows/local/profile/tests/main.nf.test b/subworkflows/local/profile/tests/main.nf.test new file mode 100644 index 0000000..ba46c7c --- /dev/null +++ b/subworkflows/local/profile/tests/main.nf.test @@ -0,0 +1,428 @@ +nextflow_workflow { + + topics 'versions' + name "Test profile " + script "../main.nf" + workflow "PROFILE" + + tag "subworkflows" + tag "subworkflows/profile" + + + test("run multisampleinputs - grouped databases (humann_v3)") { + tag 'humann' + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + input[0] = Channel.fromList( + [ + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + + + + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + input[0] = Channel.of( + [ + [ + id: 'fmh', + tool: 'fmhfunprofiler', + db_name: 'demo_1000', + db_entity: '', + db_params: '11 1000' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_nucleotide', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_nucleotide', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/chocophlan_nfDEMO.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_protein', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_protein', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/uniref_nfDEMO.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_metaphlan', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_metaphlan', + db_params: '' + ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/delete_me/metaphlan4_database.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_utility', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_utility', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/utility_nfDEMO.tar.gz') + ] + + ) + """ + } + } + } + when { + params { + run_humann_v3 = true + run_fmhfunprofiler = true + outdir = "$outputDir" + } + workflow { + """ + input[0] = DATAPREP.out.reads + input[1] = DATAPREP.out.reads_concat + input[2] = DBPREP.out.dbs + + """ + } + } + then { + assert workflow.success + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + assert snapshot(stable_path).match() + } + } + test("run fmh") { + tag 'fmh' + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + input[0] = Channel.fromList( + [ + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + + + + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + input[0] = Channel.of( + [ + [ + id: 'fmh', + tool: 'fmhfunprofiler', + db_name: 'demo_1000', + db_entity: '', + db_params: '11 1000' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip') + ], + + ) + """ + } + } + } + when { + params { + run_humann_v3 = false + run_fmhfunprofiler = true + outdir = "$outputDir" + } + workflow { + """ + input[0] = DATAPREP.out.reads + input[1] = DATAPREP.out.reads_concat + input[2] = DBPREP.out.dbs + + """ + } + } + then { + assert workflow.success + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + assert snapshot(stable_path).match() + } + } + test("run RGI") { + tag 'rgi' + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + input[0] = Channel.fromList( + [ + + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + + + + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + input[0] = Channel.of( + [ + [ + id: 'rgi', + tool: 'rgi', + db_name: 'fullv4', + db_entity: '', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/rgi/broadstreet-v4.0.1.tar.bz2') + ] + + ) + """ + } + } + } + when { + params { + run_humann_v3 = false + run_rgi = true + run_fmhfunprofiler = false + outdir = "$outputDir" + } + workflow { + """ + input[0] = DATAPREP.out.reads + input[1] = DATAPREP.out.reads_concat + input[2] = DBPREP.out.dbs + + """ + } + } + then { + assert workflow.success + def rgi_paths = getAllFilesFromDir(params.outdir, include: ["rgi/**"], ignore: ["rgi/card_database_processed/**"]) + println(rgi_paths) + def outDir = rgi_paths[0].parentFile + + def mappingFile = outDir.listFiles().find { + it.name.endsWith(".gene_mapping_data.txt") + } + + assert mappingFile != null : "No .gene_mapping_data.txt file found in ${outDir}" + + def sortedLines = mappingFile.readLines().sort() + + assert snapshot(sortedLines + topics.versions).match() + + } + } + test("run eggnogmapper") { + tag 'eggnogmapper' + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + // sarscov2 reads rather than minigut: the demo eggnog.db only carries + // annotations for the proteins in the demo proteome.dmnd, so a gut + // metagenome snapshots an annotation file with nothing but the header + input[0] = Channel.fromList( + [ + [['id':'sarscov2'],'1','ILLUMINA', + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz'), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz'),''] + ] + ) + """ + } + } + + + + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + // emapper.py's --data_dir must be a directory, but the demo eggnog.db is a bare file, + // so put it in one here + def eggnog_db = file(params.modules_testdata_base_path + 'delete_me/eggnogmapper/eggnog.db') + eggnog_db.copyTo("${workDir}/eggnog_data_dir/eggnog.db") + + input[0] = Channel.of( + [ + [ + id: 'eggnogmapper_demo_eggnogmapper_db', + tool: 'eggnogmapper', + db_name: 'demo', + db_entity: 'eggnogmapper_db', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/eggnog-mapper/proteome.dmnd') + ], + [ + [ + id: 'eggnogmapper_demo_eggnogmapper_data_dir', + tool: 'eggnogmapper', + db_name: 'demo', + db_entity: 'eggnogmapper_data_dir', + db_params: '' + ], + file("${workDir}/eggnog_data_dir") + ] + + ) + """ + } + } + } + when { + params { + run_eggnogmapper = true + outdir = "$outputDir" + } + workflow { + """ + input[0] = DATAPREP.out.reads + input[1] = DATAPREP.out.reads_concat + input[2] = DBPREP.out.dbs + + """ + } + } + then { + assert workflow.success + def eggnog_paths = getAllFilesFromDir(params.outdir, include: ["eggnogmapper/**"]) + def annotationFile = eggnog_paths.find { it.name.endsWith(".emapper.annotations") } + + assert annotationFile != null : "No .emapper.annotations file found in ${params.outdir}/eggnogmapper" + + // the ## lines carry the emapper version, the full command line and a runtime, so drop them + def stableLines = annotationFile.readLines().findAll { !it.startsWith("##") } + def header = stableLines.head() + def annotations = stableLines.tail().collect { it.split("\t", -1) } + + // guard the snapshot: a run that annotates nothing still writes the header, so + // without this an empty result would snapshot cleanly and hide a broken search + assert annotations : "No annotations in ${annotationFile}, only the header" + + // one row per annotated read is neither small nor guaranteed to be ordered the same + // way twice, so snapshot what the annotation is rather than which reads carried it: + // columns 2, 5 and 8 are seed_ortholog, eggNOG_OGs and Description + def annotated = annotations.collect { [it[1], it[4], it[7]] }.unique().sort() + + assert snapshot(header, annotated, eggnog_paths*.name.sort(), topics.versions).match() + + } + } + test("run diamond") { + tag 'diamond' + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + input[0] = Channel.fromList( + [ + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + + + + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + // B. fragilis is one of the genomes behind the minigut fixture, so blastx + // has something to find; the SARS-CoV-2 proteome the eggNOG-mapper test + // uses returns a single hit on these reads + input[0] = Channel.of( + [ + [ + id: 'diamond_bfragilis', + tool: 'diamond', + db_name: 'bfragilis', + db_entity: '', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/diamond/bfragilis_proteome.dmnd') + ], + + ) + """ + } + } + } + when { + params { + run_diamond = true + outdir = "$outputDir" + } + workflow { + """ + input[0] = DATAPREP.out.reads + input[1] = DATAPREP.out.reads_concat + input[2] = DBPREP.out.dbs + + """ + } + } + then { + assert workflow.success + def diamond_paths = getAllFilesFromDir(params.outdir, include: ["diamond/**"]) + def alignments = diamond_paths.find { it.name.endsWith(".txt") } + + assert alignments != null : "No DIAMOND alignment table found in ${params.outdir}/diamond" + + // --outfmt 6 writes no header, so an empty file is a silently failed search + def hits = alignments.readLines().collect { it.split("\t", -1) } + assert hits : "No alignments in ${alignments}" + + // as for eggNOG-mapper, snapshot which subjects were hit rather than which reads + // hit them. minigut hits 1201 of the 4170 proteins in the database, which is + // more than belongs in a snapshot file, so record how many and name the first few + def subjects = hits.collect { it[1] }.unique().sort() + + assert snapshot(subjects.size(), subjects.take(10), diamond_paths*.name.sort(), topics.versions).match() + + } + } +} diff --git a/subworkflows/local/profile/tests/main.nf.test.snap b/subworkflows/local/profile/tests/main.nf.test.snap new file mode 100644 index 0000000..4bfbc6e --- /dev/null +++ b/subworkflows/local/profile/tests/main.nf.test.snap @@ -0,0 +1,154 @@ +{ + "run RGI": { + "content": [ + [ + "ARO Term\tARO Accession\tReference Model Type\tReference DB\tAlleles with Mapped Reads\tReference Allele(s) Identity to CARD Reference Protein (%)\tResistomes & Variants: Observed in Genome(s)\tResistomes & Variants: Observed in Plasmid(s)\tResistomes & Variants: Observed Pathogen(s)\tCompletely Mapped Reads\tMapped Reads with Flanking Sequence\tAll Mapped Reads\tAverage Percent Coverage\tAverage Length Coverage (bp)\tAverage MAPQ (Completely Mapped Reads)\tNumber of Mapped Baits\tNumber of Mapped Baits with Reads\tAverage Number of reads per Bait\tNumber of reads per Bait Coefficient of Variation (%)\tNumber of reads mapping to baits and mapping to complete gene\tNumber of reads mapping to baits and mapping to complete gene (%)\tMate Pair Linkage (# reads)\tReference Length\tAMR Gene Family\tDrug Class\tResistance Mechanism", + "Escherichia coli acrA\t3004043\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t51.00\t0.00\t51.00\t100.00\t1194.00\t188.71\t0\t0\t0\t0\tN/A\tN/A\t\t1194\tresistance-nodulation-cell division (RND) antibiotic efflux pump\tfluoroquinolone antibiotic; cephalosporin; glycylcycline; penicillin beta-lactam; tetracycline antibiotic; rifamycin antibiotic; phenicol antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "Escherichia coli emrE\t3004039\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t23.00\t0.00\t23.00\t100.00\t333.00\t175.96\t0\t0\t0\t0\tN/A\tN/A\t\t333\tsmall multidrug resistance (SMR) antibiotic efflux pump\tmacrolide antibiotic\tantibiotic efflux", + "LptD\t3005059\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tKlebsiella pneumoniae\t38.00\t0.00\t38.00\t44.57\t1047.00\t131.34\t0\t0\t0\t0\tN/A\tN/A\t\t2349\tATP-binding cassette (ABC) antibiotic efflux pump\tcarbapenem; peptide antibiotic; aminocoumarin antibiotic; rifamycin antibiotic\tantibiotic efflux", + "acrB\t3000216\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t133.00\t0.00\t133.00\t100.00\t3150.00\t191.36\t0\t0\t0\t0\tN/A\tN/A\t\t3150\tresistance-nodulation-cell division (RND) antibiotic efflux pump\tfluoroquinolone antibiotic; cephalosporin; glycylcycline; penicillin beta-lactam; tetracycline antibiotic; rifamycin antibiotic; phenicol antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "kdpE\t3003841\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t45.00\t0.00\t45.00\t100.00\t678.00\t175.80\t0\t0\t0\t0\tN/A\tN/A\t\t678\tkdpDE\taminoglycoside antibiotic\tantibiotic efflux", + "leuO\t3003843\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tEscherichia coli\t55.00\t0.00\t55.00\t100.00\t945.00\t173.55\t0\t0\t0\t0\tN/A\tN/A\t\t945\tmajor facilitator superfamily (MFS) antibiotic efflux pump\tnucleoside antibiotic; disinfecting agents and antiseptics\tantibiotic efflux", + "rmtH\t3003198\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tKlebsiella pneumoniae\t4.00\t0.00\t4.00\t6.59\t50.00\t79.00\t0\t0\t0\t0\tN/A\tN/A\t\t759\t16S rRNA methyltransferase (G1405)\taminoglycoside antibiotic\tantibiotic target alteration", + "tet(Q)\t3000191\tprotein homolog model\tCARD\t1\t100.0\tno data\tno data\tBacteroides fragilis\t138.00\t0.00\t138.00\t100.00\t1974.00\t179.62\t0\t0\t0\t0\tN/A\tN/A\t\t1974\ttetracycline-resistant ribosomal protection protein\ttetracycline antibiotic\tantibiotic target protection", + [ + "DATAPREP:CAT_FASTQ", + "cat", + "9.5" + ], + [ + "DBPREP:UNTAR", + "untar", + "1.34" + ], + [ + "PROFILE:RGI_BWT", + "kma", + "KMA-1.6.11" + ], + [ + "PROFILE:RGI_BWT", + "rgi", + "6.0.8" + ], + [ + "PROFILE:RGI_BWT", + "rgi-database", + "4.0.1" + ] + ] + ], + "timestamp": "2026-08-04T15:13:38.986799", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "run diamond": { + "content": [ + 1201, + [ + "WP_002558051.1", + "WP_002560983.1", + "WP_004291423.1", + "WP_004291424.1", + "WP_004291426.1", + "WP_004291454.1", + "WP_004291455.1", + "WP_004291456.1", + "WP_004291466.1", + "WP_004291467.1" + ], + [ + "minigut_bfragilis.diamond.log", + "minigut_bfragilis.diamond.txt" + ], + [ + [ + "DATAPREP:CAT_FASTQ", + "cat", + "9.5" + ], + [ + "PROFILE:DIAMOND_BLASTX", + "diamond", + "2.2.1" + ] + ] + ], + "timestamp": "2026-08-04T15:23:43.891346", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "run fmh": { + "content": [ + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129", + "minigut_KOs_sketched_scaled_1000_demo.sig.fmhfunprofiler.csv:md5,1081039ab9e9b378d2dfd3206e96e917" + ] + ], + "timestamp": "2026-07-29T16:20:47.621463", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "run multisampleinputs - grouped databases (humann_v3)": { + "content": [ + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129", + "minigut_KOs_sketched_scaled_1000_demo.sig.fmhfunprofiler.csv:md5,1081039ab9e9b378d2dfd3206e96e917" + ] + ], + "timestamp": "2026-07-29T16:20:29.367839", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "run eggnogmapper": { + "content": [ + "#query\tseed_ortholog\tevalue\tscore\teggNOG_OGs\tmax_annot_lvl\tCOG_category\tDescription\tPreferred_name\tGOs\tEC\tKEGG_ko\tKEGG_Pathway\tKEGG_Module\tKEGG_Reaction\tKEGG_rclass\tBRITE\tKEGG_TC\tCAZy\tBiGG_Reaction\tPFAMs", + [ + [ + "ENSSASP00005000002.1", + "COG0498@1|root,COG0498@2|Bacteria,1MUWQ@1224|Proteobacteria,2VHR6@28216|Betaproteobacteria,2KUMA@206389|Rhodocyclales", + "threonine synthase" + ] + ], + [ + "sarscov2.emapper.annotations", + "sarscov2.emapper.seed_orthologs" + ], + [ + [ + "DATAPREP:CAT_FASTQ", + "cat", + "9.5" + ], + [ + "PROFILE:EGGNOGMAPPER", + "eggnog-mapper", + "2.1.13" + ], + [ + "PROFILE:GUNZIP", + "gunzip", + "1.13" + ], + [ + "PROFILE:SEQKIT_FQ2FA", + "seqkit", + "2.13.0" + ] + ] + ], + "timestamp": "2026-08-04T15:14:00.583844", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/profile/tests/prepareInput.nf.test b/subworkflows/local/profile/tests/prepareInput.nf.test new file mode 100644 index 0000000..80423fc --- /dev/null +++ b/subworkflows/local/profile/tests/prepareInput.nf.test @@ -0,0 +1,308 @@ +nextflow_workflow { + + name "Test prepareInputs via wrapper workflow" + script "../main.nf" + workflow "TEST_PREPAREINPUTS_WRAPPER" + + tag "subworkflows" + tag "subworkflows/profile" + + + test("prep inputs - single FQ tool -- fail when given paired data") { + when { + workflow { + """ + input[0] = Channel.fromList([ + [ + [ + id: '2612', + sample: '2612', + run_accession: 'ERR5766176', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['ERX5474932_ERR5766176_r1.fastq.gz', 'ERX5474932_ERR5766176_r2.fastq.gz'] + ], + [ + [ + id: 'sample2', + sample: 'sample2', + run_accession: 'abc', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['sample2_r1.fastq.gz', 'sample2_r2.fastq.gz'] + ], + ]) + + input[1] = Channel.fromList([ + [ + [ + tool: 'fmhfunprofiler', + db_name: 'fmhfunprofiler1000', + params: '11 1000' + ], + [ + [db_entity: 'main', db_path: "./KOs_sketched_scaled_1000_demo.sig.zip"] + ] + ]]) + + input[2] = 'fmhfunprofiler' + input[3] = true + """ + } + } + then { + assert workflow.failed + assert snapshot(workflow.out).match() + + } + } + test("prep inputs - single FQ tool ") { + when { + workflow { + """ + input[0] = Channel.fromList([ + [ + [ + id: '2612', + sample: '2612', + run_accession: 'ERR5766176', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['ERX5474932_ERR5766176_merged.fastq.gz'] + ], + [ + [ + id: 'sample2', + sample: 'sample2', + run_accession: 'abc', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['sample2_merged.fastq.gz'] + ], + ]) + input[1] = Channel.fromList([ + [ + [ + tool: 'fmhfunprofiler', + db_name: 'fmhfunprofiler1000', + params: '11 1000' + ], + [ + [db_entity: 'main', db_path: "./KOs_sketched_scaled_1000_demo.sig.zip"] + ] + ]]) + input[2] = 'fmhfunprofiler' + input[3] = true + """ + } + } + then { + assert workflow.success + assert snapshot(workflow.out).match() + + } + } + test("prep inputs - PE aware tool (rgi)") { + when { + workflow { + """ + input[0] = Channel.fromList([ + [ + [ + id: '2612', + sample: '2612', + run_accession: 'ERR5766176', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['ERX5474932_ERR5766176_r1.fastq.gz', 'ERX5474932_ERR5766176_r2.fastq.gz'] + ], + [ + [ + id: 'sample2', + sample: 'sample2', + run_accession: 'abc', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['sample2_r1.fastq.gz', 'sample2_r2.fastq.gz'] + ], + ]) + + input[1] = Channel.fromList([ + [ + [ + tool: 'rgi', + db_name: '4.0.1', + params: '' + ], + [ + [db_entity: 'main', db_path: 'broadstreet-v4.0.1.tar.bz2'] + ] + ]]) + input[2] = 'rgi' // tool_name + input[3] = false // singleFqTool + """ + } + } + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + } + + test("prep inputs - grouped databases (humann_v3)") { + when { + workflow { + """ + input[0] = Channel.of([ + [ + id: '2612', + sample: '2612', + run_accession: 'ERR5766176', + instrument_platform: 'ILLUMINA', + single_end: false + ], + ['ERX5474932_ERR5766176_merged.fastq.gz'] + ]) + + input[1] = Channel.fromList([ + [ + [ + id: 'humann_v3_demo_v3_humann_nucleotide', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_nucleotide', + db_params: '' + ], + [ + [db_entity: 'humann_nucleotide', db_path: 'chocophlan_nfDEMO.tar.gz'], + [db_entity: 'humann_protein', db_path: 'uniref_nfDEMO.tar.gz'], + [db_entity: 'humann_utility', db_path: 'utility_nfDEMO.tar.gz'] + ] + ]]) + + input[2] = 'humann_v3' // tool_name + input[3] = true // singleFqTool + """ + } + } + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + } + test("prep multisampleinputs - grouped databases (humann_v3)") { + setup { + run("DATAPREP") { + script "subworkflows/local/dataprep/main.nf" + process { + """ + input[0] = Channel.fromList( + [ + [["id": "2612"],"ERR5766176",'ILLUMINA', + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_2.fastq.gz'),''], + [["id": "2612"], "ERR5766176_B","ILLUMINA", + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_B_1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'taxprofiler/data/fastq/ERX5474932_ERR5766176_B_2.fastq.gz'),''], + + [['id':'minigut'],'1','ILLUMINA', + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R1.fastq.gz'), + file(params.pipelines_testdata_base_path + 'mag/test_data/test_minigut_R2.fastq.gz'),''] + ] + ) + """ + } + } + run("DBPREP") { + script "subworkflows/local/dbprep/main.nf" + process { + """ + input[0] = Channel.of( + [ + [ + id: 'humann_v3_demo_v3_humann_nucleotide', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_nucleotide', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/chocophlan_nfDEMO.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_protein', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_protein', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/uniref_nfDEMO.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_metaphlan', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_metaphlan', + db_params: '' + ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/delete_me/metaphlan4_database.tar.gz') + ], + [ + [ + id: 'humann_v3_demo_v3_humann_utility', + tool: 'humann_v3', + db_name: 'demo_v3', + db_entity: 'humann_utility', + db_params: '' + ], + file(params.pipelines_testdata_base_path + 'funcprofiler/data/database/humann/v3/utility_nfDEMO.tar.gz') + ] + + ) + """ + } + } + } + when { + workflow { + """ + input[0] = DATAPREP.out.reads_concat + input[1] = DBPREP.out.dbs + input[2] = 'humann_v3' // tool_name + input[3] = true // singleFqTool + """ + } + } + then { + assert workflow.success + assert snapshot( + workflow.out.reads + .sort { it[0].toString() }, + workflow.out.db + .sort { it[0].toString() } + .collect { item -> + item.collect { element -> + if (element instanceof Map) { + // Sort map by keys AND sort any list values + return element.sort().collectEntries { key, value -> + if (value instanceof List) { + [(key): value.sort()] + } else { + [(key): value] + } + } + } + return element + } + } + ).match() + } + } +} diff --git a/subworkflows/local/profile/tests/prepareInput.nf.test.snap b/subworkflows/local/profile/tests/prepareInput.nf.test.snap new file mode 100644 index 0000000..13c4852 --- /dev/null +++ b/subworkflows/local/profile/tests/prepareInput.nf.test.snap @@ -0,0 +1,545 @@ +{ + "prep inputs - single FQ tool ": { + "content": [ + { + "0": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_merged.fastq.gz" + ] + ], + [ + { + "id": "sample2", + "sample": "sample2", + "run_accession": "abc", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "" + }, + [ + "sample2_merged.fastq.gz" + ] + ] + ], + "1": [ + [ + { + "id": "fmhfunprofiler-fmhfunprofiler1000-", + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "./KOs_sketched_scaled_1000_demo.sig.zip" + } + ], + [ + { + "id": "fmhfunprofiler-fmhfunprofiler1000-", + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "./KOs_sketched_scaled_1000_demo.sig.zip" + } + ] + ], + "db": [ + [ + { + "id": "fmhfunprofiler-fmhfunprofiler1000-", + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "./KOs_sketched_scaled_1000_demo.sig.zip" + } + ], + [ + { + "id": "fmhfunprofiler-fmhfunprofiler1000-", + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "./KOs_sketched_scaled_1000_demo.sig.zip" + } + ] + ], + "reads": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_merged.fastq.gz" + ] + ], + [ + { + "id": "sample2", + "sample": "sample2", + "run_accession": "abc", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "fmhfunprofiler", + "db_name": "fmhfunprofiler1000", + "db_params": "" + }, + [ + "sample2_merged.fastq.gz" + ] + ] + ] + } + ], + "timestamp": "2026-08-04T12:26:37.701915", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "prep inputs - grouped databases (humann_v3)": { + "content": [ + { + "0": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_merged.fastq.gz" + ] + ] + ], + "1": [ + [ + { + "id": "humann-v3-demo-v3-", + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "", + "db_entities": [ + "humann_nucleotide", + "humann_protein", + "humann_utility" + ], + "num_files": 3 + }, + { + "humann_nucleotide": "chocophlan_nfDEMO.tar.gz", + "humann_protein": "uniref_nfDEMO.tar.gz", + "humann_utility": "utility_nfDEMO.tar.gz" + } + ] + ], + "db": [ + [ + { + "id": "humann-v3-demo-v3-", + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "", + "db_entities": [ + "humann_nucleotide", + "humann_protein", + "humann_utility" + ], + "num_files": 3 + }, + { + "humann_nucleotide": "chocophlan_nfDEMO.tar.gz", + "humann_protein": "uniref_nfDEMO.tar.gz", + "humann_utility": "utility_nfDEMO.tar.gz" + } + ] + ], + "reads": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_merged.fastq.gz" + ] + ] + ] + } + ], + "timestamp": "2026-08-04T12:26:48.134987", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "prep inputs - single FQ tool -- fail when given paired data": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "db": [ + + ], + "reads": [ + + ] + } + ], + "timestamp": "2026-04-17T01:27:47.151296", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "prep inputs - PE aware tool (rgi)": { + "content": [ + { + "0": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_r1.fastq.gz", + "ERX5474932_ERR5766176_r2.fastq.gz" + ] + ], + [ + { + "id": "sample2", + "sample": "sample2", + "run_accession": "abc", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "" + }, + [ + "sample2_r1.fastq.gz", + "sample2_r2.fastq.gz" + ] + ] + ], + "1": [ + [ + { + "id": "rgi-4.0.1-", + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "broadstreet-v4.0.1.tar.bz2" + } + ], + [ + { + "id": "rgi-4.0.1-", + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "broadstreet-v4.0.1.tar.bz2" + } + ] + ], + "db": [ + [ + { + "id": "rgi-4.0.1-", + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "broadstreet-v4.0.1.tar.bz2" + } + ], + [ + { + "id": "rgi-4.0.1-", + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "", + "db_entities": [ + "main" + ], + "num_files": 1 + }, + { + "main": "broadstreet-v4.0.1.tar.bz2" + } + ] + ], + "reads": [ + [ + { + "id": "2612", + "sample": "2612", + "run_accession": "ERR5766176", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "" + }, + [ + "ERX5474932_ERR5766176_r1.fastq.gz", + "ERX5474932_ERR5766176_r2.fastq.gz" + ] + ], + [ + { + "id": "sample2", + "sample": "sample2", + "run_accession": "abc", + "instrument_platform": "ILLUMINA", + "single_end": false, + "tool": "rgi", + "db_name": "4.0.1", + "db_params": "" + }, + [ + "sample2_r1.fastq.gz", + "sample2_r2.fastq.gz" + ] + ] + ] + } + ], + "timestamp": "2026-08-04T12:26:43.049758", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "prep multisampleinputs - grouped databases (humann_v3)": { + "content": [ + [ + [ + { + "id": "2612", + "single_end": true, + "instrument_platform": "ILLUMINA", + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "-" + }, + [ + "2612.merged.fastq.gz:md5,270bf4c4d9707c6afc970fe5622cc673" + ] + ], + [ + { + "id": "minigut", + "single_end": true, + "instrument_platform": "ILLUMINA", + "tool": "humann_v3", + "db_name": "demo_v3", + "db_params": "-" + }, + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129" + ] + ] + ], + [ + [ + { + "db_entities": [ + "humann_metaphlan", + "humann_nucleotide", + "humann_protein", + "humann_utility" + ], + "db_name": "demo_v3", + "db_params": "-", + "id": "humann-v3-demo-v3-", + "num_files": 4, + "tool": "humann_v3" + }, + { + "humann_metaphlan": [ + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.1.bt2l:md5,f560f1878d407cad746b40e19c137b2f", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.2.bt2l:md5,ada1fa4dbfa0bbd00fd9541458d0caab", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.3.bt2l:md5,1b5ec794c2f0c456ea60deb5898f4840", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.4.bt2l:md5,fe7bbac658aece93db332255910e3f4f", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.fna.bz2:md5,43dd63a3263c01105af26b701a9b5562", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.pkl:md5,005453b7c66c85f3e01218653d09e266", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.1.bt2l:md5,7b23ad55748937a1b21f8ed735fe0d73", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.2.bt2l:md5,acc38a28f2e590d5ce12a9defe4c8c87" + ], + "humann_nucleotide": [ + "g__Bacteroides.s__Bacteroides_dorei.centroids.v201901_v31.ffn.gz:md5,c23ab47a3f0a34abd20f0b1826482c6d", + "g__Bacteroides.s__Bacteroides_vulgatus.centroids.v201901_v31.ffn.gz:md5,61a2c5aa5ff04e400147974852e5bcc2" + ], + "humann_protein": [ + "uniref90_demo_prots_v201901b.dmnd:md5,1d2f8df48a349d72436425aafa29a6b1", + "uniref90_demo_prots_v201901b.fna:md5,10699776b9428fdf673030dba1f818a7" + ], + "humann_utility": [ + "README.txt:md5,9d3db20d44df2404c41064a815d14e35", + "map_eggnog_name.txt.gz:md5,b23ae8c34c86b1f160d66b1e218d1c8a", + "map_eggnog_uniref50.txt.gz:md5,50bd690aecd716cdacee47ecaf405d56", + "map_eggnog_uniref90.txt.gz:md5,4dac1a34d5557565afd964f44e0dab2e", + "map_go_name.txt.gz:md5,9e437e5000ce203b74cd16b42acca0f2", + "map_go_uniref50.txt.gz:md5,efa82fad21970c4b6f8695aeed44f56f", + "map_go_uniref90.txt.gz:md5,cc12d3d1d8a9493b5eb1637004d4de02", + "map_kegg-mdl_name.txt.gz:md5,ce28c1ae107325b12a328644f70f724d", + "map_ko_name.txt.gz:md5,093ceb058735a98e2e68d178f791ed36", + "map_ko_uniref50.txt.gz:md5,628aa13e990777760f822d347cb0b1ad", + "map_ko_uniref90.txt.gz:md5,420f8ec15e77c18da8069465f679cde7", + "map_level4ec_name.txt.gz:md5,2e201c4d860789795dd7c8acb36ab595", + "map_level4ec_uniref50.txt.gz:md5,c6988287fd4bdda511110e18915eeea9", + "map_level4ec_uniref90.txt.gz:md5,b14904213f3e3c010a8b3fdbdc9cd7ef", + "map_pfam_name.txt.gz:md5,cdd6c73f7fb4bc0284d9e6769124854b", + "map_pfam_uniref50.txt.gz:md5,b9f128f4b337c83a652c9926e6c292e4", + "map_pfam_uniref90.txt.gz:md5,5d03d39e5305a541b6017fd308e2154b", + "map_uniref50_name.txt.bz2:md5,62ea0afa60ad7ad1ba7aa2af43ed7d23", + "map_uniref90_name.txt.bz2:md5,988f3ce65a432bbe2c8fd3354cad99fa" + ] + } + ], + [ + { + "db_entities": [ + "humann_metaphlan", + "humann_nucleotide", + "humann_protein", + "humann_utility" + ], + "db_name": "demo_v3", + "db_params": "-", + "id": "humann-v3-demo-v3-", + "num_files": 4, + "tool": "humann_v3" + }, + { + "humann_metaphlan": [ + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.1.bt2l:md5,f560f1878d407cad746b40e19c137b2f", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.2.bt2l:md5,ada1fa4dbfa0bbd00fd9541458d0caab", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.3.bt2l:md5,1b5ec794c2f0c456ea60deb5898f4840", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.4.bt2l:md5,fe7bbac658aece93db332255910e3f4f", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.fna.bz2:md5,43dd63a3263c01105af26b701a9b5562", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.pkl:md5,005453b7c66c85f3e01218653d09e266", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.1.bt2l:md5,7b23ad55748937a1b21f8ed735fe0d73", + "mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.2.bt2l:md5,acc38a28f2e590d5ce12a9defe4c8c87" + ], + "humann_nucleotide": [ + "g__Bacteroides.s__Bacteroides_dorei.centroids.v201901_v31.ffn.gz:md5,c23ab47a3f0a34abd20f0b1826482c6d", + "g__Bacteroides.s__Bacteroides_vulgatus.centroids.v201901_v31.ffn.gz:md5,61a2c5aa5ff04e400147974852e5bcc2" + ], + "humann_protein": [ + "uniref90_demo_prots_v201901b.dmnd:md5,1d2f8df48a349d72436425aafa29a6b1", + "uniref90_demo_prots_v201901b.fna:md5,10699776b9428fdf673030dba1f818a7" + ], + "humann_utility": [ + "README.txt:md5,9d3db20d44df2404c41064a815d14e35", + "map_eggnog_name.txt.gz:md5,b23ae8c34c86b1f160d66b1e218d1c8a", + "map_eggnog_uniref50.txt.gz:md5,50bd690aecd716cdacee47ecaf405d56", + "map_eggnog_uniref90.txt.gz:md5,4dac1a34d5557565afd964f44e0dab2e", + "map_go_name.txt.gz:md5,9e437e5000ce203b74cd16b42acca0f2", + "map_go_uniref50.txt.gz:md5,efa82fad21970c4b6f8695aeed44f56f", + "map_go_uniref90.txt.gz:md5,cc12d3d1d8a9493b5eb1637004d4de02", + "map_kegg-mdl_name.txt.gz:md5,ce28c1ae107325b12a328644f70f724d", + "map_ko_name.txt.gz:md5,093ceb058735a98e2e68d178f791ed36", + "map_ko_uniref50.txt.gz:md5,628aa13e990777760f822d347cb0b1ad", + "map_ko_uniref90.txt.gz:md5,420f8ec15e77c18da8069465f679cde7", + "map_level4ec_name.txt.gz:md5,2e201c4d860789795dd7c8acb36ab595", + "map_level4ec_uniref50.txt.gz:md5,c6988287fd4bdda511110e18915eeea9", + "map_level4ec_uniref90.txt.gz:md5,b14904213f3e3c010a8b3fdbdc9cd7ef", + "map_pfam_name.txt.gz:md5,cdd6c73f7fb4bc0284d9e6769124854b", + "map_pfam_uniref50.txt.gz:md5,b9f128f4b337c83a652c9926e6c292e4", + "map_pfam_uniref90.txt.gz:md5,5d03d39e5305a541b6017fd308e2154b", + "map_uniref50_name.txt.bz2:md5,62ea0afa60ad7ad1ba7aa2af43ed7d23", + "map_uniref90_name.txt.bz2:md5,988f3ce65a432bbe2c8fd3354cad99fa" + ] + } + ] + ] + ], + "timestamp": "2026-08-04T14:42:06.880276", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + } +} \ No newline at end of file diff --git a/subworkflows/local/utils_nfcore_funcprofiler_pipeline/main.nf b/subworkflows/local/utils_nfcore_funcprofiler_pipeline/main.nf index c042558..226c01d 100644 --- a/subworkflows/local/utils_nfcore_funcprofiler_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_funcprofiler_pipeline/main.nf @@ -8,14 +8,14 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { samplesheetToList } from 'plugin/nf-schema' -include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' -include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { imNotification } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -24,77 +24,95 @@ include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipelin */ 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 + 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 + outdir // string: The output directory where the results will be saved + input // string: Path to input samplesheet + databases // string: Path to databases + help // boolean: Display help message and exit + help_full // boolean: Show the full help message + show_hidden // boolean: Show hidden parameters in the help message main: - ch_versions = Channel.empty() + ch_versions = channel.empty() // // Print version and exit if required and dump pipeline parameters to JSON file // - UTILS_NEXTFLOW_PIPELINE ( + UTILS_NEXTFLOW_PIPELINE( version, true, outdir, - workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 + workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1, ) // // Validate parameters and generate parameter summary to stdout // - UTILS_NFSCHEMA_PLUGIN ( + 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/funcprofiler ${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/funcprofiler/blob/master/CITATIONS.md +""" + command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " + // + // Validate parameters and generate parameter summary to stdout + // + UTILS_NFSCHEMA_PLUGIN( workflow, validate_params, - null + null, + help, + help_full, + show_hidden, + before_text, + after_text, + command, + false ) // // Check config provided to the pipeline // - UTILS_NFCORE_PIPELINE ( + UTILS_NFCORE_PIPELINE( nextflow_cli_args ) - // - // Custom validation for pipeline parameters - // - validateInputParameters() - // // Create channel from input file provided through params.input // Channel - .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) - .map { - meta, fastq_1, fastq_2 -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } - } - .groupTuple() - .map { samplesheet -> - validateInputSamplesheet(samplesheet) - } - .map { - meta, fastqs -> - return [ meta, fastqs.flatten() ] - } + .fromList(samplesheetToList(params.input, "assets/schema_input.json")) .set { ch_samplesheet } + // + // Create channel from databases file provided through params.databases + // + Channel + .fromList(samplesheetToList(params.databases, "assets/schema_database.json")) + .set { ch_databases } + emit: samplesheet = ch_samplesheet - versions = ch_versions + databases = ch_databases + versions = ch_versions } /* @@ -104,15 +122,14 @@ workflow PIPELINE_INITIALISATION { */ workflow PIPELINE_COMPLETION { - take: - email // string: email address - email_on_fail // string: email address sent on pipeline failure + email // string: email address + email_on_fail // string: email address sent on pipeline failure plaintext_email // boolean: Send plain-text email instead of HTML - outdir // path: Path to output directory where results will be published + outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output - hook_url // string: hook URL for notifications - multiqc_report // string: Path to MultiQC report + hook_url // string: hook URL for notifications + multiqc_report // string: Path to MultiQC report main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") @@ -135,13 +152,10 @@ 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: https://nf-co.re/docs/usage/troubleshooting") } } @@ -150,77 +164,96 @@ workflow PIPELINE_COMPLETION { FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -// -// Check and validate pipeline parameters -// -def validateInputParameters() { - genomeExistsError() -} - -// // Validate channels from input samplesheet // def validateInputSamplesheet(input) { - def (metas, fastqs) = input[1..2] + def (metas, fastqs, fasta) = input[1..3] // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 + def endedness_ok = metas.collect { meta -> meta.single_end }.unique().size == 1 if (!endedness_ok) { error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") } - return [ metas[0], fastqs ] -} -// -// Get attribute from genome config file e.g. fasta -// -def getGenomeAttribute(attribute) { - if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) { - if (params.genomes[ params.genome ].containsKey(attribute)) { - return params.genomes[ params.genome ][ attribute ] - } - } - return null + return [metas[0], fastqs, fasta] } -// -// Exit pipeline if incorrect --genome key provided -// -def genomeExistsError() { - if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + - " Currently, the available genome keys are:\n" + - " ${params.genomes.keySet().join(", ")}\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - error(error_string) - } -} // // Generate methods description for MultiQC // def toolCitationText() { - // TODO nf-core: Optionally add in-text citation tools to this list. - // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", - // Uncomment function in methodsDescriptionText to render in MultiQC report + // pending fastq_shortreads_preprocess_qc implementation + def text_qc = "" + + def text_humann = [ + "Functional profiling was performed with", + params.run_humann_v3 && params.run_humann_v4 + ? "HUMAnN v3 and HUMAnN v4 (Beghini et al. 2021)" + : params.run_humann_v3 + ? "HUMAnN v3 (Beghini et al. 2021)" + : "HUMAnN v4 (Beghini et al. 2021)", + "using MetaPhlAn (Blanco-Míguez et al. 2023) for taxonomic marker-based profiling.", + ].join(' ').trim() + + def text_diamond = ["Protein-level sequence alignment was performed with DIAMOND (Buchfink et al. 2021)."].join(' ').trim() + + def text_fmhfunprofiler = ["Functional profiling was additionally performed with fmhfunprofiler (Hera et al. 2024)."].join(' ').trim() + + def text_mifaser = ["Enzyme function annotation was performed with mi-faser (Zhu et al. 2017)."].join(' ').trim() + + def text_eggnogmapper = ["Functional Annotation, Orthology Assignments, and Domain Prediction was performed with eggNOG-mapper v2 (Cantalapiedra et. al 2021)"].join(' ').trim() + + def text_rgi = ["Resistome prediction was performed using RGI (Alcock et. al 2023)"].join(' ').trim() + def citation_text = [ - "Tools used in the workflow included:", - "FastQC (Andrews 2010),", - "MultiQC (Ewels et al. 2016)", - "." - ].join(' ').trim() + "Tools used in the workflow included:", + !params.skip_preprocessing_qc ? text_qc : "", + params.run_humann_v3 || params.run_humann_v4 ? text_humann : "", + params.run_diamond ? text_diamond : "", + params.run_fmhfunprofiler ? text_fmhfunprofiler : "", + params.run_mifaser ? text_mifaser : "", + params.run_eggnogmapper ? text_eggnogmapper : "", + params.run_rgi ? text_rgi : "", + "Pipeline results statistics were summarised with MultiQC (Ewels et al. 2016).", + ].join(' ').trim().replaceAll("[,|.] +\\.", ".") return citation_text } def toolBibliographyText() { - // TODO nf-core: Optionally add bibliographic entries to this list. - // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", - // Uncomment function in methodsDescriptionText to render in MultiQC report + // + //def text_qc = [!params.skip_preprocessing_qc ? "
  • Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. Available at: http://www.bioinformatics.babraham.ac.uk/projects/fastqc/
  • " : ""].join(' ').trim() + def text_qc = "" // pending implementation of fastq_shortreads_preprocess_qc subworkflow + + def text_humann = [ + params.run_humann_v3 || params.run_humann_v4 ? "
  • Beghini, F., McIver, L. J., Blanco-M\u00edguez, A., Dubois, L., Asnicar, F., Maharjan, S., Mailyan, A., Thomas, A. M., Manghi, P., Valles-Colomer, M., Weingart, G., Zhang, Y., Zolfo, M., Huttenhower, C., Franzosa, E. A., & Segata, N. (2021). Integrating taxonomic, functional, and strain-level profiling of diverse microbial communities with bioBakery 3. eLife, 10, e65088. 10.7554/eLife.65088
  • " : "", + params.run_humann_v3 || params.run_humann_v4 ? "
  • Blanco-M\u00edguez, A., Beghini, F., Cumbo, F., McIver, L. J., Thompson, K. N., Zolfo, M., Manghi, P., Dubois, L., Huang, K. D., Thomas, A. M., Nickols, W. A., Piccinno, G., Piperni, E., Pun\u010doch\u00e1\u0159, M., Valles-Colomer, M., Tett, A., Giordano, F., Davies, R., Wolf, J., \u2026 Segata, N. (2023). Extending and improving metagenomic taxonomic profiling with uncharacterized species using MetaPhlAn 4. Nature Biotechnology, 41, 1633\u20131645. 10.1038/s41587-023-01688-w
  • " : "", + ].join(' ').trim() + + def text_diamond = [params.run_diamond ? "
  • Buchfink, B., Reuter, K., & Drost, H.-G. (2021). Sensitive protein alignments at tree-of-life scale using DIAMOND. Nature Methods, 18(4), 366–368. 10.1038/s41592-021-01101-x
  • " : ""].join(' ').trim() + + def text_fmhfunprofiler = [params.run_fmhfunprofiler ? "
  • Hera, M. R., Liu, S., Wei, W., Rodriguez, J. S., Ma, C., & Koslicki, D. (2024). Metagenomic functional profiling: to sketch or not to sketch? Bioinformatics, 40(Suppl 2), ii165–ii173. 10.1093/bioinformatics/btae397
  • " : ""].join(' ').trim() + + def text_mifaser = [ + params.run_mifaser ? "
  • Zhu, C., Miller, M., Marpaka, S., Vaysberg, P., R\u00fchlemann, M. C., Wu, G., Heinsen, F.-A., Tempel, M., Woodhouse, L., Burkhardt, L., Tams, R., Knecht, C., Heinig, M., Franke, A., Huser, T., & Bromberg, Y. (2017). Functional sequencing read annotation for high precision microbiome analysis. Nucleic Acids Research, 46(4), e23. 10.1093/nar/gkx1209
  • " : "", + params.run_mifaser ? "
  • Mahlich, Y., Zhu, C., Chung, H., Velaga, P. K., De Paolis Kaluza, M. C., Radivojac, P., Bromberg, Y. (2023). Learning from the unknown: exploring the range of bacterial functionality. Nucleic Acids Research. 10.1093/nar/gkad757
  • " : "", + params.run_mifaser ? "
  • Zhu, C., Delmont, T. O., Vogel, T. M., & Bromberg, Y. (2015). Functional basis of microorganism classification. PLoS Computational Biology, 11(8), e1004472. 10.1371/journal.pcbi.1004472
  • " : "", + ].join(' ').trim() + + def text_eggnggmapper = [params.run_eggnogmapper ? "
  • Carlos P Cantalapiedra, Ana Hernández-Plaza, Ivica Letunic, Peer Bork, Jaime Huerta-Cepas, eggNOG-mapper v2: Functional Annotation, Orthology Assignments, and Domain Prediction at the Metagenomic Scale, Molecular Biology and Evolution, Volume 38, Issue 12, December 2021, 0.1093/molbev/msab293
  • " : ""].join(' ').trim() + + def text_rgi = [params.run_rgi ? "
  • Alcock et al. 2023. CARD 2023: expanded curation, support for machine learning, and resistome prediction at the Comprehensive Antibiotic Resistance Database. Nucleic Acids Researchpubmed.ncbi.nlm.nih.gov/36263822
  • " : ""].join(' ').trim() + def reference_text = [ - "
  • Andrews S, (2010) FastQC, URL: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/).
  • ", - "
  • Ewels, P., Magnusson, M., Lundin, S., & Käller, M. (2016). MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics , 32(19), 3047–3048. doi: /10.1093/bioinformatics/btw354
  • " - ].join(' ').trim() + text_qc, + text_humann, + text_eggnggmapper, + text_rgi, + text_diamond, + text_fmhfunprofiler, + text_mifaser, + "
  • Ewels, P., Magnusson, M., Lundin, S., & Käller, M. (2016). MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics, 32(19), 3047–3048. 10.1093/bioinformatics/btw354
  • ", + ].join(' ').trim() return reference_text } @@ -228,6 +261,7 @@ def toolBibliographyText() { def methodsDescriptionText(mqc_methods_yaml) { // Convert to a named map so can be used as with familiar NXF ${workflow} variable syntax in the MultiQC YML file def meta = [:] + meta.workflow = workflow.toMap() meta["manifest_map"] = workflow.manifest.toMap() @@ -242,21 +276,21 @@ def methodsDescriptionText(mqc_methods_yaml) { temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " } meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) - } else meta["doi_text"] = "" + } + else { + meta["doi_text"] = "" + } meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " - // Tool references - meta["tool_citations"] = "" - meta["tool_bibliography"] = "" - - // TODO nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! - // meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") - // meta["tool_bibliography"] = toolBibliographyText() + // meta["tool_citations"] = "" + // meta["tool_bibliography"] = "" + meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") + meta["tool_bibliography"] = toolBibliographyText() def methods_text = mqc_methods_yaml.text - def engine = new groovy.text.SimpleTemplateEngine() + def engine = new groovy.text.SimpleTemplateEngine() def description_html = engine.createTemplate(methods_text).make(meta) return description_html.toString() diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index d6e593e..37939ac 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -73,11 +73,23 @@ def getWorkflowVersion() { def dumpParametersToJSON(outdir) { def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') def filename = "params_${timestamp}.json" - def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") - def jsonStr = groovy.json.JsonOutput.toJson(params) + def temp_pf = workflow.launchDir.resolve(".${filename}") + def jsonGenerator = new groovy.json.JsonGenerator.Options() + .excludeNulls() + .addConverter(Path) { Path path -> path.toUriString() } + .addConverter(Duration) { Duration duration -> duration.toMillis() } + .addConverter(MemoryUnit) { MemoryUnit memory -> memory.toBytes() } + .addConverter(nextflow.script.types.VersionNumber) { nextflow.script.types.VersionNumber version -> version.toString() } + .build() + def jsonStr = jsonGenerator.toJson(params) temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - - nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + if (outdir instanceof Path) { + temp_pf.copyTo(outdir.resolve("pipeline_info/${filename}")) + } else if (outdir instanceof String) { + temp_pf.copyTo("${outdir}/pipeline_info/params_${timestamp}.json") + } else { + log.warn("Could not determine type of outdir, parameters JSON file will not be copied to output directory!") + } temp_pf.delete() } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml deleted file mode 100644 index f847611..0000000 --- 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 bfd2587..afca543 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.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test similarity index 100% rename from subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test rename to subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap similarity index 100% rename from subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap rename to subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml deleted file mode 100644 index ac8523c..0000000 --- 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 4994303..9ff0681 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,62 @@ 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 + cli_typecast // boolean: whether to perform typecasting of CLI parameters. Set this to `null` to use the default behaviour 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 << [parameters_schema: parameters_schema] + } + log.info paramsHelp( + help_options, + (help instanceof String && help != "true") ? 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 << [parameters_schema: 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 << [parameters_schema: parameters_schema] + } + if(cli_typecast != null) { + validateOptions << [cast_cli_params: cli_typecast] } + validateParameters(validateOptions) } emit: dummy_emit = true } - diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml index f7d9f02..1d8c75a 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml +++ b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml @@ -25,6 +25,30 @@ input: option. When this input is empty it will automatically use the configured schema or "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way for meta pipelines. + - help: + type: boolean, string + description: | + Show the help message and exit. When a parameter name is given, show the help message for that parameter instead of the general help message. + - help_full: + type: boolean + description: Show the full help message and exit. + - show_hidden: + type: boolean + description: Show hidden parameters in the help message. + - before_text: + type: string + description: Text to show before the parameters summary and help message. + - after_text: + type: string + description: Text to show after the parameters summary and help message. + - command: + type: string + description: An example command to run the pipeline, to show in the help message and the summary. + - cli_typecast: + type: boolean + description: | + Whether to apply typecasting to the parameters given via the CLI before validation. + Set this to `null` to use the default behavior. output: - dummy_emit: type: boolean diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test index 8fb3016..1fd1eac 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,13 @@ 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] = "" + input[9] = null """ } } @@ -51,6 +58,13 @@ 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] = "" + input[9] = null """ } } @@ -77,6 +91,13 @@ 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] = "" + input[9] = null """ } } @@ -103,6 +124,13 @@ 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] = "" + input[9] = null """ } } @@ -114,4 +142,37 @@ 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" + input[9] = null + """ + } + } + + 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 09ef842..fd71cb8 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.4.2" + id "nf-schema@2.7.2" } 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 158c83c..139e1bd 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -1,11 +1,29 @@ .DS_Store multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt -multiqc/multiqc_data/BETA-multiqc.parquet +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 +multiqc/multiqc_data/llms-full.txt +multiqc/multiqc_data/multiqc.parquet fastqc/*_fastqc.{html,zip} pipeline_info/*.{html,json,txt,yml} +**/*.log +**/*.biom +**/*_profile.txt +**/*_genefamilies.tsv.gz +**/*_pathcoverage.tsv.gz +**/*_pathabundance.tsv.gz +**/*_reactions.tsv.gz +**/*bowtie2out.txt +**/*_mapping_data.json +**/*_mapping_data.txt +**/*.seqs.temp.txt +**/*.allele_mapping_data.json +**/*.allele_mapping_data.txt +**/*.gene_mapping_data.json +**/*.gene_mapping_data.txt diff --git a/tests/default.nf.test b/tests/default.nf.test index 637443a..e28fd20 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -3,6 +3,7 @@ nextflow_pipeline { name "Test pipeline" script "../main.nf" tag "pipeline" + profile "test" test("-profile test") { @@ -13,21 +14,19 @@ nextflow_pipeline { } 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_funcprofiler_software_mqc_versions.yml"), + //removeNextflowVersion("$outputDir/pipeline_info/nf_core_funcprofiler_software_mqc_versions.yml"), // All stable path name, with a relative path - stable_name, + stable_path, // All files with stable contents - stable_path + stable_content ).match() } ) } diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap new file mode 100644 index 0000000..34c585e --- /dev/null +++ b/tests/default.nf.test.snap @@ -0,0 +1,101 @@ +{ + "-profile test": { + "content": [ + [ + "cat", + "cat/minigut.merged.fastq.gz", + "fmhfunprofiler", + "fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip", + "fmhfunprofiler/KOs_sketched_scaled_1000_demo.sig.zip/minigut_KOs_sketched_scaled_1000_demo.sig.fmhfunprofiler.csv", + "humann3", + "humann3/minigut.log", + "humann3/minigut_genefamilies.tsv.gz", + "humann3/minigut_pathabundance.tsv.gz", + "humann3/minigut_pathcoverage.tsv.gz", + "mifaser", + "mifaser/minigut_analysis.tsv", + "mifaser/minigut_ec_count.tsv", + "mifaser/minigut_multi_ec.tsv", + "mpahumann3", + "mpahumann3/minigut.biom", + "mpahumann3/minigut.bowtie2out.txt", + "mpahumann3/minigut_profile.txt", + "pipeline_info", + "pipeline_info/nf_core_funcprofiler_software_mqc_versions.yml", + "rgi", + "rgi/4.0.1", + "rgi/4.0.1/minigut.allele_mapping_data.json", + "rgi/4.0.1/minigut.allele_mapping_data.txt", + "rgi/4.0.1/minigut.artifacts_mapping_stats.txt", + "rgi/4.0.1/minigut.coverage.temp.txt", + "rgi/4.0.1/minigut.coverage_all_positions.summary.temp.txt", + "rgi/4.0.1/minigut.coverage_all_positions.temp.txt", + "rgi/4.0.1/minigut.gene_mapping_data.txt", + "rgi/4.0.1/minigut.overall_mapping_stats.txt", + "rgi/4.0.1/minigut.reference_mapping_stats.txt", + "rgi/4.0.1/minigut.seqs.temp.txt", + "rgi/4.0.1/minigut.temp.txt", + "rgi/card_database_processed", + "rgi/card_database_processed/CARD-Download-README.txt", + "rgi/card_database_processed/PMID.tsv", + "rgi/card_database_processed/aro_categories.tsv", + "rgi/card_database_processed/aro_categories_index.tsv", + "rgi/card_database_processed/aro_index.tsv", + "rgi/card_database_processed/card.json", + "rgi/card_database_processed/card_database_v4.0.1.fasta", + "rgi/card_database_processed/card_database_v4.0.1_all.fasta", + "rgi/card_database_processed/nucleotide_fasta_protein_homolog_model.fasta", + "rgi/card_database_processed/nucleotide_fasta_protein_knockout_model.fasta", + "rgi/card_database_processed/nucleotide_fasta_protein_overexpression_model.fasta", + "rgi/card_database_processed/nucleotide_fasta_protein_variant_model.fasta", + "rgi/card_database_processed/nucleotide_fasta_rRNA_gene_variant_model.fasta", + "rgi/card_database_processed/protein_fasta_protein_homolog_model.fasta", + "rgi/card_database_processed/protein_fasta_protein_knockout_model.fasta", + "rgi/card_database_processed/protein_fasta_protein_overexpression_model.fasta", + "rgi/card_database_processed/protein_fasta_protein_variant_model.fasta", + "rgi/card_database_processed/shortname_antibiotics.tsv", + "rgi/card_database_processed/shortname_pathogens.tsv", + "rgi/card_database_processed/snps.txt" + ], + [ + "minigut.merged.fastq.gz:md5,1fbae8f5fe6fdfa6552cfca32d9c3129", + "minigut_KOs_sketched_scaled_1000_demo.sig.fmhfunprofiler.csv:md5,1081039ab9e9b378d2dfd3206e96e917", + "minigut_analysis.tsv:md5,1cda8e4b88a34f56539d04cc2dac0914", + "minigut_ec_count.tsv:md5,5c2306e908a487f57d70da9b4f131217", + "minigut_multi_ec.tsv:md5,915713718d7b6fabc3fbc3a1286999e0", + "minigut.artifacts_mapping_stats.txt:md5,26b4346ac5367d575ab67f9246e8ca08", + "minigut.coverage.temp.txt:md5,8fa9ceb6c1f02bdcd89472c2523a775a", + "minigut.coverage_all_positions.summary.temp.txt:md5,9d93d7e96faf94c18f637a02ef1cebf2", + "minigut.coverage_all_positions.temp.txt:md5,fd6083d850435153d3678aa5c387fdc2", + "minigut.overall_mapping_stats.txt:md5,7a66e3f185702925bef3873f356072ff", + "minigut.reference_mapping_stats.txt:md5,986084fa8f72769b0e8a8827ce84f138", + "minigut.temp.txt:md5,e8510289eeb0be3d0e25faaef0c43116", + "CARD-Download-README.txt:md5,b57364cc1a5fab0541e13a01fabe5dea", + "PMID.tsv:md5,e3ce79c4b5dcf0a9e3117ed683f96e54", + "aro_categories.tsv:md5,6f9c4b0410b9e2b3cf5867a2a3f1db07", + "aro_categories_index.tsv:md5,d5fbc673c0de6601b07c8016b3909f8e", + "aro_index.tsv:md5,0f183c7869876fa32c8f86aade0df7b5", + "card.json:md5,72156d00155f69e637664bfb5d3b5395", + "card_database_v4.0.1.fasta:md5,5ead0b239c312ebb068a3b5aa9676b2d", + "card_database_v4.0.1_all.fasta:md5,f389ce15fac30e9ab394ca8a49f6451f", + "nucleotide_fasta_protein_homolog_model.fasta:md5,696d1aa4f04bd08fc4bdeea33ab9db43", + "nucleotide_fasta_protein_knockout_model.fasta:md5,d8224ce019ad69a041d83ccf7877b4e0", + "nucleotide_fasta_protein_overexpression_model.fasta:md5,80a1e7957c79d311446e06c6dd49db8e", + "nucleotide_fasta_protein_variant_model.fasta:md5,7450e559045c9d1d8f13c73054c64f4c", + "nucleotide_fasta_rRNA_gene_variant_model.fasta:md5,bd53f46d630f652c9f6b7584c2126e1f", + "protein_fasta_protein_homolog_model.fasta:md5,36ea300133fd7c5a45de2fee4c5050bf", + "protein_fasta_protein_knockout_model.fasta:md5,f16667df70d1a5f910d3ae45f5250c3d", + "protein_fasta_protein_overexpression_model.fasta:md5,723e8762be5c96aed8c379a6499cecee", + "protein_fasta_protein_variant_model.fasta:md5,8c02d8fc84c9a90953f8534355244019", + "shortname_antibiotics.tsv:md5,9a4ba742fd8a3a49c7f50744001a4129", + "shortname_pathogens.tsv:md5,5211712be4f4c3306cbe4052cafae1d7", + "snps.txt:md5,529d4fdb74c8940c0930ec1a7a6d4980" + ] + ], + "timestamp": "2026-07-31T09:50:44.24986845", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + } +} \ No newline at end of file diff --git a/tests/nextflow.config b/tests/nextflow.config index 73e92d1..cbac3c9 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -4,11 +4,51 @@ ======================================================================================== */ -// 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/' - pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/funcprofiler' + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' + publish_dir_mode = 'copy' + run_diamond = false + } +cleanup = false + aws.client.anonymous = true // fixes S3 access issues on self-hosted runners + + +process { + + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'FASTQC' { + ext.when = false + } + withName: 'MULTIQC' { + ext.when = false + } + withName: 'HUMANN3_REGROUP' { + ext.when = false + } + withName: 'HUMANN4_REGROUP' { + ext.when = false + } + + withName: HUMANN3 { + publishDir = [ + path: { "${params.outdir}/humann3/" }, + mode: params.publish_dir_mode, + pattern: '*.{tsv.gz,log,.command.*}' + ] + ext.args = "--bypass-nucleotide-search" // no reads proceed to translated search with some test data + } + withName: HUMANN4 { + ext.when = false + } +} +// Fixes S3 access issues on self-hosted runners +aws.client.anonymous = true diff --git a/workflows/funcprofiler.nf b/workflows/funcprofiler.nf index 18a9ad8..b5f6698 100644 --- a/workflows/funcprofiler.nf +++ b/workflows/funcprofiler.nf @@ -3,95 +3,131 @@ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { FASTQC } from '../modules/nf-core/fastqc/main' -include { MULTIQC } from '../modules/nf-core/multiqc/main' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_funcprofiler_pipeline' + + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -workflow FUNCPROFILER { + + +// +// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules +// + + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT NF-CORE MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// MODULE: Installed directly from nf-core/modules +// +include { UNTAR } from '../modules/nf-core/untar/main' +include { PROFILE } from '../subworkflows/local/profile/main' +include { DATAPREP } from '../subworkflows/local/dataprep/main' +include { DBPREP } from '../subworkflows/local/dbprep/main' + + + + +workflow FUNCPROFILER { take: - ch_samplesheet // channel: samplesheet read in from --input + samplesheet // channel: samplesheet read in from --input + databases // channel: databases from --databases + multiqc_config + multiqc_logo + multiqc_methods_description + outdir + main: ch_versions = Channel.empty() ch_multiqc_files = Channel.empty() - // - // MODULE: Run FastQC - // - FASTQC ( - ch_samplesheet + + DATAPREP( + samplesheet + ) + + DBPREP( + databases + ) + PROFILE( + DATAPREP.out.reads, + DATAPREP.out.reads_concat, + DBPREP.out.dbs, ) - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}) - ch_versions = ch_versions.mix(FASTQC.out.versions.first()) // // Collate and save software versions // - softwareVersionsToYAML(ch_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", - name: 'nf_core_' + 'funcprofiler_software_' + 'mqc_' + 'versions.yml', + storeDir: "${outdir}/pipeline_info", + name: 'nf_core_' + 'funcprofiler_software_' + 'mqc_' + 'versions.yml', sort: true, - newLine: true - ).set { ch_collated_versions } - + newLine: true, + ) // // MODULE: MultiQC // - ch_multiqc_config = Channel.fromPath( - "$projectDir/assets/multiqc_config.yml", checkIfExists: true) - ch_multiqc_custom_config = params.multiqc_config ? - Channel.fromPath(params.multiqc_config, checkIfExists: true) : - Channel.empty() - ch_multiqc_logo = params.multiqc_logo ? - Channel.fromPath(params.multiqc_logo, checkIfExists: true) : - Channel.empty() - - summary_params = paramsSummaryMap( - workflow, parameters_schema: "nextflow_schema.json") - ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) - ch_multiqc_files = ch_multiqc_files.mix( - ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - ch_multiqc_custom_methods_description = params.multiqc_methods_description ? - file(params.multiqc_methods_description, checkIfExists: true) : - file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) - ch_methods_description = Channel.value( - methodsDescriptionText(ch_multiqc_custom_methods_description)) - ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) - ch_multiqc_files = ch_multiqc_files.mix( - ch_methods_description.collectFile( - name: 'methods_description_mqc.yaml', - sort: true - ) - ) - - MULTIQC ( - ch_multiqc_files.collect(), - ch_multiqc_config.toList(), - ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList(), - [], - [] + def ch_summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") + def ch_workflow_summary = channel.value(paramsSummaryMultiqc(ch_summary_params)) + ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + def ch_multiqc_custom_methods_description = multiqc_methods_description + ? file(multiqc_methods_description, checkIfExists: true) + : file("${projectDir}/assets/methods_description_template.yml", checkIfExists: true) + def ch_methods_description = channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) + ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml', sort: true)) + MULTIQC( + ch_multiqc_files.flatten().collect().map { files -> + [ + [id: 'funcprofiler'], + files, + multiqc_config + ? file(multiqc_config, checkIfExists: true) + : file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true), + multiqc_logo ? file(multiqc_logo, checkIfExists: true) : [], + [], + [], + ] + } ) - emit:multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html - versions = ch_versions // channel: [ path(versions.yml) ] - + emit: + multiqc_report = MULTIQC.out.report.map { _meta, report -> [report] }.toList() // channel: /path/to/multiqc_report.html + versions = ch_versions // channel: [ path(versions.yml) ] } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/