diff --git a/.github/actions/nf-test/action.yml b/.github/actions/nf-test/action.yml index 4175e3c..d5c04a1 100644 --- a/.github/actions/nf-test/action.yml +++ b/.github/actions/nf-test/action.yml @@ -43,6 +43,9 @@ runs: 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 @@ -53,7 +56,7 @@ runs: auto-update-conda: true conda-solver: libmamba channels: conda-forge - channel-priority: strict + channel-priority: flexible conda-remove-defaults: true - name: Run nf-test diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 91f761d..4f60919 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -24,7 +24,6 @@ jobs: - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@51565b514bff1827cf34620de25d0055759f1fc9 # v2 - # TODO nf-core: You can customise AWS full pipeline tests as required # Add full size test data (but still relatively small datasets for few samples) # on the `test_full.config` test runs with only one set of parameters with: diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 277f12f..f25e608 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -67,7 +67,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: linting-logs path: | diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index e363215..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.4" + NFT_VER: "0.9.5" NFT_WORKDIR: "~" NXF_ANSI_LOG: false NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity @@ -50,7 +50,7 @@ jobs: env: NFT_VER: ${{ env.NFT_VER }} with: - max_shards: 7 + max_shards: 19 - name: debug run: | @@ -68,13 +68,11 @@ 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: @@ -100,7 +98,19 @@ jobs: 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: | diff --git a/.gitignore b/.gitignore index cc2b1a7..393cd5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,12 @@ testing/ testing* *.pyc null/ +*~ +.nf-test/ +.nf-test.log +dontcommit +tmp/ +.data/ +*.code-workspace .lineage/ +conf/tmp.config diff --git a/.nf-core.yml b/.nf-core.yml index 734987f..8ceb31e 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -7,6 +7,7 @@ lint: - .gitignore nf_core_version: 4.1.0 repository_type: pipeline + template: author: Nick Waters, Vini Salazar, Yixuan Yang, Mirae Baichoo description: Read-based functional profiling of microbiome sequencing data diff --git a/CHANGELOG.md b/CHANGELOG.md index a84f032..1d93637 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Initial release of nf-core/funcprofiler, created with the [nf-core](https://nf-co.re/) template. +Read-based functional profiling of short-read microbiome sequencing data with the following profilers, all off by default and each enabled with its own `--run_` flag: + +- [HUMAnN](https://huttenhower.sph.harvard.edu/humann/) v3 and v4, each preceded by a [MetaPhlAn](https://github.com/biobakery/MetaPhlAn) taxonomic prescreen and followed by `humann_regroup_table` +- [FMH FunProfiler](https://github.com/KoslickiLab/fmh-funprofiler) +- [mi-faser](https://bromberglab.org/project/mifaser/) +- [RGI](https://github.com/arpcard/rgi) `bwt`, against CARD +- [DIAMOND](https://github.com/bbuchfink/diamond) `blastx` (beta) +- [eggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) (beta) + +This release performs no read QC or preprocessing; reads are expected to arrive already trimmed, quality filtered and host decontaminated. +Long-read platforms are not supported. + ### `Added` ### `Fixed` diff --git a/CITATIONS.md b/CITATIONS.md index 5f71d8d..7faf7a8 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -10,14 +10,56 @@ ## Pipeline tools -- [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) + -> Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. +- [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. + +- [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 c38fb7e..5109d6e 100644 --- a/README.md +++ b/README.md @@ -21,48 +21,63 @@ ## 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 already preprocessed short-read 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. Long-read platforms are not supported in this release. - +### 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/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. - +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_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] @@ -82,7 +97,9 @@ nf-core/funcprofiler was originally written by Nick Waters, Vini Salazar, Yixuan 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 @@ -92,11 +109,8 @@ For further information or help, don't hesitate to get in touch on the [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/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/nf-core-funcprofiler_logo_light.png b/assets/nf-core-funcprofiler_logo_light.png index fe1d759..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..3902fdd --- /dev/null +++ b/assets/nf-metro_command.sh @@ -0,0 +1,8 @@ +# --x-spacing 110 is load-bearing: the layout was tuned at that spacing. +# The committed SVGs also carry manual geometry corrections that nf-metro has no +# directive for (the 'Short reads' caption re-anchored clear of the exit port, +# the database bundle and report lane routed below the reads trunk, the two file +# icons centred in their section boxes), so a plain re-render will not reproduce +# them byte-for-byte. +nf-metro render pipeline.mmd -o pipeline_light.svg --logo nf-core-funcprofiler_logo_light.png --theme light --animate --x-spacing 110 +nf-metro render pipeline.mmd -o pipeline_nf-core.svg --logo nf-core-funcprofiler_logo_light.png --theme nfcore --animate --x-spacing 110 diff --git a/assets/pipeline.mmd b/assets/pipeline.mmd new file mode 100644 index 0000000..69f8ed3 --- /dev/null +++ b/assets/pipeline.mmd @@ -0,0 +1,140 @@ +%%metro title: nf-core/funcprofiler +%%metro logo: nf-core-funcprofiler_logo_light.png +%%metro line_spread: bundle + + +%% One line per input type, as on the nf-core/taxprofiler tube map: the tool a +%% route ends at is already named by the station it stops at. Blue stops at +%% 'merge & concat' and green carries everything downstream of it, RGI included. +%% That is a deliberate simplification: RGI is actually fed the unconcatenated +%% reads (subworkflows/local/profile/main.nf:41 builds its channel from 'reads' +%% with singleFqTool = false, every other tool from 'reads_concat'), but drawing +%% that ran a second blue strand through the profiling block for one tool. +%%metro line: shortread | Short reads | #1B7FC4 +%%metro line: concat | Concatenated reads | #14795A +%% The reports branch. Orange so the split at the results junction reads as two +%% different things leaving it, not one bundle drawn twice. It runs from every +%% profiler, not just from the junction: that is what MultiQC actually collates, +%% and it is also what lifts the junction onto the top lane, level with Output. +%% A junction station otherwise centres on the mean row of its inputs, which +%% with seven profiler lanes is three rows down; giving it a line that reaches a +%% row-0 station pulls it up. +%%metro line: report | Summary statistics | #E8871A +%% Three strands so the databases read as a bundle, as on the taxprofiler map. +%% Three hues of the same purple, not three different colours: they are one +%% thing. legend_combo collapses them into one striped legend row. +%%metro line: db | Databases | #6D3F9E +%%metro line: db2 | Databases | #A263C9 +%%metro line: db3 | Databases | #C89BE0 +%%metro legend_combo: db, db2, db3 | Databases + +%%metro marker_legend: circle, open | Opt-in +%%metro marker_legend: circle, #333333 | Runs by default + +%% Filled markers take the colour of the line they sit on rather than a flat +%% #333333, so the dot reads as part of its route. +%%metro marker: prep | circle, #1B7FC4 +%%metro marker: multiqc | circle, #E8871A +%%metro marker: hub | circle, #14795A +%%metro marker: results | circle, #14795A + +%%metro files: input_reads | fastq | Short reads | banner +%%metro files: input_dbs | db | Databases | banner +%%metro file: out_tables | tsv | Abundance tables | banner + +%% Three grid rows, with Functional profiling spanning all three. Input is on +%% row 0 level with the top of profiling and Run merging directly beneath it +%% on row 1; Summary statistics shares row 1, under Output. The third row +%% is what puts Run merging where it belongs: a spanning section dumps its +%% leftover height into the row above the last one it occupies, so with only two +%% rows the whole slack landed between Input and Run merging and pushed +%% Run merging to the bottom of the canvas. +%%metro grid: input | 0,0 +%%metro grid: merging | 0,1 +%%metro grid: profiling | 1,0,3 +%%metro grid: qc | 2,1 +%%metro grid: output | 2,0 + +graph LR + subgraph input[Input] + %% TB is what makes the drop into Run merging a single straight line: + %% the exit port moves to the bottom of the icon instead of its right + %% edge, so the route never has to cross this section's boundary + %% sideways. It does put the 'Short reads' caption under the port + %% circle, which a post-render pass moves to the icon's top right. + %%metro direction: TB + %%metro exit: bottom | shortread + input_reads([Short reads]) + end + + subgraph merging[Run merging] + %% Entry hint only. Without it blue U-turns around this section. An + %% explicit '%%metro exit:' on Input changes nothing: the descent still + %% steps 10px sideways where it crosses this section's top edge, because + %% the route leaves Input at the section boundary (x=207) and the entry + %% port sits at the inset (x=197). + %%metro entry: top | shortread + prep(merge & concat) + end + + subgraph profiling[Functional profiling] + input_dbs([Databases]) + hub(( )) + %% RGI first: it is the only station the paired line reaches, and a + %% branching line declared later strikes through the labels above it. + rgi(RGI) + metaphlan3(MetaPhlAn) + humann3(HUMAnN v3) + metaphlan4(MetaPhlAn) + humann4(HUMAnN v4) + eggnog(eggNOG-mapper) + fmhfunprofiler(FMH FunProfiler) + mifaser(mi-faser) + diamond(DIAMOND) + %% Unnamed junction: the seven profiler outputs join here, and the split + %% to the tables and to MultiQC happens once instead of seven times. + results(( )) + end + + subgraph qc[Summary statistics] + multiqc(MultiQC) + end + + subgraph output[Output] + out_tables([Abundance tables]) + end + + %% Runs of one sample are merged first, and the map then treats every + %% profiler as reading the concatenated FASTQ. See the note on the lines. + input_reads -->|shortread| prep + prep -->|concat| hub + hub -->|concat| rgi + + hub -->|concat| metaphlan3 + hub -->|concat| metaphlan4 + hub -->|concat| eggnog + hub -->|concat| fmhfunprofiler + hub -->|concat| mifaser + hub -->|concat| diamond + + metaphlan3 -->|concat| humann3 + metaphlan4 -->|concat| humann4 + + %% The database bundle terminates at the hub. It does not continue into the + %% profiler lanes: the hub is where the databases are handed over. + input_dbs -->|db,db2,db3| hub + + %% Results leave the profilers as one bundle and split at the section edge. + rgi -->|concat,report| results + humann3 -->|concat,report| results + humann4 -->|concat,report| results + eggnog -->|concat,report| results + fmhfunprofiler -->|concat,report| results + mifaser -->|concat,report| results + diamond -->|concat,report| results + + %% Two branches off the junction: tables on green, run statistics on orange. + %% Orange reaches the junction from each profiler above, so the junction is + %% a real interchange rather than the point where the reports appear. + results -->|concat| out_tables + results -->|report| multiqc diff --git a/assets/pipeline_light.svg b/assets/pipeline_light.svg new file mode 100644 index 0000000..0e1435f --- /dev/null +++ b/assets/pipeline_light.svg @@ -0,0 +1,213 @@ + + + + +{"groups":[{"color":"#1B7FC4","id":"shortread","label":"Short reads"},{"color":"#14795A","id":"concat","label":"Concatenated reads"},{"color":"#E8871A","id":"report","label":"Summary statistics"},{"color":"#6D3F9E","id":"db","label":"Databases"},{"color":"#A263C9","id":"db2","label":"Databases"},{"color":"#C89BE0","id":"db3","label":"Databases"}],"height":749,"match":{"flags":"i","target":"fqProcessName","type":"regex"},"nodes":[{"groups":["shortread"],"h":12.0,"id":"input_reads","label":"Short reads","patterns":[],"r":6.0,"region":"input","rx":6.0,"w":12.0,"x":207.0,"y":116.8},{"groups":["concat","shortread"],"h":12.0,"id":"prep","label":"merge & concat","patterns":[],"r":6.0,"region":"merging","rx":6.0,"w":12.0,"x":262.0,"y":294.8},{"groups":["db","db2","db3"],"h":20.0,"id":"input_dbs","label":"Databases","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":410.0,"y":179.2},{"groups":["concat","db","db2","db3"],"h":28.0,"id":"hub","label":"hub","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":586.0,"y":124.8},{"groups":["concat","report"],"h":16.0,"id":"rgi","label":"RGI","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":130.8},{"groups":["concat"],"h":12.0,"id":"metaphlan3","label":"MetaPhlAn","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":424.8},{"groups":["concat","report"],"h":16.0,"id":"humann3","label":"HUMAnN v3","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":872.0,"y":422.8},{"groups":["concat"],"h":12.0,"id":"metaphlan4","label":"MetaPhlAn","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":483.2},{"groups":["concat","report"],"h":16.0,"id":"humann4","label":"HUMAnN v4","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":872.0,"y":481.2},{"groups":["concat","report"],"h":16.0,"id":"eggnog","label":"eggNOG-mapper","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":189.2},{"groups":["concat","report"],"h":16.0,"id":"fmhfunprofiler","label":"FMH FunProfiler","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":247.6},{"groups":["concat","report"],"h":16.0,"id":"mifaser","label":"mi-faser","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":306.0},{"groups":["concat","report"],"h":16.0,"id":"diamond","label":"DIAMOND","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":762.0,"y":364.4},{"groups":["concat","report"],"h":16.0,"id":"results","label":"results","patterns":[],"r":6.0,"region":"profiling","rx":6.0,"w":12.0,"x":1048.0,"y":130.8},{"groups":["report"],"h":12.0,"id":"multiqc","label":"MultiQC","patterns":[],"r":6.0,"region":"qc","rx":6.0,"w":12.0,"x":1253.0,"y":294.8},{"groups":["concat"],"h":12.0,"id":"out_tables","label":"Abundance tables","patterns":[],"r":6.0,"region":"output","rx":6.0,"w":12.0,"x":1279.0,"y":132.8}],"regions":[{"id":"input","label":"Input"},{"id":"merging","label":"Run merging"},{"id":"profiling","label":"Functional profiling"},{"id":"qc","label":"Summary statistics"},{"id":"output","label":"Output"}],"title":"nf-core/funcprofiler","version":"1.0","width":1415} + + + + +1 + + + +2 + + + +3 + + + +5 + + + +4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +fastq +Short reads + + + + + + + + + + + + + + + +db +Databases + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +tsv +Abundance tables + + + +merge & concat + +MultiQC + +RGI + +eggNOG-mapper + +FMH FunProfiler + +mi-faser + +DIAMOND + +MetaPhlAn + +MetaPhlAn + +HUMAnN v3 + +HUMAnN v4 + + + +Short reads + +Concatenated reads + +Summary statistics + + + +Databases + +Opt-in + +Runs by default +created with nf-metro v1.1.0 + diff --git a/assets/pipeline_nf-core.svg b/assets/pipeline_nf-core.svg new file mode 100644 index 0000000..659d39f --- /dev/null +++ b/assets/pipeline_nf-core.svg @@ -0,0 +1,209 @@ + + + + +{"groups":[{"color":"#1B7FC4","id":"shortread","label":"Short reads"},{"color":"#14795A","id":"concat","label":"Concatenated reads"},{"color":"#E8871A","id":"report","label":"Summary statistics"},{"color":"#6D3F9E","id":"db","label":"Databases"},{"color":"#A263C9","id":"db2","label":"Databases"},{"color":"#C89BE0","id":"db3","label":"Databases"}],"height":749,"match":{"flags":"i","target":"fqProcessName","type":"regex"},"nodes":[{"groups":["shortread"],"h":10.0,"id":"input_reads","label":"Short reads","patterns":[],"r":5.0,"region":"input","rx":5.0,"w":10.0,"x":207.0,"y":116.8},{"groups":["concat","shortread"],"h":10.0,"id":"prep","label":"merge & concat","patterns":[],"r":5.0,"region":"merging","rx":5.0,"w":10.0,"x":262.0,"y":294.8},{"groups":["db","db2","db3"],"h":18.0,"id":"input_dbs","label":"Databases","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":410.0,"y":179.2},{"groups":["concat","db","db2","db3"],"h":26.0,"id":"hub","label":"hub","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":586.0,"y":124.8},{"groups":["concat","report"],"h":14.0,"id":"rgi","label":"RGI","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":130.8},{"groups":["concat"],"h":10.0,"id":"metaphlan3","label":"MetaPhlAn","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":424.8},{"groups":["concat","report"],"h":14.0,"id":"humann3","label":"HUMAnN v3","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":872.0,"y":422.8},{"groups":["concat"],"h":10.0,"id":"metaphlan4","label":"MetaPhlAn","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":483.2},{"groups":["concat","report"],"h":14.0,"id":"humann4","label":"HUMAnN v4","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":872.0,"y":481.2},{"groups":["concat","report"],"h":14.0,"id":"eggnog","label":"eggNOG-mapper","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":189.2},{"groups":["concat","report"],"h":14.0,"id":"fmhfunprofiler","label":"FMH FunProfiler","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":247.6},{"groups":["concat","report"],"h":14.0,"id":"mifaser","label":"mi-faser","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":306.0},{"groups":["concat","report"],"h":14.0,"id":"diamond","label":"DIAMOND","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":762.0,"y":364.4},{"groups":["concat","report"],"h":14.0,"id":"results","label":"results","patterns":[],"r":5.0,"region":"profiling","rx":5.0,"w":10.0,"x":1048.0,"y":130.8},{"groups":["report"],"h":10.0,"id":"multiqc","label":"MultiQC","patterns":[],"r":5.0,"region":"qc","rx":5.0,"w":10.0,"x":1253.0,"y":294.8},{"groups":["concat"],"h":10.0,"id":"out_tables","label":"Abundance tables","patterns":[],"r":5.0,"region":"output","rx":5.0,"w":10.0,"x":1279.0,"y":132.8}],"regions":[{"id":"input","label":"Input"},{"id":"merging","label":"Run merging"},{"id":"profiling","label":"Functional profiling"},{"id":"qc","label":"Summary statistics"},{"id":"output","label":"Output"}],"title":"nf-core/funcprofiler","version":"1.0","width":1415} + + + + +1 + + + +2 + + + +3 + + + +5 + + + +4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +fastq +Short reads + + + + + + + + + + + + + + + +db +Databases + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +tsv +Abundance tables + + + +merge & concat + +MultiQC + +RGI + +eggNOG-mapper + +FMH FunProfiler + +mi-faser + +DIAMOND + +MetaPhlAn + +MetaPhlAn + +HUMAnN v3 + +HUMAnN v4 + + + +Short reads + +Concatenated reads + +Summary statistics + + + +Databases + +Opt-in + +Runs by default +created with nf-metro v1.1.0 + diff --git a/assets/schema_database.json b/assets/schema_database.json new file mode 100644 index 0000000..1937796 --- /dev/null +++ b/assets/schema_database.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/nf-core/funcprofiler/main/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+$", + "help_text": "Name of the database as a whole, i.e. the release or version you want recorded in the results (e.g. `uniref90_v3`). All rows belonging to the same database must share this name.", + "errorMessage": "A 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" + ], + "help_text": "Name of the individual component (entity) of the database given in `db_name`. Tools that take a single database file or directory leave this empty; tools that need several components require one row per component, all sharing the same `db_name`. HUMAnN needs `humann_metaphlan`, `humann_nucleotide`, `humann_protein` and `humann_utility`; eggNOG-mapper needs `eggnogmapper_db` and `eggnogmapper_data_dir`.", + "errorMessage": "Invalid db_entity. For HUMAnN, specify whether db_path is the humann_metaphlan, humann_nucleotide, humann_protein or humann_utility component; for eggnogmapper, specify eggnogmapper_db or eggnogmapper_data_dir. Leave empty for tools that take a single database.", + "meta": ["db_entity"] + }, + "db_params": { + "type": "string", + "pattern": "^[^\"']*$", + "errorMessage": "Invalid database db_params entry. No quotes allowed.", + "meta": ["db_params"] + }, + "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..1cf6b5a 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -8,26 +8,59 @@ "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" + ], + "errorMessage": "Sequencing platform must be provided. Long-read platforms (OXFORD_NANOPORE, PACBIO_SMRT) are not supported." + }, "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": "FastA input is not supported by nf-core/funcprofiler. The column is accepted for compatibility with nf-core/taxprofiler samplesheets, but must be left empty." } }, - "required": ["sample", "fastq_1"] - } + "required": ["sample", "run_accession", "instrument_platform", "fastq_1"] + }, + "allOf": [ + { "uniqueEntries": ["fastq_1"] }, + { "uniqueEntries": ["fastq_2"] }, + { "uniqueEntries": ["fasta"] }, + { "uniqueEntries": ["sample", "run_accession"] } + ] } diff --git a/conf/base.config b/conf/base.config index f61c036..49af73f 100644 --- a/conf/base.config +++ b/conf/base.config @@ -10,7 +10,6 @@ process { - // TODO nf-core: Check the defaults for all processes cpus = { 1 * task.attempt } memory = { 6.GB * task.attempt } time = { 4.h * task.attempt } @@ -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 } diff --git a/conf/containers_conda_lock_files_amd64.config b/conf/containers_conda_lock_files_amd64.config index df04a4b..dbe98ea 100644 --- a/conf/containers_conda_lock_files_amd64.config +++ b/conf/containers_conda_lock_files_amd64.config @@ -1,2 +1,2 @@ -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 index 7ed29f3..425f943 100644 --- a/conf/containers_conda_lock_files_arm64.config +++ b/conf/containers_conda_lock_files_arm64.config @@ -1,2 +1,2 @@ -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 index a66e3d1..70e7784 100644 --- a/conf/containers_docker_amd64.config +++ b/conf/containers_docker_amd64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'community.wave.seqera.io/library/fastqc:0.12.1--5cb1a2fa2f18c7c2' } } process { withName: 'MULTIQC' { container = 'community.wave.seqera.io/library/multiqc:1.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 index 215f686..a3063f4 100644 --- a/conf/containers_docker_arm64.config +++ b/conf/containers_docker_arm64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'community.wave.seqera.io/library/fastqc:0.12.1--e455e32f745abe68' } } process { withName: 'MULTIQC' { container = 'community.wave.seqera.io/library/multiqc:1.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 index 2fb11a3..86f4d30 100644 --- a/conf/containers_singularity_https_amd64.config +++ b/conf/containers_singularity_https_amd64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f2/f20b021476d1d87658820f971ebecc1e8cdbde0f338eb0d9cea2b0a8fc54a54b/data' } } process { withName: 'MULTIQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/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 index 5fa5b4f..4e53bf6 100644 --- a/conf/containers_singularity_https_arm64.config +++ b/conf/containers_singularity_https_arm64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/46/46daf2dad0169afd2ae047c3e50ed3776259f664bf07e5e06b045dc23449e994/data' } } process { withName: 'MULTIQC' { container = 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/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 index b334375..d2235d0 100644 --- a/conf/containers_singularity_oras_amd64.config +++ b/conf/containers_singularity_oras_amd64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'oras://community.wave.seqera.io/library/fastqc:0.12.1--5c4bd442468d75dd' } } process { withName: 'MULTIQC' { container = 'oras://community.wave.seqera.io/library/multiqc:1.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 index 661c656..9a0d1f1 100644 --- a/conf/containers_singularity_oras_arm64.config +++ b/conf/containers_singularity_oras_arm64.config @@ -1,2 +1,2 @@ -process { withName: 'FASTQC' { container = 'oras://community.wave.seqera.io/library/fastqc:0.12.1--127a87fc06499035' } } process { withName: 'MULTIQC' { container = 'oras://community.wave.seqera.io/library/multiqc:1.35--c0468833d65b2f81' } } +process { withName: 'RGI_BWT' { container = 'oras://community.wave.seqera.io/library/rgi_kma:a6eaadaaffbeaf85' } } diff --git a/conf/modules.config b/conf/modules.config index d4e90be..055e5dc 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -18,10 +18,67 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - 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 not published: 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 = [ @@ -29,5 +86,4 @@ process { mode: params.publish_dir_mode ] } - } diff --git a/conf/test.config b/conf/test.config index 9f7ea72..ab28367 100644 --- a/conf/test.config +++ b/conf/test.config @@ -16,15 +16,42 @@ process { memory: '15.GB', time: '1.h' ] + + // MultiQC has no per-sample modules to report on here: the pipeline runs no read QC, so + // the report only carries the run summary and the software versions. + withName: 'MULTIQC' { + ext.when = false + } + + // The regroup steps add several minutes per sample for output the test does not check. + withName: 'HUMANN3_REGROUP' { + ext.when = false + } + withName: 'HUMANN4_REGROUP' { + ext.when = false + } + + // No read of the demo data proceeds to translated search against the demo UniRef database + withName: 'HUMANN3_HUMANN' { + ext.args = '--bypass-nucleotide-search' + } } +// rgi (505 MB) and metaphlan (976 MB) come from depot.galaxyproject.org, which is slow enough +// under CI concurrency that the 20 min default kills the pull mid-download. +apptainer.pullTimeout = '60m' +singularity.pullTimeout = '60m' + 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..cb32d32 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -10,15 +10,23 @@ ---------------------------------------------------------------------------------------- */ -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' +// rgi and metaphlan come from depot.galaxyproject.org, which is slow enough that the 20 min +// default kills the pull mid-download. +apptainer.pullTimeout = '60m' +singularity.pullTimeout = '60m' - // Genome references - genome = 'R64-1-1' +params { + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' + input = params.pipelines_testdata_base_path + 'funcprofiler/samplesheets/test_full.csv' + databases = params.pipelines_testdata_base_path + 'funcprofiler/database_full.csv' + run_fmhfunprofiler = true + run_humann_v3 = false // disabled until a good hosting solution can be found for indexed mpa database + run_rgi = true + run_mifaser = true + // DIAMOND and eggNOG-mapper are off because they are still beta and have no full-size + // database in `database_full.csv`; turn them on once one is staged on S3. + run_diamond = false + run_eggnogmapper = false + run_humann_v4 = false } diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 30309b6..95b80c6 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -182,4 +182,9 @@ If you update images or graphics, follow the nf-core [style guidelines](https:// ## 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 764bc28..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 80aea4f..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 6434d7a..4ff95ff 100644 --- a/docs/output.md +++ b/docs/output.md @@ -2,35 +2,130 @@ ## Introduction -This document describes the output produced by the pipeline. Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline. +This document describes the output produced by the pipeline. +Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline. -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. - - +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 +- [HUMAnN v3 / v4](#humann-v3--v4) - Functional profiling via MetaPhlAn + HUMAnN +- [FMH FunProfiler](#fmh-funprofiler) - Sketch-based functional profiling +- [mi-faser](#mi-faser) - Read-level functional profiling +- [RGI BWT](#rgi-bwt) - Antimicrobial resistance gene identification +- [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) - [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution -### FastQC +> [!NOTE] +> Other than MultiQC and pipeline information, all other steps (the profilers) are off by default, and must be switched on manually. The pipeline performs no read QC or preprocessing; see the [usage documentation](https://nf-co.re/funcprofiler/usage) for why. + +### 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.
Output files -- `fastqc/` - - `*_fastqc.html`: FastQC report containing quality metrics. - - `*_fastqc.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. +- `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.
-[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/). +### FMH FunProfiler + +[FMH FunProfiler](https://github.com/KoslickiLab/fmh-funprofiler) uses FracMinHash sketching to rapidly assign reads to KEGG Orthology (KO) functional categories. +Enabled with `--run_fmhfunprofiler`. + +
+Output files + +- `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`. + +
+Output files + +- `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. + +
+ +### 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`. + +
+Output files + +- `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. + +
+ +### 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. + +
+Output files + +- `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.). + +
+ +### 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. + +
+Output files + +- `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. ### MultiQC +[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. +
Output files @@ -41,12 +136,15 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d
-[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 . +Because the pipeline runs no read QC, the report currently carries the run summary and the software versions rather than per-sample QC modules. +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 +[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. +
Output files @@ -57,5 +155,3 @@ Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQ - Parameters used by the pipeline run: `params.json`.
- -[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 b8512c9..50a644c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -6,58 +6,290 @@ ## 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. + +## Read preprocessing + +The pipeline does not perform read QC or preprocessing! +Reads are expected to arrive already trimmed, quality filtered and host decontaminated. + +We recommend users run nf-core/funcprofiler after running [nf-core/taxprofiler](https://nf-co.re/taxprofiler), which already covers short-read preprocessing, and provides complimentary information. +Adopting the nf-core [`fastq_shortreads_preprocess_qc`](https://nf-co.re/subworkflows/fastq_shortreads_preprocess_qc/) subworkflow is planned for a later release. ## Samplesheet input -You will need to create a samplesheet with information about the samples you would like to analyse 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 as shown in the examples below. +You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. +Use this parameter to specify its location. +It has to be a comma-separated file with a header row and the columns shown below. ```bash --input '[path to samplesheet file]' ``` -### Multiple runs of the same sample +| 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: `ABI_SOLID`, `BGISEQ`, `CAPILLARY`, `COMPLETE_GENOMICS`, `DNBSEQ`, `HELICOS`, `ILLUMINA`, `ION_TORRENT`, `LS454`. | +| `fastq_1` | Yes | Full path to gzipped already preprocessed FASTQ file for read 1. Must end in `.fastq.gz` or `.fq.gz`. | +| `fastq_2` | No | Full path to gzipped already preprocessed FASTQ file for read 2 (paired-end only). Leave empty for single-end reads. | +| `fasta` | No | Unused. The column is retained for compatibility with nf-core/taxprofiler samplesheets and must be left empty. | -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: +> [!NOTE] +> `fastq_1` must be provided for each row! We do **not** support `OXFORD_NANOPORE` or `PACBIO_SMRT` 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 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 +```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,, ``` -### Full samplesheet +In this example, `SAMPLE1` has two runs which will be merged before profiling. `SAMPLE2` is single-end short reads. + +## Enabling profilers -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. +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` | mi-faser | Available | +| `--run_rgi` | RGI BWT | Available | +| `--run_diamond` | DIAMOND blastx | Work in progress / beta | +| `--run_eggnogmapper` | eggNOG-mapper | Work in progress / beta | + +> [!NOTE] +> Each `--run_` flag requires a matching database entry in the `--databases` CSV. Database rows for tools that are not enabled will be ignored. + +> [!WARNING] +> Beta means the profiler runs and produces output, but database handling and output behaviour have not been validated end to end, and neither is covered by the full-size test. +> Interpret the results with caution and check them independently before using them in an analysis. -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. +## Databases input -```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, +```bash +--databases '[path to databases file]' ``` -| 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". | +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 | Name of the database as a whole, i.e. the release or version you want recorded in the results. All rows belonging to the same database must share this name. | +| `db_entity` | No | Name of an individual component of that database, for the tools that need more than one. Leave empty for tools that take a single database file or directory. | +| `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. | + +> [!IMPORTANT] +> `db_name` and `db_entity` describe two different levels. `db_name` names the database, `db_entity` names one of its parts. +> HUMAnN and eggNOG-mapper need several parts, so they take **one row per part**, all sharing the same `db_name` and each naming a different `db_entity`: `humann_metaphlan`, `humann_nucleotide`, `humann_protein` and `humann_utility` for HUMAnN, and `eggnogmapper_db` and `eggnogmapper_data_dir` for eggNOG-mapper. +> FMH FunProfiler, mi-faser, DIAMOND and RGI take a single database, so they take one row with `db_entity` left empty. + +The pipeline checks the database sheet against the enabled profilers before it submits any job, so a missing component fails immediately rather than partway through a run. + +### Database versions and compatibility + +The pipeline passes `db_path` straight to the profiler and never checks it against the tool version, so pairing a database with a compatible tool release is up to you. +The versions a run actually used are recorded in `/pipeline_info/nf_core_funcprofiler_software_mqc_versions.yml`. + +These combinations were exercised on a human gut metagenome cohort during development; RGI, DIAMOND and HUMAnN v4 were only tested against the small CI databases. + +| Tool | Tool version | Database | +| --------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- | +| HUMAnN v3 | 3.6.1 | ChocoPhlAn full `v201901_v31`, UniRef90 `201901b` full, `utility_mapping` full | +| MetaPhlAn | 4.0.6 | `mpa_vJan21_CHOCOPhlAnSGB_202103` | +| FMH FunProfiler | 1.1.1 | KO sketches from [Zenodo record 10045253](https://zenodo.org/records/10045253), scaled 1000 / k=11 and scaled 500 | +| mi-faser | 1.64 | `GS-24-all`, downloaded from the mi-faser website | +| eggNOG-mapper | 2.1.13 | eggNOG 5.0.2 data directory | + +### HUMAnN -An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline. +[HUMAnN](https://huttenhower.sph.harvard.edu/humann/) profiles the abundance of microbial metabolic pathways and gene families, guided by a MetaPhlAn taxonomic profile. +Enable it with `--run_humann_v3` or `--run_humann_v4`. + +#### Database preparation + +HUMAnN requires four database components per named database, each as a separate row with the same `db_name`. +The ChocoPhlAn nucleotide database, the UniRef protein database and the utility mapping files are downloaded with `humann_databases`, which ships with HUMAnN; the MetaPhlAn marker database is downloaded with `metaphlan --install`. + +```bash +humann_databases --download chocophlan full /data/databases +humann_databases --download uniref uniref90_diamond /data/databases +humann_databases --download utility_mapping full /data/databases +metaphlan --install --bowtie2db /data/databases/metaphlan_db +``` + +See the [HUMAnN documentation](https://github.com/biobakery/humann#5-download-the-databases) for the full list of available releases. +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_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 +``` + +### FMH FunProfiler + +[FMH FunProfiler](https://github.com/KoslickiLab/fmh-funprofiler) uses FracMinHash sketching to assign reads to KEGG Orthology (KO) categories. +Enable it with `--run_fmhfunprofiler`. + +#### Database preparation + +Download a pre-sketched KO database from [Zenodo record 10045253](https://zenodo.org/records/10045253), or build your own sketches with `sourmash sketch` as described in the [FMH FunProfiler README](https://github.com/KoslickiLab/fmh-funprofiler#usage). +`db_path` points at the `.sig.zip` sketch file. + +FMH FunProfiler is the one tool that needs its `db_params` filled in: it takes the k-mer size and the sketch scale of the database, in that order, separated by a space. +A sketch built at k=11 and scale 1000 therefore needs `11 1000`. + +```csv +tool,db_name,db_entity,db_params,db_path +fmhfunprofiler,kegg_v1,,11 1000,/data/databases/fmhfunprofiler_kegg.sig.zip +``` + +### mi-faser + +[mi-faser](https://bromberglab.org/project/mifaser/) performs functional profiling by mapping reads to functional databases at the protein level. +Enable it with `--run_mifaser`. + +#### Database preparation + +Download a pre-built mi-faser database (e.g. GS-21, GS-24-all, or GS-580) from the [mi-faser website](https://bromberglab.org/project/mifaser/). +`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_path +mifaser,GS-24-all,,,/data/databases/mifaser/GS-24-all +``` + +### 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 it 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_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. + +### eggNOG-mapper + +[eggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) assigns functional annotations by mapping sequences to orthologous groups in the eggNOG database. +Enable it with `--run_eggnogmapper`. + +> [!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. + +#### Database preparation + +eggNOG-mapper requires two rows per named database: the search database (`eggnogmapper_db`) and the eggNOG data directory (`eggnogmapper_data_dir`). +Both are downloaded with `download_eggnog_data.py`, which ships with the eggnog-mapper package; see the [eggNOG-mapper wiki](https://github.com/eggnogdb/eggnog-mapper/wiki) for the available releases. + +```bash +download_eggnog_data.py --data_dir /data/databases/eggnog_mapper/data -P +create_dbs.py -m diamond --dbname eggnog_proteins --data_dir /data/databases/eggnog_mapper +``` + +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. + +```csv +tool,db_name,db_entity,db_params,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 +``` + +### 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). + +```csv +tool,db_name,db_entity,db_params,db_path +diamond,uniref90_v3,,,/data/databases/diamond +``` + +> [!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. + +### 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_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,,11 1000,/data/databases/fmhfunprofiler_kegg.sig.zip +mifaser,GS-24-all,,,/data/databases/mifaser/GS-24-all +rgi,card_v3,,,/data/databases/card +eggnogmapper,eggnog_v5,eggnogmapper_db,diamond,/data/databases/eggnog_mapper/eggnog_proteins.dmnd +eggnogmapper,eggnog_v5,eggnogmapper_data_dir,,/data/databases/eggnog_mapper/data +diamond,uniref90_v3,,,/data/databases/diamond +``` ## 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 +303,14 @@ 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/running/run-pipelines#configuring-pipelines), other infrastructural tweaks (such as output directories), or module arguments (args). +> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/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 +321,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). @@ -127,7 +361,7 @@ 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] +> [!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). diff --git a/main.nf b/main.nf index c0d4a4e..7a99a80 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,22 +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 + reads // channel: validated reads read in from --input + databases // channel: databases in from --databases main: // // WORKFLOW: Run pipeline // - FUNCPROFILER ( - samplesheet, + FUNCPROFILER( + reads, + 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 } @@ -67,44 +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.databases, params.help, params.help_full, - params.show_hidden + params.show_hidden, ) // // WORKFLOW: Run main workflow // - NFCORE_FUNCPROFILER ( - PIPELINE_INITIALISATION.out.samplesheet + NFCORE_FUNCPROFILER( + PIPELINE_INITIALISATION.out.reads, + 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, - NFCORE_FUNCPROFILER.out.multiqc_report + params.hook_url, + NFCORE_FUNCPROFILER.out.multiqc_report, ) } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ diff --git a/modules.json b/modules.json index 5ba5433..54adb7c 100644 --- a/modules.json +++ b/modules.json @@ -5,15 +5,80 @@ "https://github.com/nf-core/modules.git": { "modules": { "nf-core": { - "fastqc": { + "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"] + }, + "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": "98403d15b0e50edae1f3fec5eae5e24982f1fade", "installed_by": ["modules"] + }, + "rgi/bwt": { + "branch": "master", + "git_sha": "0a93f68a28f5e07bb7ae82aeb005720faf8a3b35", + "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,7 +86,7 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", + "git_sha": "1a545fcbd762911c21a64ced3dbef99b2b51ac75", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { 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..b877369 --- /dev/null +++ b/modules/local/humann4/humann/main.nf @@ -0,0 +1,70 @@ +// +// Local module: there is no nf-core/modules HUMAnN 4 module, because HUMAnN 4 is still an alpha +// release with no Bioconda package or Biocontainer of its own. The script follows the nf-core +// humann3 modules; the container is a community build carrying humann 4.0.0.alpha.1. +// +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 + + 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 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..98a4c17 --- /dev/null +++ b/modules/local/humann4/humann/meta.yaml @@ -0,0 +1,68 @@ +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" + - "@vinisalazar" 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..dfe522d --- /dev/null +++ b/modules/local/humann4/regroup/main.nf @@ -0,0 +1,50 @@ +// +// Local module: there is no nf-core/modules HUMAnN 4 module, because HUMAnN 4 is still an alpha +// release with no Bioconda package or Biocontainer of its own. The script follows the nf-core +// humann3 modules; the container is a community build carrying humann 4.0.0.alpha.1. +// +process HUMANN4_REGROUP { + 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) + 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..690ad6f --- /dev/null +++ b/modules/local/humann4/regroup/meta.yaml @@ -0,0 +1,47 @@ +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" + - "@nickp60" + - "@vinisalazar" 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..d098a27 --- /dev/null +++ b/modules/local/humann4/renorm/main.nf @@ -0,0 +1,44 @@ +// +// Local module: there is no nf-core/modules HUMAnN 4 module, because HUMAnN 4 is still an alpha +// release with no Bioconda package or Biocontainer of its own. The script follows the nf-core +// humann3 modules; the container is a community build carrying humann 4.0.0.alpha.1. +// +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..4beb532 --- /dev/null +++ b/modules/local/humann4/renorm/meta.yaml @@ -0,0 +1,43 @@ +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" + - "@nickp60" + - "@vinisalazar" 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/fastqc/environment.yml b/modules/nf-core/diamond/blastx/environment.yml similarity index 86% rename from modules/nf-core/fastqc/environment.yml rename to modules/nf-core/diamond/blastx/environment.yml index f9f54ee..5dc13ad 100644 --- a/modules/nf-core/fastqc/environment.yml +++ b/modules/nf-core/diamond/blastx/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::fastqc=0.12.1 + - 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 deleted file mode 100644 index 7770ccd..0000000 --- a/modules/nf-core/fastqc/.conda-lock/linux_amd64-bd-5cb1a2fa2f18c7c2_1.txt +++ /dev/null @@ -1,822 +0,0 @@ - -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 deleted file mode 100644 index cdc434c..0000000 --- a/modules/nf-core/fastqc/.conda-lock/linux_arm64-bd-e455e32f745abe68_1.txt +++ /dev/null @@ -1,769 +0,0 @@ - -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 deleted file mode 100644 index 1085126..0000000 --- a/modules/nf-core/fastqc/main.nf +++ /dev/null @@ -1,57 +0,0 @@ -process FASTQC { - tag "${meta.id}" - label 'process_low' - - conda "${moduleDir}/environment.yml" - 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, stageAs: '?/*') - - output: - tuple val(meta), path("*.html"), emit: html - 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}" - // 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(' ') - - // 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.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 - [ -f "\${new_name}" ] || ln -s \$old_name \$new_name - done - - fastqc \\ - ${args} \\ - --threads ${task.cpus} \\ - ${fastqc_memory_arg} \\ - ${renamed_files} - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.html - touch ${prefix}.zip - """ -} diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml deleted file mode 100644 index 2f6cfef..0000000 --- a/modules/nf-core/fastqc/meta.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: fastqc -description: Run FastQC on sequenced reads -keywords: - - quality control - - qc - - adapters - - fastq -tools: - - fastqc: - description: | - FastQC gives general quality metrics about your reads. - It provides information about the quality score distribution - across your reads, the per base sequence content (%A/C/G/T). - - You get information about adapter contamination and other - overrepresented sequences. - homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ - documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ - licence: ["GPL-2.0-only"] - identifier: biotools:fastqc -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. - ontologies: [] -output: - html: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.html": - type: file - description: FastQC report - pattern: "*_{fastqc.html}" - ontologies: [] - zip: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.zip": - type: file - description: FastQC report archive - pattern: "*_{fastqc.zip}" - ontologies: [] - versions_fastqc: - - - ${task.process}: - type: string - description: The process the versions were collected from - - fastqc: - type: string - description: The tool name - - fastqc --version | sed "/FastQC v/!d; s/.*v//": - type: eval - description: The expression to obtain the version of the tool - -topics: - versions: - - - ${task.process}: - type: string - description: The process the versions were collected from - - fastqc: - type: string - description: The tool name - - fastqc --version | sed "/FastQC v/!d; s/.*v//": - type: eval - description: The expression to obtain the version of the tool -authors: - - "@drpatelh" - - "@grst" - - "@ewels" - - "@FelixKrueger" -maintainers: - - "@drpatelh" - - "@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 deleted file mode 100644 index 66c44da..0000000 --- a/modules/nf-core/fastqc/tests/main.nf.test +++ /dev/null @@ -1,309 +0,0 @@ -nextflow_process { - - name "Test Process FASTQC" - script "../main.nf" - process "FASTQC" - - tag "modules" - tag "modules_nfcore" - tag "fastqc" - - test("sarscov2 single-end [fastq]") { - - when { - process { - """ - input[0] = Channel.of([ - [ id: 'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it. - // looks like this:
Mon 2 Oct 2023
test.gz
- // https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039 - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 paired-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) ] - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 interleaved [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_interleaved.fastq.gz', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 paired-end [bam]") { - - when { - process { - """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 multiple [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), - 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 process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" }, - { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" }, - { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, - { assert snapshot(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 custom_prefix") { - - when { - process { - """ - input[0] = Channel.of([ - [ id:'mysample', single_end:true ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert 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(sanitizeOutput(process.out).findAll { key, val -> key != 'html' && key != 'zip' }).match() } - ) - } - } - - test("sarscov2 single-end [fastq] - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [ id: 'test', single_end:true ], - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("sarscov2 paired-end [fastq] - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("sarscov2 interleaved [fastq] - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("sarscov2 paired-end [bam] - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("sarscov2 multiple [fastq] - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("sarscov2 custom_prefix - stub") { - - options "-stub" - when { - process { - """ - input[0] = Channel.of([ - [ id:'mysample', single_end:true ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) - ]) - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } -} diff --git a/modules/nf-core/fastqc/tests/main.nf.test.snap b/modules/nf-core/fastqc/tests/main.nf.test.snap deleted file mode 100644 index c8ee120..0000000 --- a/modules/nf-core/fastqc/tests/main.nf.test.snap +++ /dev/null @@ -1,476 +0,0 @@ -{ - "sarscov2 custom_prefix": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:14.518503" - }, - "sarscov2 single-end [fastq] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": true - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": true - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "test", - "single_end": true - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "test", - "single_end": true - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:19.309008" - }, - "sarscov2 custom_prefix - stub": { - "content": [ - { - "0": [ - [ - { - "id": "mysample", - "single_end": true - }, - "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "mysample", - "single_end": true - }, - "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "mysample", - "single_end": true - }, - "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "mysample", - "single_end": true - }, - "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:44.94888" - }, - "sarscov2 interleaved [fastq]": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:38:45.168496" - }, - "sarscov2 paired-end [bam]": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:38:53.268919" - }, - "sarscov2 multiple [fastq]": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:05.050305" - }, - "sarscov2 paired-end [fastq]": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:38:37.2373" - }, - "sarscov2 paired-end [fastq] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:24.450398" - }, - "sarscov2 multiple [fastq] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:39.758762" - }, - "sarscov2 single-end [fastq]": { - "content": [ - { - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:38:29.555068" - }, - "sarscov2 interleaved [fastq] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "timestamp": "2025-10-28T16:39:29.193136" - }, - "sarscov2 paired-end [bam] - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "html": [ - [ - { - "id": "test", - "single_end": false - }, - "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions_fastqc": [ - [ - "FASTQC", - "fastqc", - "0.12.1" - ] - ], - "zip": [ - [ - { - "id": "test", - "single_end": false - }, - "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" - }, - "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-c1f4a7982b743963_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c1f4a7982b743963_1.txt deleted file mode 100644 index 7619030..0000000 --- a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c1f4a7982b743963_1.txt +++ /dev/null @@ -1,1552 +0,0 @@ - -version: 6 -environments: -default: -channels: -- url: https://conda.anaconda.org/conda-forge/ -- url: https://conda.anaconda.org/bioconda/ -- url: https://conda.anaconda.org/bioconda/ -options: -pypi-prerelease-mode: if-necessary-or-explicit -packages: -linux-64: -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.39.3-py310hbcd5346_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py314h2e6c369_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.2.28-py314h5bd0f2a_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.52.0-h04a0ce9_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda -packages: -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda -build_number: 20 -sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 -md5: a9f577daf3de00bca7c3c76c0ecbd1de -depends: -- __glibc >=2.17,<3.0.a0 -- libgomp >=7.5.0 -constrains: -- openmp_impl <0.0a0 -license: BSD-3-Clause -license_family: BSD -size: 28948 -timestamp: 1770939786096 -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda -sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 -md5: aaa2a381ccc56eac91d63b6c1240312f -depends: -- cpython -- python-gil -license: MIT -license_family: MIT -size: 8191 -timestamp: 1744137672556 -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda -sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 -md5: 2934f256a8acfe48f6ebb4fce6cde29c -depends: -- python >=3.9 -- typing-extensions >=4.0.0 -license: MIT -license_family: MIT -size: 18074 -timestamp: 1733247158254 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda -sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab -md5: c6b0543676ecb1fb2d7643941fe375f2 -depends: -- python >=3.10 -- python -license: MIT -license_family: MIT -size: 64927 -timestamp: 1773935801332 -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda -noarch: generic -sha256: c31ab719d256bc6f89926131e88ecd0f0c5d003fe8481852c6424f4ec6c7eb29 -md5: a2ac7763a9ac75055b68f325d3255265 -depends: -- python >=3.14 -license: BSD-3-Clause AND MIT AND EPL-2.0 -size: 7514 -timestamp: 1767044983590 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda -sha256: 3ad3500bff54a781c29f16ce1b288b36606e2189d0b0ef2f67036554f47f12b0 -md5: 8910d2c46f7e7b519129f486e0fe927a -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -constrains: -- libbrotlicommon 1.2.0 hb03c661_1 -license: MIT -license_family: MIT -size: 367376 -timestamp: 1764017265553 -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda -sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 -md5: d2ffd7602c02f2b316fd921d39876885 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: bzip2-1.0.6 -license_family: BSD -size: 260182 -timestamp: 1771350215188 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda -sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc -md5: 4492fd26db29495f0ba23f146cd5638d -depends: -- __unix -license: ISC -size: 147413 -timestamp: 1772006283803 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda -sha256: a6b118fd1ed6099dc4fc03f9c492b88882a780fadaef4ed4f93dc70757713656 -md5: 765c4d97e877cdbbb88ff33152b86125 -depends: -- python >=3.10 -license: ISC -size: 151445 -timestamp: 1772001170301 -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda -sha256: d86dfd428b2e3c364fa90e07437c8405d635aa4ef54b25ab51d9c712be4112a5 -md5: 49ee13eb9b8f44d63879c69b8a40a74b -depends: -- python >=3.10 -license: MIT -license_family: MIT -size: 58510 -timestamp: 1773660086450 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda -sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 -md5: ea8a6c3256897cc31263de9f455e25d9 -depends: -- python >=3.10 -- __unix -- python -license: BSD-3-Clause -license_family: BSD -size: 97676 -timestamp: 1764518652276 -- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda -sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 -md5: b866ff7007b934d564961066c8195983 -depends: -- humanfriendly >=9.1 -- python >=3.9 -license: MIT -license_family: MIT -size: 43758 -timestamp: 1733928076798 -- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda -sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 -md5: 071cf7b0ce333c81718b054066c15102 -depends: -- networkx >=2.0 -- numpy -- python >=3.9 -license: BSD-3-Clause -license_family: BSD -size: 39326 -timestamp: 1735759976140 -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda -noarch: generic -sha256: 91b06300879df746214f7363d6c27c2489c80732e46a369eb2afc234bcafb44c -md5: 3bb89e4f795e5414addaa531d6b1500a -depends: -- python >=3.14,<3.15.0a0 -- python_abi * *_cp314 -license: Python-2.0 -size: 50078 -timestamp: 1770674447292 -- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda -sha256: 0cc345e4dead417996ce9a1f088b28d858f03d113d43c1963d29194366dcce27 -md5: a0535741a4934b3e386051065c58761a -depends: -- __glibc >=2.17,<3.0.a0 -- libexpat 2.7.4 hecca717_0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 145274 -timestamp: 1771259434699 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 -sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b -md5: 0c96522c6bdaed4b1566d11387caaf45 -license: BSD-3-Clause -license_family: BSD -size: 397370 -timestamp: 1566932522327 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 -sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c -md5: 34893075a5c9e55cdafac56607368fc6 -license: OFL-1.1 -license_family: Other -size: 96530 -timestamp: 1620479909603 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 -sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 -md5: 4d59c254e01d9cde7957100457e2d5fb -license: OFL-1.1 -license_family: Other -size: 700814 -timestamp: 1620479612257 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda -sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 -md5: 49023d73832ef61042f6a237cb2687e7 -license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 -license_family: Other -size: 1620504 -timestamp: 1727511233259 -- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda -sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c -md5: 867127763fbe935bab59815b6e0b7b5c -depends: -- __glibc >=2.17,<3.0.a0 -- libexpat >=2.7.4,<3.0a0 -- libfreetype >=2.14.1 -- libfreetype6 >=2.14.1 -- libgcc >=14 -- libuuid >=2.41.3,<3.0a0 -- libzlib >=1.3.1,<2.0a0 -license: MIT -license_family: MIT -size: 270705 -timestamp: 1771382710863 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda -sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 -md5: a7970cd949a077b7cb9696379d338681 -depends: -- font-ttf-ubuntu -- font-ttf-inconsolata -- font-ttf-dejavu-sans-mono -- font-ttf-source-code-pro -license: BSD-3-Clause -license_family: BSD -size: 4059 -timestamp: 1762351264405 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda -sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 -md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 -depends: -- python >=3.10 -- hyperframe >=6.1,<7 -- hpack >=4.1,<5 -- python -license: MIT -license_family: MIT -size: 95967 -timestamp: 1756364871835 -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda -sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba -md5: 0a802cb9888dd14eeefc611f05c40b6e -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 30731 -timestamp: 1737618390337 -- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda -sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d -md5: 7fe569c10905402ed47024fc481bb371 -depends: -- __unix -- python >=3.9 -license: MIT -license_family: MIT -size: 73563 -timestamp: 1733928021866 -- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda -sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 -md5: daddf757c3ecd6067b9af1df1f25d89e -depends: -- python >=3.10 -license: MIT -license_family: MIT -size: 67994 -timestamp: 1766267728652 -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda -sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 -md5: 8e6923fc12f1fe8f8c4e5c9f343256ac -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 17397 -timestamp: 1737618427549 -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda -sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a -md5: c80d8a3b84358cb967fa81e7075fbc8a -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -license: MIT -license_family: MIT -size: 12723451 -timestamp: 1773822285671 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda -sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 -md5: 53abe63df7e10a6ba605dc5f9f961d36 -depends: -- python >=3.10 -license: BSD-3-Clause -license_family: BSD -size: 50721 -timestamp: 1760286526795 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda -sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 -md5: 080594bf4493e6bae2607e65390c520a -depends: -- python >=3.10 -- zipp >=3.20 -- python -license: Apache-2.0 -license_family: APACHE -size: 34387 -timestamp: 1773931568510 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda -sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b -md5: 04558c96691bed63104678757beb4f8d -depends: -- markupsafe >=2.0 -- python >=3.10 -- python -license: BSD-3-Clause -license_family: BSD -size: 120685 -timestamp: 1764517220861 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda -sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 -md5: ada41c863af263cc4c5fcbaff7c3e4dc -depends: -- attrs >=22.2.0 -- jsonschema-specifications >=2023.3.6 -- python >=3.10 -- referencing >=0.28.4 -- rpds-py >=0.25.0 -- python -license: MIT -license_family: MIT -size: 82356 -timestamp: 1767839954256 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda -sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 -md5: 439cd0f567d697b20a8f45cb70a1005a -depends: -- python >=3.10 -- referencing >=0.31.0 -- python -license: MIT -license_family: MIT -size: 19236 -timestamp: 1757335715225 -- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 -sha256: 7f243680ca03eba7457b7a48f93a9440ba8181a8eac20a3eb5ef165ab6c96664 -md5: b3723b235b0758abaae8c82ce4d80146 -depends: -- __glibc >=2.17,<3.0.a0 -- expat >=2.2.10,<3.0.0a0 -- fontconfig -- fonts-conda-forge -- libgcc-ng >=9.3.0 -- mathjax 2.7.* -- nspr >=4.29,<5.0a0 -- nss >=3.62,<4.0a0 -- sqlite >=3.34.0,<4.0a0 -license: MIT -license_family: MIT -size: 62099926 -timestamp: 1615199463039 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda -sha256: 836ec4b895352110335b9fdcfa83a8dcdbe6c5fb7c06c4929130600caea91c0a -md5: 6f2e2c8f58160147c4d1c6f4c14cbac4 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libjpeg-turbo >=3.1.2,<4.0a0 -- libtiff >=4.7.1,<4.8.0a0 -license: MIT -license_family: MIT -size: 249959 -timestamp: 1768184673131 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda -sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c -md5: 18335a698559cdbcd86150a48bf54ba6 -depends: -- __glibc >=2.17,<3.0.a0 -- zstd >=1.5.7,<1.6.0a0 -constrains: -- binutils_impl_linux-64 2.45.1 -license: GPL-3.0-only -license_family: GPL -size: 728002 -timestamp: 1774197446916 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda -sha256: f84cb54782f7e9cea95e810ea8fef186e0652d0fa73d3009914fa2c1262594e1 -md5: a752488c68f2e7c456bcbd8f16eec275 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -license: Apache-2.0 -license_family: Apache -size: 261513 -timestamp: 1773113328888 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda -build_number: 5 -sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c -md5: c160954f7418d7b6e87eaf05a8913fa9 -depends: -- libopenblas >=0.3.30,<0.3.31.0a0 -- libopenblas >=0.3.30,<1.0a0 -constrains: -- mkl <2026 -- liblapack 3.11.0 5*_openblas -- libcblas 3.11.0 5*_openblas -- blas 2.305 openblas -- liblapacke 3.11.0 5*_openblas -license: BSD-3-Clause -license_family: BSD -size: 18213 -timestamp: 1765818813880 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda -build_number: 5 -sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 -md5: 6636a2b6f1a87572df2970d3ebc87cc0 -depends: -- libblas 3.11.0 5_h4a7cf45_openblas -constrains: -- liblapacke 3.11.0 5*_openblas -- blas 2.305 openblas -- liblapack 3.11.0 5*_openblas -license: BSD-3-Clause -license_family: BSD -size: 18194 -timestamp: 1765818837135 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda -sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 -md5: 6c77a605a7a689d17d4819c0f8ac9a00 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 73490 -timestamp: 1761979956660 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda -sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 -md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -constrains: -- expat 2.7.4.* -license: MIT -license_family: MIT -size: 76798 -timestamp: 1771259418166 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda -sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 -md5: a360c33a5abe61c07959e449fa1453eb -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 58592 -timestamp: 1769456073053 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda -sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 -md5: e289f3d17880e44b633ba911d57a321b -depends: -- libfreetype6 >=2.14.3 -license: GPL-2.0-only OR FTL -size: 8049 -timestamp: 1774298163029 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda -sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d -md5: fb16b4b69e3f1dcfe79d80db8fd0c55d -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libpng >=1.6.55,<1.7.0a0 -- libzlib >=1.3.2,<2.0a0 -constrains: -- freetype >=2.14.3 -license: GPL-2.0-only OR FTL -size: 384575 -timestamp: 1774298162622 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda -sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 -md5: 0aa00f03f9e39fb9876085dee11a85d4 -depends: -- __glibc >=2.17,<3.0.a0 -- _openmp_mutex >=4.5 -constrains: -- libgcc-ng ==15.2.0=*_18 -- libgomp 15.2.0 he0feb66_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 1041788 -timestamp: 1771378212382 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda -sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 -md5: d5e96b1ed75ca01906b3d2469b4ce493 -depends: -- libgcc 15.2.0 he0feb66_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 27526 -timestamp: 1771378224552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda -sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee -md5: 9063115da5bc35fdc3e1002e69b9ef6e -depends: -- libgfortran5 15.2.0 h68bc16d_18 -constrains: -- libgfortran-ng ==15.2.0=*_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 27523 -timestamp: 1771378269450 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda -sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 -md5: 646855f357199a12f02a87382d429b75 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=15.2.0 -constrains: -- libgfortran 15.2.0 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 2482475 -timestamp: 1771378241063 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda -sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 -md5: 239c5e9546c38a1e884d69effcf4c882 -depends: -- __glibc >=2.17,<3.0.a0 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 603262 -timestamp: 1771378117851 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda -sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 -md5: 8397539e3a0bbd1695584fb4f927485a -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -constrains: -- jpeg <0.0.0a -license: IJG AND BSD-3-Clause AND Zlib -size: 633710 -timestamp: 1762094827865 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda -build_number: 5 -sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 -md5: b38076eb5c8e40d0106beda6f95d7609 -depends: -- libblas 3.11.0 5_h4a7cf45_openblas -constrains: -- blas 2.305 openblas -- liblapacke 3.11.0 5*_openblas -- libcblas 3.11.0 5*_openblas -license: BSD-3-Clause -license_family: BSD -size: 18200 -timestamp: 1765818857876 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda -sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb -md5: c7c83eecbb72d88b940c249af56c8b17 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -constrains: -- xz 5.8.2.* -license: 0BSD -size: 113207 -timestamp: 1768752626120 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda -sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 -md5: 2c21e66f50753a083cbe6b80f38268fa -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: BSD-2-Clause -license_family: BSD -size: 92400 -timestamp: 1769482286018 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda -sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 -md5: be43915efc66345cccb3c310b6ed0374 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libgfortran -- libgfortran5 >=14.3.0 -constrains: -- openblas >=0.3.30,<0.3.31.0a0 -license: BSD-3-Clause -license_family: BSD -size: 5927939 -timestamp: 1763114673331 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda -sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c -md5: 5f13ffc7d30ffec87864e678df9957b4 -depends: -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- libzlib >=1.3.1,<2.0a0 -license: zlib-acknowledgement -size: 317669 -timestamp: 1770691470744 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda -sha256: d716847b7deca293d2e49ed1c8ab9e4b9e04b9d780aea49a97c26925b28a7993 -md5: fd893f6a3002a635b5e50ceb9dd2c0f4 -depends: -- __glibc >=2.17,<3.0.a0 -- icu >=78.2,<79.0a0 -- libgcc >=14 -- libzlib >=1.3.1,<2.0a0 -license: blessing -size: 951405 -timestamp: 1772818874251 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda -sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e -md5: 1b08cd684f34175e4514474793d44bcb -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc 15.2.0 he0feb66_18 -constrains: -- libstdcxx-ng ==15.2.0=*_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 5852330 -timestamp: 1771378262446 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda -sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 -md5: cd5a90476766d53e901500df9215e927 -depends: -- __glibc >=2.17,<3.0.a0 -- lerc >=4.0.0,<5.0a0 -- libdeflate >=1.25,<1.26.0a0 -- libgcc >=14 -- libjpeg-turbo >=3.1.0,<4.0a0 -- liblzma >=5.8.1,<6.0a0 -- libstdcxx >=14 -- libwebp-base >=1.6.0,<2.0a0 -- libzlib >=1.3.1,<2.0a0 -- zstd >=1.5.7,<1.6.0a0 -license: HPND -size: 435273 -timestamp: 1762022005702 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda -sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee -md5: db409b7c1720428638e7c0d509d3e1b5 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: BSD-3-Clause -license_family: BSD -size: 40311 -timestamp: 1766271528534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda -sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b -md5: aea31d2e5b1091feca96fcfe945c3cf9 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -constrains: -- libwebp 1.6.0 -license: BSD-3-Clause -license_family: BSD -size: 429011 -timestamp: 1752159441324 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda -sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa -md5: 92ed62436b625154323d40d5f2f11dd7 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=13 -- pthread-stubs -- xorg-libxau >=1.0.11,<2.0a0 -- xorg-libxdmcp -license: MIT -license_family: MIT -size: 395888 -timestamp: 1727278577118 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda -sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 -md5: d87ff7921124eccd67248aa483c23fec -depends: -- __glibc >=2.17,<3.0.a0 -constrains: -- zlib 1.3.2 *_2 -license: Zlib -license_family: Other -size: 63629 -timestamp: 1774072609062 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda -sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b -md5: ba0a9221ce1063f31692c07370d062f3 -depends: -- importlib-metadata >=4.4 -- python >=3.10 -- python -license: BSD-3-Clause -license_family: BSD -size: 85893 -timestamp: 1770694658918 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda -sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e -md5: 5b5203189eb668f042ac2b0826244964 -depends: -- mdurl >=0.1,<1 -- python >=3.10 -license: MIT -license_family: MIT -size: 64736 -timestamp: 1754951288511 -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda -sha256: c279be85b59a62d5c52f5dd9a4cd43ebd08933809a8416c22c3131595607d4cf -md5: 9a17c4307d23318476d7fbf0fedc0cde -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -constrains: -- jinja2 >=3.0.0 -license: BSD-3-Clause -license_family: BSD -size: 27424 -timestamp: 1772445227915 -- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 -sha256: 02fef69bde69db264a12f21386612262f545b6e3e68d8f1ccec19f3eaae58edf -md5: 86e69bd82c2a2c6fd29f5ab7e02b3691 -license: Apache-2.0 -license_family: Apache -size: 22281629 -timestamp: 1662784498331 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda -sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 -md5: 592132998493b3ff25fd7479396e8351 -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 14465 -timestamp: 1733255681319 -- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda -sha256: f005760b13093362fc9c997d603dd487de32ab2e821a3cbce52a42bcb8136517 -md5: 698a8a27c2b9d8a542c70cb47099a75e -depends: -- click -- coloredlogs -- humanize -- importlib-metadata -- jinja2 >=3.0.0 -- jsonschema -- markdown -- natsort -- numpy -- packaging -- pillow >=10.2.0 -- plotly >=5.18 -- polars-lts-cpu -- pyaml-env -- pydantic >=2.7.1 -- python >=3.8,!=3.14.1 -- python-dotenv -- python-kaleido 0.2.1 -- pyyaml >=4 -- requests -- rich >=10 -- rich-click -- spectra >=0.0.10 -- tiktoken -- tqdm -- typeguard -license: GPL-3.0-or-later -license_family: GPL3 -size: 4198799 -timestamp: 1765300743879 -- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda -sha256: 541fd4390a0687228b8578247f1536a821d9261389a65585af9d1a6f2a14e1e0 -md5: 30bec5e8f4c3969e2b1bd407c5e52afb -depends: -- python >=3.10 -- python -license: MIT -size: 280459 -timestamp: 1774380620329 -- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda -sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 -md5: e941e85e273121222580723010bd4fa2 -depends: -- python >=3.9 -- python -license: MIT -license_family: MIT -size: 39262 -timestamp: 1770905275632 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda -sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 -md5: 47e340acb35de30501a76c7c799c41d7 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=13 -license: X11 AND BSD-3-Clause -size: 891641 -timestamp: 1738195959188 -- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda -sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 -md5: a2c1eeadae7a309daed9d62c96012a2b -depends: -- python >=3.11 -- python -constrains: -- numpy >=1.25 -- scipy >=1.11.2 -- matplotlib-base >=3.8 -- pandas >=2.0 -license: BSD-3-Clause -license_family: BSD -size: 1587439 -timestamp: 1765215107045 -- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda -sha256: e3664264bd936c357523b55c71ed5a30263c6ba278d726a75b1eb112e6fb0b64 -md5: e235d5566c9cc8970eb2798dd4ecf62f -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -license: MPL-2.0 -license_family: MOZILLA -size: 228588 -timestamp: 1762348634537 -- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda -sha256: 44dd98ffeac859d84a6dcba79a2096193a42fc10b29b28a5115687a680dd6aea -md5: 567fbeed956c200c1db5782a424e58ee -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libsqlite >=3.51.0,<4.0a0 -- libstdcxx >=14 -- libzlib >=1.3.1,<2.0a0 -- nspr >=4.38,<5.0a0 -license: MPL-2.0 -license_family: MOZILLA -size: 2057773 -timestamp: 1763485556350 -- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda -sha256: f2ba8cb0d86a6461a6bcf0d315c80c7076083f72c6733c9290086640723f79ec -md5: 36f5b7eb328bdc204954a2225cf908e2 -depends: -- python -- libstdcxx >=14 -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- python_abi 3.14.* *_cp314 -- libcblas >=3.9.0,<4.0a0 -- liblapack >=3.9.0,<4.0a0 -- libblas >=3.9.0,<4.0a0 -constrains: -- numpy-base <0a0 -license: BSD-3-Clause -license_family: BSD -size: 8927860 -timestamp: 1773839233468 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda -sha256: 3900f9f2dbbf4129cf3ad6acf4e4b6f7101390b53843591c53b00f034343bc4d -md5: 11b3379b191f63139e29c0d19dee24cd -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libpng >=1.6.50,<1.7.0a0 -- libstdcxx >=14 -- libtiff >=4.7.1,<4.8.0a0 -- libzlib >=1.3.1,<2.0a0 -license: BSD-2-Clause -license_family: BSD -size: 355400 -timestamp: 1758489294972 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda -sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c -md5: f61eb8cd60ff9057122a3d338b99c00f -depends: -- __glibc >=2.17,<3.0.a0 -- ca-certificates -- libgcc >=14 -license: Apache-2.0 -license_family: Apache -size: 3164551 -timestamp: 1769555830639 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda -sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 -md5: b76541e68fea4d511b1ac46a28dcd2c6 -depends: -- python >=3.8 -- python -license: Apache-2.0 -license_family: APACHE -size: 72010 -timestamp: 1769093650580 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda -sha256: 9e6ec8f3213e8b7d64b0ad45f84c51a2c9eba4398efda31e196c9a56186133ee -md5: 79678378ae235e24b3aa83cee1b38207 -depends: -- python -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- libwebp-base >=1.6.0,<2.0a0 -- zlib-ng >=2.3.3,<2.4.0a0 -- python_abi 3.14.* *_cp314 -- tk >=8.6.13,<8.7.0a0 -- libjpeg-turbo >=3.1.2,<4.0a0 -- libxcb >=1.17.0,<2.0a0 -- openjpeg >=2.5.4,<3.0a0 -- lcms2 >=2.18,<3.0a0 -- libtiff >=4.7.1,<4.8.0a0 -- libfreetype >=2.14.1 -- libfreetype6 >=2.14.1 -license: HPND -size: 1073026 -timestamp: 1770794002408 -- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda -sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 -md5: 3e9427ee186846052e81fadde8ebe96a -depends: -- narwhals >=1.15.1 -- packaging -- python >=3.10 -constrains: -- ipywidgets >=7.6 -license: MIT -license_family: MIT -size: 5251872 -timestamp: 1772628857717 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda -sha256: d332c2d5002fc440ae37ed9679ffc21b552f18d20232390005d1dd3bce0888d3 -md5: d5a4e013a30dd8dfde9ab39f45aaf9c1 -depends: -- polars-runtime-32 ==1.39.3 -- python >=3.10 -- python -constrains: -- numpy >=1.16.0 -- pyarrow >=7.0.0 -- fastexcel >=0.9 -- openpyxl >=3.0.0 -- xlsx2csv >=0.8.0 -- connectorx >=0.3.2 -- deltalake >=1.0.0 -- pyiceberg >=0.7.1 -- altair >=5.4.0 -- great_tables >=0.8.0 -- polars-runtime-32 ==1.39.3 -- polars-runtime-64 ==1.39.3 -- polars-runtime-compat ==1.39.3 -license: MIT -license_family: MIT -size: 533495 -timestamp: 1774207987966 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda -sha256: e466fb31f67ba9bde18deafeb34263ca5eb25807f39ead0e9d753a8e82c4c4f4 -md5: ef0340e75068ac8ff96462749b5c98e7 -depends: -- polars >=1.34.0 -- polars-runtime-compat >=1.34.0 -license: MIT -license_family: MIT -size: 3902 -timestamp: 1760206808444 -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda -noarch: python -sha256: 9744f8086bb0832998f5b01076f57ddc9efbe460e493b14303c3567dc4f401e7 -md5: f9327f9f2cfc4215f55b613e64afd3ba -depends: -- python -- libstdcxx >=14 -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- _python_abi3_support 1.* -- cpython >=3.10 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 37570276 -timestamp: 1774207987966 -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.39.3-py310hbcd5346_1.conda -noarch: python -sha256: bf0b932713f0f27924f42159c98426e0073bb6145ed796eaa4cec79ca05363c7 -md5: 4b9b312453eebd6fbdbbe2a88fa1b5c4 -depends: -- python -- libgcc >=14 -- libstdcxx >=14 -- __glibc >=2.17,<3.0.a0 -- _python_abi3_support 1.* -- cpython >=3.10 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 37224264 -timestamp: 1774207985377 -- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda -sha256: 4ce2e1ee31a6217998f78c31ce7dc0a3e0557d9238b51d49dd20c52d467a126d -md5: f2c23a77b25efcad57d377b34bd84941 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- ncurses >=6.5,<7.0a0 -license: GPL-2.0-or-later AND LGPL-2.0-or-later -license_family: GPL -size: 593603 -timestamp: 1769710381284 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda -sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 -md5: b3c17d95b5a10c6e64a21fa17573e70e -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=13 -license: MIT -license_family: MIT -size: 8252 -timestamp: 1726802366959 -- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda -sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 -md5: e17be1016bcc3516827b836cd3e4d9dc -depends: -- python >=3.9 -- pyyaml >=5.0,<=7.0 -license: MIT -license_family: MIT -size: 14645 -timestamp: 1736766960536 -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda -sha256: 868569d9505b7fe246c880c11e2c44924d7613a8cdcc1f6ef85d5375e892f13d -md5: c3946ed24acdb28db1b5d63321dbca7d -depends: -- typing-inspection >=0.4.2 -- typing_extensions >=4.14.1 -- python >=3.10 -- typing-extensions >=4.6.1 -- annotated-types >=0.6.0 -- pydantic-core ==2.41.5 -- python -license: MIT -license_family: MIT -size: 340482 -timestamp: 1764434463101 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py314h2e6c369_1.conda -sha256: 7e0ae379796e28a429f8e48f2fe22a0f232979d65ec455e91f8dac689247d39f -md5: 432b0716a1dfac69b86aa38fdd59b7e6 -depends: -- python -- typing-extensions >=4.6.0,!=4.7.0 -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- python_abi 3.14.* *_cp314 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 1943088 -timestamp: 1762988995556 -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda -sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a -md5: 6b6ece66ebcae2d5f326c77ef2c5a066 -depends: -- python >=3.9 -license: BSD-2-Clause -license_family: BSD -size: 889287 -timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda -sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 -md5: 461219d1a5bd61342293efa2c0c90eac -depends: -- __unix -- python >=3.9 -license: BSD-3-Clause -license_family: BSD -size: 21085 -timestamp: 1733217331982 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda -build_number: 101 -sha256: cb0628c5f1732f889f53a877484da98f5a0e0f47326622671396fb4f2b0cd6bd -md5: c014ad06e60441661737121d3eae8a60 -depends: -- __glibc >=2.17,<3.0.a0 -- bzip2 >=1.0.8,<2.0a0 -- ld_impl_linux-64 >=2.36.1 -- libexpat >=2.7.3,<3.0a0 -- libffi >=3.5.2,<3.6.0a0 -- libgcc >=14 -- liblzma >=5.8.2,<6.0a0 -- libmpdec >=4.0.0,<5.0a0 -- libsqlite >=3.51.2,<4.0a0 -- libuuid >=2.41.3,<3.0a0 -- libzlib >=1.3.1,<2.0a0 -- ncurses >=6.5,<7.0a0 -- openssl >=3.5.5,<4.0a0 -- python_abi 3.14.* *_cp314 -- readline >=8.3,<9.0a0 -- tk >=8.6.13,<8.7.0a0 -- tzdata -- zstd >=1.5.7,<1.6.0a0 -license: Python-2.0 -size: 36702440 -timestamp: 1770675584356 -python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda -sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 -md5: 130584ad9f3a513cdd71b1fdc1244e9c -depends: -- python >=3.10 -license: BSD-3-Clause -license_family: BSD -size: 27848 -timestamp: 1772388605021 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda -sha256: 233aebd94c704ac112afefbb29cf4170b7bc606e22958906f2672081bc50638a -md5: 235765e4ea0d0301c75965985163b5a1 -depends: -- cpython 3.14.3.* -- python_abi * *_cp314 -license: Python-2.0 -size: 50062 -timestamp: 1770674497152 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 -sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 -md5: 310259a5b03ff02289d7705f39e2b1d2 -depends: -- kaleido-core 0.2.1.* -- python >=3.5 -license: MIT -license_family: MIT -size: 18320 -timestamp: 1615204747600 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda -build_number: 8 -sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 -md5: 0539938c55b6b1a59b560e843ad864a4 -constrains: -- python 3.14.* *_cp314 -license: BSD-3-Clause -license_family: BSD -size: 6989 -timestamp: 1752805904792 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda -sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d -md5: 2035f68f96be30dc60a5dfd7452c7941 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -- yaml >=0.2.5,<0.3.0a0 -license: MIT -license_family: MIT -size: 202391 -timestamp: 1770223462836 -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda -sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 -md5: d7d95fc8287ea7bf33e0e7116d2b95ec -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- ncurses >=6.5,<7.0a0 -license: GPL-3.0-only -license_family: GPL -size: 345073 -timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda -sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 -md5: 870293df500ca7e18bedefa5838a22ab -depends: -- attrs >=22.2.0 -- python >=3.10 -- rpds-py >=0.7.0 -- typing_extensions >=4.4.0 -- python -license: MIT -license_family: MIT -size: 51788 -timestamp: 1760379115194 -- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.2.28-py314h5bd0f2a_0.conda -sha256: e085e336f1446f5263a3ec9747df8c719b6996753901181add50dc4fdd8bb2e8 -md5: 3c8b6a8c4d0ff5a264e9831eac4941f4 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -license: Apache-2.0 AND CNRI-Python -license_family: PSF -size: 411924 -timestamp: 1772255161535 -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda -sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 -md5: c65df89a0b2e321045a9e01d1337b182 -depends: -- python >=3.10 -- certifi >=2017.4.17 -- charset-normalizer >=2,<4 -- idna >=2.5,<4 -- urllib3 >=1.21.1,<3 -- python -constrains: -- chardet >=3.0.2,<6 -license: Apache-2.0 -license_family: APACHE -size: 63602 -timestamp: 1766926974520 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda -sha256: b06ce84d6a10c266811a7d3adbfa1c11f13393b91cc6f8a5b468277d90be9590 -md5: 7a6289c50631d620652f5045a63eb573 -depends: -- markdown-it-py >=2.2.0 -- pygments >=2.13.0,<3.0.0 -- python >=3.10 -- typing_extensions >=4.0.0,<5.0.0 -- python -license: MIT -license_family: MIT -size: 208472 -timestamp: 1771572730357 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda -sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 -md5: 0c20a8ebcddb24a45da89d5e917e6cb9 -depends: -- python >=3.10 -- rich >=12 -- click >=8 -- typing-extensions >=4 -- __unix -- python -license: MIT -license_family: MIT -size: 64356 -timestamp: 1769850479089 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda -sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 -md5: c1c368b5437b0d1a68f372ccf01cb133 -depends: -- python -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -- python_abi 3.14.* *_cp314 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 376121 -timestamp: 1764543122774 -- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda -sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 -md5: 472239e4eb7b5a84bb96b3ed7e3a596a -depends: -- colormath >=3.0.0 -- python >=3.9 -license: MIT -license_family: MIT -size: 22284 -timestamp: 1735770589188 -- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.52.0-h04a0ce9_0.conda -sha256: c9af81e7830d9c4b67a7f48e512d060df2676b29cac59e3b31f09dbfcee29c58 -md5: 7d9d7efe9541d4bb71b5934e8ee348ea -depends: -- __glibc >=2.17,<3.0.a0 -- icu >=78.2,<79.0a0 -- libgcc >=14 -- libsqlite 3.52.0 hf4e2dac_0 -- libzlib >=1.3.1,<2.0a0 -- ncurses >=6.5,<7.0a0 -- readline >=8.3,<9.0a0 -license: blessing -size: 203641 -timestamp: 1772818888368 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda -sha256: 7e395d67fd249d901beb1ae269057763c0d8c3ee5f7a348694bdb16d158a37d9 -md5: d705f9d8a1185a2b01cced191177a028 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -- regex >=2022.1.18 -- requests >=2.26.0 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 939648 -timestamp: 1764028306357 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda -sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac -md5: cffd3bdd58090148f4cfcd831f4b26ab -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libzlib >=1.3.1,<2.0a0 -constrains: -- xorg-libx11 >=1.8.12,<2.0a0 -license: TCL -license_family: BSD -size: 3301196 -timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda -sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 -md5: e5ce43272193b38c2e9037446c1d9206 -depends: -- python >=3.10 -- __unix -- python -license: MPL-2.0 and MIT -size: 94132 -timestamp: 1770153424136 -- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda -sha256: 39d8ae33c43cdb8f771373e149b0b4fae5a08960ac58dcca95b2f1642bb17448 -md5: 260af1b0a94f719de76b4e14094e9a3b -depends: -- importlib-metadata >=3.6 -- python >=3.10 -- typing-extensions >=4.10.0 -- typing_extensions >=4.14.0 -constrains: -- pytest >=7 -license: MIT -license_family: MIT -size: 36838 -timestamp: 1771532971545 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda -sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c -md5: edd329d7d3a4ab45dcf905899a7a6115 -depends: -- typing_extensions ==4.15.0 pyhcf101f3_0 -license: PSF-2.0 -license_family: PSF -size: 91383 -timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda -sha256: 70db27de58a97aeb7ba7448366c9853f91b21137492e0b4430251a1870aa8ff4 -md5: a0a4a3035667fc34f29bfbd5c190baa6 -depends: -- python >=3.10 -- typing_extensions >=4.12.0 -license: MIT -license_family: MIT -size: 18923 -timestamp: 1764158430324 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda -sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 -md5: 0caa1af407ecff61170c9437a808404d -depends: -- python >=3.10 -- python -license: PSF-2.0 -license_family: PSF -size: 51692 -timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda -sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c -md5: ad659d0a2b3e47e38d829aa8cad2d610 -license: LicenseRef-Public-Domain -size: 119135 -timestamp: 1767016325805 -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda -sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a -md5: 9272daa869e03efe68833e3dc7a02130 -depends: -- backports.zstd >=1.0.0 -- brotli-python >=1.2.0 -- h2 >=4,<5 -- pysocks >=1.5.6,<2.0,!=1.5.7 -- python >=3.10 -license: MIT -license_family: MIT -size: 103172 -timestamp: 1767817860341 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda -sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b -md5: b2895afaf55bf96a8c8282a2e47a5de0 -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 15321 -timestamp: 1762976464266 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda -sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 -md5: 1dafce8548e38671bea82e3f5c6ce22f -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 20591 -timestamp: 1762976546182 -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda -sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad -md5: a77f85f77be52ff59391544bfe73390a -depends: -- libgcc >=14 -- __glibc >=2.17,<3.0.a0 -license: MIT -license_family: MIT -size: 85189 -timestamp: 1753484064210 -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda -sha256: b4533f7d9efc976511a73ef7d4a2473406d7f4c750884be8e8620b0ce70f4dae -md5: 30cd29cb87d819caead4d55184c1d115 -depends: -- python >=3.10 -- python -license: MIT -license_family: MIT -size: 24194 -timestamp: 1764460141901 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda -sha256: ea4e50c465d70236408cb0bfe0115609fd14db1adcd8bd30d8918e0291f8a75f -md5: 2aadb0d17215603a82a2a6b0afd9a4cb -depends: -- __glibc >=2.17,<3.0.a0 -- libgcc >=14 -- libstdcxx >=14 -license: Zlib -license_family: Other -size: 122618 -timestamp: 1770167931827 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda -sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 -md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 -depends: -- __glibc >=2.17,<3.0.a0 -- libzlib >=1.3.1,<2.0a0 -license: BSD-3-Clause -license_family: BSD -size: 601375 -timestamp: 1764777111296 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt deleted file mode 100644 index a55a4d4..0000000 --- a/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt +++ /dev/null @@ -1,126 +0,0 @@ - -# This file may be used to create an environment using: -# $ conda create --name --file -# platform: linux-64 -@EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda#2934f256a8acfe48f6ebb4fce6cde29c -https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 -https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c -https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda#7fe569c10905402ed47024fc481bb371 -https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda#b866ff7007b934d564961066c8195983 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 -https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda#071cf7b0ce333c81718b054066c15102 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.5-hecca717_0.conda#7de50d165039df32d38be74c1b34a910 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb -https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e -https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda#daddf757c3ecd6067b9af1df1f25d89e -https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda#c1c368b5437b0d1a68f372ccf01cb133 -https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab -https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2#86e69bd82c2a2c6fd29f5ab7e02b3691 -https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda#e235d5566c9cc8970eb2798dd4ecf62f -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee -https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.53.0-h04a0ce9_0.conda#dc540e5bd5616d83a1ec46af8315ff98 -https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2#b3723b235b0758abaae8c82ce4d80146 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f -https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 -https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda#ba0a9221ce1063f31692c07370d062f3 -https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 -https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda#e941e85e273121222580723010bd4fa2 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 -https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 -https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.40.0-py310hbcd5346_0.conda#03a6899e17bb731c8e21b08212f1a64c -https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda#ef0340e75068ac8ff96462749b5c98e7 -https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a -https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda#2035f68f96be30dc60a5dfd7452c7941 -https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda#e17be1016bcc3516827b836cd3e4d9dc -https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.3-py314h2e6c369_0.conda#1f3fd537f929b8d3236f9f0f0e7f7a32 -https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda#a0a4a3035667fc34f29bfbd5c190baa6 -https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.3-pyhcf101f3_0.conda#f690e6f204efd2e5c06b57518a383d98 -https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda#130584ad9f3a513cdd71b1fdc1244e9c -https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2#310259a5b03ff02289d7705f39e2b1d2 -https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 -https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda#0242025a3c804966bf71aa04eee82f66 -https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda#0c20a8ebcddb24a45da89d5e917e6cb9 -https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda#472239e4eb7b5a84bb96b3ed7e3a596a -https://conda.anaconda.org/conda-forge/linux-64/regex-2026.4.4-py314h5bd0f2a_0.conda#4ffb42385183c854564f1f9adcf80a63 -https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda#d705f9d8a1185a2b01cced191177a028 -https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda#e5ce43272193b38c2e9037446c1d9206 -https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda#260af1b0a94f719de76b4e14094e9a3b -https://conda.anaconda.org/bioconda/noarch/multiqc-1.34-pyhdfd78af_0.conda#a7111ab9a6a6146b40cbce16655ac873 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f -https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda#f2c23a77b25efcad57d377b34bd84941 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt deleted file mode 100644 index a58231a..0000000 --- a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-40bf3b435e89dc22_1.txt +++ /dev/null @@ -1,1502 +0,0 @@ - -version: 6 -environments: -default: -channels: -- url: https://conda.anaconda.org/conda-forge/ -- url: https://conda.anaconda.org/bioconda/ -- url: https://conda.anaconda.org/bioconda/ -options: -pypi-prerelease-mode: if-necessary-or-explicit -packages: -linux-aarch64: -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.4-hfae3067_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py314hac3e5ec_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.39.3-py310hff09b76_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.39.3-py310hf00a4a2_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.41.5-py314h451b6cc_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.2.28-py314h51f160d_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.52.0-hf1c7be2_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda -packages: -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda -build_number: 20 -sha256: a2527b1d81792a0ccd2c05850960df119c2b6d8f5fdec97f2db7d25dc23b1068 -md5: 468fd3bb9e1f671d36c2cbc677e56f1d -depends: -- libgomp >=7.5.0 -constrains: -- openmp_impl <0.0a0 -license: BSD-3-Clause -license_family: BSD -size: 28926 -timestamp: 1770939656741 -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda -sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 -md5: aaa2a381ccc56eac91d63b6c1240312f -depends: -- cpython -- python-gil -license: MIT -license_family: MIT -size: 8191 -timestamp: 1744137672556 -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda -sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 -md5: 2934f256a8acfe48f6ebb4fce6cde29c -depends: -- python >=3.9 -- typing-extensions >=4.0.0 -license: MIT -license_family: MIT -size: 18074 -timestamp: 1733247158254 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda -sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab -md5: c6b0543676ecb1fb2d7643941fe375f2 -depends: -- python >=3.10 -- python -license: MIT -license_family: MIT -size: 64927 -timestamp: 1773935801332 -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda -noarch: generic -sha256: c31ab719d256bc6f89926131e88ecd0f0c5d003fe8481852c6424f4ec6c7eb29 -md5: a2ac7763a9ac75055b68f325d3255265 -depends: -- python >=3.14 -license: BSD-3-Clause AND MIT AND EPL-2.0 -size: 7514 -timestamp: 1767044983590 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda -sha256: 5a5b0cdcd7ed89c6a8fb830924967f6314a2b71944bc1ebc2c105781ba97aa75 -md5: a1b5c571a0923a205d663d8678df4792 -depends: -- libgcc >=14 -- libstdcxx >=14 -- python >=3.14,<3.15.0a0 -- python >=3.14,<3.15.0a0 *_cp314 -- python_abi 3.14.* *_cp314 -constrains: -- libbrotlicommon 1.2.0 he30d5cf_1 -license: MIT -license_family: MIT -size: 373193 -timestamp: 1764017486851 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda -sha256: b3495077889dde6bb370938e7db82be545c73e8589696ad0843a32221520ad4c -md5: 840d8fc0d7b3209be93080bc20e07f2d -depends: -- libgcc >=14 -license: bzip2-1.0.6 -license_family: BSD -size: 192412 -timestamp: 1771350241232 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda -sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc -md5: 4492fd26db29495f0ba23f146cd5638d -depends: -- __unix -license: ISC -size: 147413 -timestamp: 1772006283803 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda -sha256: a6b118fd1ed6099dc4fc03f9c492b88882a780fadaef4ed4f93dc70757713656 -md5: 765c4d97e877cdbbb88ff33152b86125 -depends: -- python >=3.10 -license: ISC -size: 151445 -timestamp: 1772001170301 -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda -sha256: d86dfd428b2e3c364fa90e07437c8405d635aa4ef54b25ab51d9c712be4112a5 -md5: 49ee13eb9b8f44d63879c69b8a40a74b -depends: -- python >=3.10 -license: MIT -license_family: MIT -size: 58510 -timestamp: 1773660086450 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda -sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 -md5: ea8a6c3256897cc31263de9f455e25d9 -depends: -- python >=3.10 -- __unix -- python -license: BSD-3-Clause -license_family: BSD -size: 97676 -timestamp: 1764518652276 -- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda -sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 -md5: b866ff7007b934d564961066c8195983 -depends: -- humanfriendly >=9.1 -- python >=3.9 -license: MIT -license_family: MIT -size: 43758 -timestamp: 1733928076798 -- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda -sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 -md5: 071cf7b0ce333c81718b054066c15102 -depends: -- networkx >=2.0 -- numpy -- python >=3.9 -license: BSD-3-Clause -license_family: BSD -size: 39326 -timestamp: 1735759976140 -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda -noarch: generic -sha256: 91b06300879df746214f7363d6c27c2489c80732e46a369eb2afc234bcafb44c -md5: 3bb89e4f795e5414addaa531d6b1500a -depends: -- python >=3.14,<3.15.0a0 -- python_abi * *_cp314 -license: Python-2.0 -size: 50078 -timestamp: 1770674447292 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.4-hfae3067_0.conda -sha256: 5f087bef054c681edcaae84a8c2230585b938691e371ff92957a30707b7fcdf7 -md5: b304307db639831ad7caabd2eac6fca6 -depends: -- libexpat 2.7.4 hfae3067_0 -- libgcc >=14 -license: MIT -license_family: MIT -size: 137701 -timestamp: 1771259543650 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 -sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b -md5: 0c96522c6bdaed4b1566d11387caaf45 -license: BSD-3-Clause -license_family: BSD -size: 397370 -timestamp: 1566932522327 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 -sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c -md5: 34893075a5c9e55cdafac56607368fc6 -license: OFL-1.1 -license_family: Other -size: 96530 -timestamp: 1620479909603 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 -sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 -md5: 4d59c254e01d9cde7957100457e2d5fb -license: OFL-1.1 -license_family: Other -size: 700814 -timestamp: 1620479612257 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda -sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 -md5: 49023d73832ef61042f6a237cb2687e7 -license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 -license_family: Other -size: 1620504 -timestamp: 1727511233259 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda -sha256: 835aff8615dd8d8fff377679710ce81b8a2c47b6404e21a92fb349fda193a15c -md5: 0fed1ff55f4938a65907f3ecf62609db -depends: -- libexpat >=2.7.4,<3.0a0 -- libfreetype >=2.14.1 -- libfreetype6 >=2.14.1 -- libgcc >=14 -- libuuid >=2.41.3,<3.0a0 -- libzlib >=1.3.1,<2.0a0 -license: MIT -license_family: MIT -size: 279044 -timestamp: 1771382728182 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda -sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 -md5: a7970cd949a077b7cb9696379d338681 -depends: -- font-ttf-ubuntu -- font-ttf-inconsolata -- font-ttf-dejavu-sans-mono -- font-ttf-source-code-pro -license: BSD-3-Clause -license_family: BSD -size: 4059 -timestamp: 1762351264405 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda -sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 -md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 -depends: -- python >=3.10 -- hyperframe >=6.1,<7 -- hpack >=4.1,<5 -- python -license: MIT -license_family: MIT -size: 95967 -timestamp: 1756364871835 -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda -sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba -md5: 0a802cb9888dd14eeefc611f05c40b6e -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 30731 -timestamp: 1737618390337 -- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda -sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d -md5: 7fe569c10905402ed47024fc481bb371 -depends: -- __unix -- python >=3.9 -license: MIT -license_family: MIT -size: 73563 -timestamp: 1733928021866 -- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda -sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 -md5: daddf757c3ecd6067b9af1df1f25d89e -depends: -- python >=3.10 -license: MIT -license_family: MIT -size: 67994 -timestamp: 1766267728652 -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda -sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 -md5: 8e6923fc12f1fe8f8c4e5c9f343256ac -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 17397 -timestamp: 1737618427549 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda -sha256: 49ba6aed2c6b482bb0ba41078057555d29764299bc947b990708617712ef6406 -md5: 546da38c2fa9efacf203e2ad3f987c59 -depends: -- libgcc >=14 -- libstdcxx >=14 -license: MIT -license_family: MIT -size: 12837286 -timestamp: 1773822650615 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda -sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 -md5: 53abe63df7e10a6ba605dc5f9f961d36 -depends: -- python >=3.10 -license: BSD-3-Clause -license_family: BSD -size: 50721 -timestamp: 1760286526795 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda -sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 -md5: 080594bf4493e6bae2607e65390c520a -depends: -- python >=3.10 -- zipp >=3.20 -- python -license: Apache-2.0 -license_family: APACHE -size: 34387 -timestamp: 1773931568510 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda -sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b -md5: 04558c96691bed63104678757beb4f8d -depends: -- markupsafe >=2.0 -- python >=3.10 -- python -license: BSD-3-Clause -license_family: BSD -size: 120685 -timestamp: 1764517220861 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda -sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 -md5: ada41c863af263cc4c5fcbaff7c3e4dc -depends: -- attrs >=22.2.0 -- jsonschema-specifications >=2023.3.6 -- python >=3.10 -- referencing >=0.28.4 -- rpds-py >=0.25.0 -- python -license: MIT -license_family: MIT -size: 82356 -timestamp: 1767839954256 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda -sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 -md5: 439cd0f567d697b20a8f45cb70a1005a -depends: -- python >=3.10 -- referencing >=0.31.0 -- python -license: MIT -license_family: MIT -size: 19236 -timestamp: 1757335715225 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 -sha256: d3c7f4797566e6f983d16c2a87063a18e4b2d819a66230190a21584d70042755 -md5: 4f0d284f5d11e04277b552eb1c172c7f -depends: -- __glibc >=2.17,<3.0.a0 -- expat >=2.2.10,<3.0.0a0 -- fontconfig -- fonts-conda-forge -- libgcc-ng >=9.3.0 -- mathjax 2.7.* -- nspr >=4.29,<5.0a0 -- nss >=3.62,<4.0a0 -- sqlite >=3.34.0,<4.0a0 -license: MIT -license_family: MIT -size: 65750397 -timestamp: 1615199465742 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda -sha256: 379ef5e91a587137391a6149755d0e929f1a007d2dcb211318ac670a46c8596f -md5: bb960f01525b5e001608afef9d47b79c -depends: -- libgcc >=14 -- libjpeg-turbo >=3.1.2,<4.0a0 -- libtiff >=4.7.1,<4.8.0a0 -license: MIT -license_family: MIT -size: 293039 -timestamp: 1768184778398 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda -sha256: 7abd913d81a9bf00abb699e8987966baa2065f5132e37e815f92d90fc6bba530 -md5: a21644fc4a83da26452a718dc9468d5f -depends: -- zstd >=1.5.7,<1.6.0a0 -constrains: -- binutils_impl_linux-aarch64 2.45.1 -license: GPL-3.0-only -license_family: GPL -size: 875596 -timestamp: 1774197520746 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda -sha256: 8957fd460c1c132c8031f65fd5f56ec3807fd71b7cab2c5e2b0937b13404ab36 -md5: d13423b06447113a90b5b1366d4da171 -depends: -- libgcc >=14 -- libstdcxx >=14 -license: Apache-2.0 -license_family: Apache -size: 240444 -timestamp: 1773114901155 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda -build_number: 5 -sha256: 700f3c03d0fba8e687a345404a45fbabe781c1cf92242382f62cef2948745ec4 -md5: 5afcea37a46f76ec1322943b3c4dfdc0 -depends: -- libopenblas >=0.3.30,<0.3.31.0a0 -- libopenblas >=0.3.30,<1.0a0 -constrains: -- mkl <2026 -- libcblas 3.11.0 5*_openblas -- liblapack 3.11.0 5*_openblas -- liblapacke 3.11.0 5*_openblas -- blas 2.305 openblas -license: BSD-3-Clause -license_family: BSD -size: 18369 -timestamp: 1765818610617 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda -build_number: 5 -sha256: 3fad5c9de161dccb4e42c8b1ae8eccb33f4ed56bccbcced9cbb0956ae7869e61 -md5: 0b2f1143ae2d0aa4c991959d0daaf256 -depends: -- libblas 3.11.0 5_haddc8a3_openblas -constrains: -- liblapack 3.11.0 5*_openblas -- liblapacke 3.11.0 5*_openblas -- blas 2.305 openblas -license: BSD-3-Clause -license_family: BSD -size: 18371 -timestamp: 1765818618899 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda -sha256: 48814b73bd462da6eed2e697e30c060ae16af21e9fbed30d64feaf0aad9da392 -md5: a9138815598fe6b91a1d6782ca657b0c -depends: -- libgcc >=14 -license: MIT -license_family: MIT -size: 71117 -timestamp: 1761979776756 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda -sha256: 995ce3ad96d0f4b5ed6296b051a0d7b6377718f325bc0e792fbb96b0e369dad7 -md5: 57f3b3da02a50a1be2a6fe847515417d -depends: -- libgcc >=14 -constrains: -- expat 2.7.4.* -license: MIT -license_family: MIT -size: 76564 -timestamp: 1771259530958 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda -sha256: 3df4c539449aabc3443bbe8c492c01d401eea894603087fca2917aa4e1c2dea9 -md5: 2f364feefb6a7c00423e80dcb12db62a -depends: -- libgcc >=14 -license: MIT -license_family: MIT -size: 55952 -timestamp: 1769456078358 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda -sha256: 752e4f66283d7deb4c6fd47d88df644d8daa2aaa825a54f3bf350a625190192a -md5: a229e22d4d8814a07702b0919d8e6701 -depends: -- libfreetype6 >=2.14.3 -license: GPL-2.0-only OR FTL -size: 8125 -timestamp: 1774301094057 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda -sha256: 8e6b27fe4eec4c2fa7b7769a21973734c8dba1de80086fb0213e58375ac09f4c -md5: b99ed99e42dafb27889483b3098cace7 -depends: -- libgcc >=14 -- libpng >=1.6.55,<1.7.0a0 -- libzlib >=1.3.2,<2.0a0 -constrains: -- freetype >=2.14.3 -license: GPL-2.0-only OR FTL -size: 422941 -timestamp: 1774301093473 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda -sha256: 43df385bedc1cab11993c4369e1f3b04b4ca5d0ea16cba6a0e7f18dbc129fcc9 -md5: 552567ea2b61e3a3035759b2fdb3f9a6 -depends: -- _openmp_mutex >=4.5 -constrains: -- libgcc-ng ==15.2.0=*_18 -- libgomp 15.2.0 h8acb6b2_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 622900 -timestamp: 1771378128706 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda -sha256: 83bb0415f59634dccfa8335d4163d1f6db00a27b36666736f9842b650b92cf2f -md5: 4feebd0fbf61075a1a9c2e9b3936c257 -depends: -- libgcc 15.2.0 h8acb6b2_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 27568 -timestamp: 1771378136019 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda -sha256: 7dcd7dff2505d56fd5272a6e712ec912f50a46bf07dc6873a7e853694304e6e4 -md5: 41f261f5e4e2e8cbd236c2f1f15dae1b -depends: -- libgfortran5 15.2.0 h1b7bec0_18 -constrains: -- libgfortran-ng ==15.2.0=*_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 27587 -timestamp: 1771378169244 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda -sha256: 85347670dfb4a8d4c13cd7cae54138dcf2b1606b6bede42eef5507bf5f9660c6 -md5: 574d88ce3348331e962cfa5ed451b247 -depends: -- libgcc >=15.2.0 -constrains: -- libgfortran 15.2.0 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 1486341 -timestamp: 1771378148102 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda -sha256: fc716f11a6a8525e27a5d332ef6a689210b0d2a4dd1133edc0f530659aa9faa6 -md5: 4faa39bf919939602e594253bd673958 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 588060 -timestamp: 1771378040807 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda -sha256: 84064c7c53a64291a585d7215fe95ec42df74203a5bf7615d33d49a3b0f08bb6 -md5: 5109d7f837a3dfdf5c60f60e311b041f -depends: -- libgcc >=14 -constrains: -- jpeg <0.0.0a -license: IJG AND BSD-3-Clause AND Zlib -size: 691818 -timestamp: 1762094728337 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda -build_number: 5 -sha256: 692222d186d3ffbc99eaf04b5b20181fd26aee1edec1106435a0a755c57cce86 -md5: 88d1e4133d1182522b403e9ba7435f04 -depends: -- libblas 3.11.0 5_haddc8a3_openblas -constrains: -- liblapacke 3.11.0 5*_openblas -- blas 2.305 openblas -- libcblas 3.11.0 5*_openblas -license: BSD-3-Clause -license_family: BSD -size: 18392 -timestamp: 1765818627104 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda -sha256: 843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3 -md5: 96944e3c92386a12755b94619bae0b35 -depends: -- libgcc >=14 -constrains: -- xz 5.8.2.* -license: 0BSD -size: 125916 -timestamp: 1768754941722 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda -sha256: 57c0dd12d506e84541c4e877898bd2a59cca141df493d34036f18b2751e0a453 -md5: 7b9813e885482e3ccb1fa212b86d7fd0 -depends: -- libgcc >=14 -license: BSD-2-Clause -license_family: BSD -size: 114056 -timestamp: 1769482343003 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda -sha256: 794a7270ea049ec931537874cd8d2de0ef4b3cef71c055cfd8b4be6d2f4228b0 -md5: 11d7d57b7bdd01da745bbf2b67020b2e -depends: -- libgcc >=14 -- libgfortran -- libgfortran5 >=14.3.0 -constrains: -- openblas >=0.3.30,<0.3.31.0a0 -license: BSD-3-Clause -license_family: BSD -size: 4959359 -timestamp: 1763114173544 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda -sha256: c7378c6b79de4d571d00ad1caf0a4c19d43c9c94077a761abb6ead44d891f907 -md5: be4088903b94ea297975689b3c3aeb27 -depends: -- libgcc >=14 -- libzlib >=1.3.1,<2.0a0 -license: zlib-acknowledgement -size: 340156 -timestamp: 1770691477245 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda -sha256: 1ddaf91b44fae83856276f4cb7ce544ffe41d4b55c1e346b504c6b45f19098d6 -md5: 77891484f18eca74b8ad83694da9815e -depends: -- icu >=78.2,<79.0a0 -- libgcc >=14 -- libzlib >=1.3.1,<2.0a0 -license: blessing -size: 952296 -timestamp: 1772818881550 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda -sha256: 31fdb9ffafad106a213192d8319b9f810e05abca9c5436b60e507afb35a6bc40 -md5: f56573d05e3b735cb03efeb64a15f388 -depends: -- libgcc 15.2.0 h8acb6b2_18 -constrains: -- libstdcxx-ng ==15.2.0=*_18 -license: GPL-3.0-only WITH GCC-exception-3.1 -license_family: GPL -size: 5541411 -timestamp: 1771378162499 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda -sha256: 7ff79470db39e803e21b8185bc8f19c460666d5557b1378d1b1e857d929c6b39 -md5: 8c6fd84f9c87ac00636007c6131e457d -depends: -- lerc >=4.0.0,<5.0a0 -- libdeflate >=1.25,<1.26.0a0 -- libgcc >=14 -- libjpeg-turbo >=3.1.0,<4.0a0 -- liblzma >=5.8.1,<6.0a0 -- libstdcxx >=14 -- libwebp-base >=1.6.0,<2.0a0 -- libzlib >=1.3.1,<2.0a0 -- zstd >=1.5.7,<1.6.0a0 -license: HPND -size: 488407 -timestamp: 1762022048105 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda -sha256: c37a8e89b700646f3252608f8368e7eb8e2a44886b92776e57ad7601fc402a11 -md5: cf2861212053d05f27ec49c3784ff8bb -depends: -- libgcc >=14 -license: BSD-3-Clause -license_family: BSD -size: 43453 -timestamp: 1766271546875 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda -sha256: b03700a1f741554e8e5712f9b06dd67e76f5301292958cd3cb1ac8c6fdd9ed25 -md5: 24e92d0942c799db387f5c9d7b81f1af -depends: -- libgcc >=14 -constrains: -- libwebp 1.6.0 -license: BSD-3-Clause -license_family: BSD -size: 359496 -timestamp: 1752160685488 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda -sha256: 461cab3d5650ac6db73a367de5c8eca50363966e862dcf60181d693236b1ae7b -md5: cd14ee5cca2464a425b1dbfc24d90db2 -depends: -- libgcc >=13 -- pthread-stubs -- xorg-libxau >=1.0.11,<2.0a0 -- xorg-libxdmcp -license: MIT -license_family: MIT -size: 397493 -timestamp: 1727280745441 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda -sha256: eb111e32e5a7313a5bf799c7fb2419051fa2fe7eff74769fac8d5a448b309f7f -md5: 502006882cf5461adced436e410046d1 -constrains: -- zlib 1.3.2 *_2 -license: Zlib -license_family: Other -size: 69833 -timestamp: 1774072605429 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda -sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b -md5: ba0a9221ce1063f31692c07370d062f3 -depends: -- importlib-metadata >=4.4 -- python >=3.10 -- python -license: BSD-3-Clause -license_family: BSD -size: 85893 -timestamp: 1770694658918 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda -sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e -md5: 5b5203189eb668f042ac2b0826244964 -depends: -- mdurl >=0.1,<1 -- python >=3.10 -license: MIT -license_family: MIT -size: 64736 -timestamp: 1754951288511 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda -sha256: 383c188496d13a55658c06e61e7d4cdff2c9f9d5a0648769fca8250bece7e0ef -md5: e5de3c36dd548b35ff2a8aa49208dcb3 -depends: -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -constrains: -- jinja2 >=3.0.0 -license: BSD-3-Clause -license_family: BSD -size: 27913 -timestamp: 1772446407659 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 -sha256: 8fd4c79d6eda3d4cba73783114305a53a154ada4d1e334d4e02cb3521429599b -md5: 7b08314a6867a9d5648a1c3265e9eb8e -license: Apache-2.0 -license_family: Apache -size: 22257008 -timestamp: 1662784555011 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda -sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 -md5: 592132998493b3ff25fd7479396e8351 -depends: -- python >=3.9 -license: MIT -license_family: MIT -size: 14465 -timestamp: 1733255681319 -- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.33-pyhdfd78af_0.conda -sha256: f005760b13093362fc9c997d603dd487de32ab2e821a3cbce52a42bcb8136517 -md5: 698a8a27c2b9d8a542c70cb47099a75e -depends: -- click -- coloredlogs -- humanize -- importlib-metadata -- jinja2 >=3.0.0 -- jsonschema -- markdown -- natsort -- numpy -- packaging -- pillow >=10.2.0 -- plotly >=5.18 -- polars-lts-cpu -- pyaml-env -- pydantic >=2.7.1 -- python >=3.8,!=3.14.1 -- python-dotenv -- python-kaleido 0.2.1 -- pyyaml >=4 -- requests -- rich >=10 -- rich-click -- spectra >=0.0.10 -- tiktoken -- tqdm -- typeguard -license: GPL-3.0-or-later -license_family: GPL3 -size: 4198799 -timestamp: 1765300743879 -- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda -sha256: 541fd4390a0687228b8578247f1536a821d9261389a65585af9d1a6f2a14e1e0 -md5: 30bec5e8f4c3969e2b1bd407c5e52afb -depends: -- python >=3.10 -- python -license: MIT -size: 280459 -timestamp: 1774380620329 -- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda -sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 -md5: e941e85e273121222580723010bd4fa2 -depends: -- python >=3.9 -- python -license: MIT -license_family: MIT -size: 39262 -timestamp: 1770905275632 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda -sha256: 91cfb655a68b0353b2833521dc919188db3d8a7f4c64bea2c6a7557b24747468 -md5: 182afabe009dc78d8b73100255ee6868 -depends: -- libgcc >=13 -license: X11 AND BSD-3-Clause -size: 926034 -timestamp: 1738196018799 -- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda -sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 -md5: a2c1eeadae7a309daed9d62c96012a2b -depends: -- python >=3.11 -- python -constrains: -- numpy >=1.25 -- scipy >=1.11.2 -- matplotlib-base >=3.8 -- pandas >=2.0 -license: BSD-3-Clause -license_family: BSD -size: 1587439 -timestamp: 1765215107045 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda -sha256: 78a06e89285fef242e272998b292c1e621e3ee3dd4fba62ec014e503c7ec118f -md5: 6dd4f07147774bf720075a210f8026b9 -depends: -- libgcc >=14 -- libstdcxx >=14 -license: MPL-2.0 -license_family: MOZILLA -size: 235140 -timestamp: 1762350120355 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda -sha256: 48942696889367ffd448f8dccfc080fb7e130b9938a4a3b6b20ef8e6af856463 -md5: 4540f9570d12db2150f42ba036154552 -depends: -- libgcc >=14 -- libsqlite >=3.51.0,<4.0a0 -- libstdcxx >=14 -- libzlib >=1.3.1,<2.0a0 -- nspr >=4.38,<5.0a0 -license: MPL-2.0 -license_family: MOZILLA -size: 2061869 -timestamp: 1763490303490 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda -sha256: a6d42fd88afc57c3b0a57b21a12eff7492dfc419bb61ee3f74e9ba6261dabc88 -md5: 25d896c331481145720a21e5145fad65 -depends: -- python -- libgcc >=14 -- python 3.14.* *_cp314 -- libstdcxx >=14 -- libcblas >=3.9.0,<4.0a0 -- liblapack >=3.9.0,<4.0a0 -- python_abi 3.14.* *_cp314 -- libblas >=3.9.0,<4.0a0 -constrains: -- numpy-base <0a0 -license: BSD-3-Clause -license_family: BSD -size: 8008045 -timestamp: 1773839355275 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda -sha256: bd1bc8bdde5e6c5cbac42d462b939694e40b59be6d0698f668515908640c77b8 -md5: cea962410e327262346d48d01f05936c -depends: -- libgcc >=14 -- libpng >=1.6.50,<1.7.0a0 -- libstdcxx >=14 -- libtiff >=4.7.1,<4.8.0a0 -- libzlib >=1.3.1,<2.0a0 -license: BSD-2-Clause -license_family: BSD -size: 392636 -timestamp: 1758489353577 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda -sha256: 7f8048c0e75b2620254218d72b4ae7f14136f1981c5eb555ef61645a9344505f -md5: 25f5885f11e8b1f075bccf4a2da91c60 -depends: -- ca-certificates -- libgcc >=14 -license: Apache-2.0 -license_family: Apache -size: 3692030 -timestamp: 1769557678657 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda -sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 -md5: b76541e68fea4d511b1ac46a28dcd2c6 -depends: -- python >=3.8 -- python -license: Apache-2.0 -license_family: APACHE -size: 72010 -timestamp: 1769093650580 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py314hac3e5ec_0.conda -sha256: 1ca2d1616baad9bccb7ebc425ef2dcd6cebe742fbe91edf226fb606ad371ca0f -md5: d3c959c7efe560b2d7da459d69121fe9 -depends: -- python -- python 3.14.* *_cp314 -- libgcc >=14 -- zlib-ng >=2.3.3,<2.4.0a0 -- libwebp-base >=1.6.0,<2.0a0 -- tk >=8.6.13,<8.7.0a0 -- libfreetype >=2.14.1 -- libfreetype6 >=2.14.1 -- libtiff >=4.7.1,<4.8.0a0 -- lcms2 >=2.18,<3.0a0 -- python_abi 3.14.* *_cp314 -- openjpeg >=2.5.4,<3.0a0 -- libjpeg-turbo >=3.1.2,<4.0a0 -- libxcb >=1.17.0,<2.0a0 -license: HPND -size: 1051828 -timestamp: 1770794010335 -- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda -sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 -md5: 3e9427ee186846052e81fadde8ebe96a -depends: -- narwhals >=1.15.1 -- packaging -- python >=3.10 -constrains: -- ipywidgets >=7.6 -license: MIT -license_family: MIT -size: 5251872 -timestamp: 1772628857717 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda -sha256: d332c2d5002fc440ae37ed9679ffc21b552f18d20232390005d1dd3bce0888d3 -md5: d5a4e013a30dd8dfde9ab39f45aaf9c1 -depends: -- polars-runtime-32 ==1.39.3 -- python >=3.10 -- python -constrains: -- numpy >=1.16.0 -- pyarrow >=7.0.0 -- fastexcel >=0.9 -- openpyxl >=3.0.0 -- xlsx2csv >=0.8.0 -- connectorx >=0.3.2 -- deltalake >=1.0.0 -- pyiceberg >=0.7.1 -- altair >=5.4.0 -- great_tables >=0.8.0 -- polars-runtime-32 ==1.39.3 -- polars-runtime-64 ==1.39.3 -- polars-runtime-compat ==1.39.3 -license: MIT -license_family: MIT -size: 533495 -timestamp: 1774207987966 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda -sha256: e466fb31f67ba9bde18deafeb34263ca5eb25807f39ead0e9d753a8e82c4c4f4 -md5: ef0340e75068ac8ff96462749b5c98e7 -depends: -- polars >=1.34.0 -- polars-runtime-compat >=1.34.0 -license: MIT -license_family: MIT -size: 3902 -timestamp: 1760206808444 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.39.3-py310hff09b76_1.conda -noarch: python -sha256: c070be507c5a90df397a47ae0299660be437d5546d68f1bc0fa4402c9f07d59e -md5: 3c1a7c6b4ba8b9fb773ace9723f8a5db -depends: -- python -- libgcc >=14 -- libstdcxx >=14 -- _python_abi3_support 1.* -- cpython >=3.10 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 34785466 -timestamp: 1774207998285 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.39.3-py310hf00a4a2_1.conda -noarch: python -sha256: 683315f1a49e47ce72bf9462419733b40b588b2b3106552d95fd4cd994e174de -md5: dd3464e2132dc3a783e76e5078870c76 -depends: -- python -- libgcc >=14 -- libstdcxx >=14 -- _python_abi3_support 1.* -- cpython >=3.10 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 34652491 -timestamp: 1774207996879 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda -sha256: e9cbcbc94e151ada3d6dc365380aaaf591f65012c16d9a2abaea4b9b90adc402 -md5: ab7288cc39545556d1bc5e71ab2df9a9 -depends: -- libgcc >=14 -- ncurses >=6.5,<7.0a0 -license: GPL-2.0-or-later AND LGPL-2.0-or-later -license_family: GPL -size: 636733 -timestamp: 1769712412683 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda -sha256: 977dfb0cb3935d748521dd80262fe7169ab82920afd38ed14b7fee2ea5ec01ba -md5: bb5a90c93e3bac3d5690acf76b4a6386 -depends: -- libgcc >=13 -license: MIT -license_family: MIT -size: 8342 -timestamp: 1726803319942 -- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda -sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 -md5: e17be1016bcc3516827b836cd3e4d9dc -depends: -- python >=3.9 -- pyyaml >=5.0,<=7.0 -license: MIT -license_family: MIT -size: 14645 -timestamp: 1736766960536 -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.5-pyhcf101f3_1.conda -sha256: 868569d9505b7fe246c880c11e2c44924d7613a8cdcc1f6ef85d5375e892f13d -md5: c3946ed24acdb28db1b5d63321dbca7d -depends: -- typing-inspection >=0.4.2 -- typing_extensions >=4.14.1 -- python >=3.10 -- typing-extensions >=4.6.1 -- annotated-types >=0.6.0 -- pydantic-core ==2.41.5 -- python -license: MIT -license_family: MIT -size: 340482 -timestamp: 1764434463101 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.41.5-py314h451b6cc_1.conda -sha256: f8acb2d03ebe80fed0032b9a989fc9acfb6735e3cd3f8c704b72728cb31868f6 -md5: 28f5027a1e04d67aa13fac1c5ba79693 -depends: -- python -- typing-extensions >=4.6.0,!=4.7.0 -- libgcc >=14 -- python 3.14.* *_cp314 -- python_abi 3.14.* *_cp314 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 1828339 -timestamp: 1762989038561 -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda -sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a -md5: 6b6ece66ebcae2d5f326c77ef2c5a066 -depends: -- python >=3.9 -license: BSD-2-Clause -license_family: BSD -size: 889287 -timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda -sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 -md5: 461219d1a5bd61342293efa2c0c90eac -depends: -- __unix -- python >=3.9 -license: BSD-3-Clause -license_family: BSD -size: 21085 -timestamp: 1733217331982 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda -build_number: 101 -sha256: 87e9dff5646aba87cecfbc08789634c855871a7325169299d749040b0923a356 -md5: 205011b36899ff0edf41b3db0eda5a44 -depends: -- bzip2 >=1.0.8,<2.0a0 -- ld_impl_linux-aarch64 >=2.36.1 -- libexpat >=2.7.3,<3.0a0 -- libffi >=3.5.2,<3.6.0a0 -- libgcc >=14 -- liblzma >=5.8.2,<6.0a0 -- libmpdec >=4.0.0,<5.0a0 -- libsqlite >=3.51.2,<4.0a0 -- libuuid >=2.41.3,<3.0a0 -- libzlib >=1.3.1,<2.0a0 -- ncurses >=6.5,<7.0a0 -- openssl >=3.5.5,<4.0a0 -- python_abi 3.14.* *_cp314 -- readline >=8.3,<9.0a0 -- tk >=8.6.13,<8.7.0a0 -- tzdata -- zstd >=1.5.7,<1.6.0a0 -license: Python-2.0 -size: 37305578 -timestamp: 1770674395875 -python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda -sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 -md5: 130584ad9f3a513cdd71b1fdc1244e9c -depends: -- python >=3.10 -license: BSD-3-Clause -license_family: BSD -size: 27848 -timestamp: 1772388605021 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda -sha256: 233aebd94c704ac112afefbb29cf4170b7bc606e22958906f2672081bc50638a -md5: 235765e4ea0d0301c75965985163b5a1 -depends: -- cpython 3.14.3.* -- python_abi * *_cp314 -license: Python-2.0 -size: 50062 -timestamp: 1770674497152 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 -sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 -md5: 310259a5b03ff02289d7705f39e2b1d2 -depends: -- kaleido-core 0.2.1.* -- python >=3.5 -license: MIT -license_family: MIT -size: 18320 -timestamp: 1615204747600 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda -build_number: 8 -sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 -md5: 0539938c55b6b1a59b560e843ad864a4 -constrains: -- python 3.14.* *_cp314 -license: BSD-3-Clause -license_family: BSD -size: 6989 -timestamp: 1752805904792 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda -sha256: 496b5e65dfdd0aaaaa5de0dcaaf3bceea00fcb4398acf152f89e567c82ec1046 -md5: 9ae2c92975118058bd720e9ba2bb7c58 -depends: -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python >=3.14,<3.15.0a0 *_cp314 -- python_abi 3.14.* *_cp314 -- yaml >=0.2.5,<0.3.0a0 -license: MIT -license_family: MIT -size: 195678 -timestamp: 1770223441816 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda -sha256: fe695f9d215e9a2e3dd0ca7f56435ab4df24f5504b83865e3d295df36e88d216 -md5: 3d49cad61f829f4f0e0611547a9cda12 -depends: -- libgcc >=14 -- ncurses >=6.5,<7.0a0 -license: GPL-3.0-only -license_family: GPL -size: 357597 -timestamp: 1765815673644 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda -sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 -md5: 870293df500ca7e18bedefa5838a22ab -depends: -- attrs >=22.2.0 -- python >=3.10 -- rpds-py >=0.7.0 -- typing_extensions >=4.4.0 -- python -license: MIT -license_family: MIT -size: 51788 -timestamp: 1760379115194 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.2.28-py314h51f160d_0.conda -sha256: 2080ecea825e1ef91a2422cc0bc63e85db9e38908ed17657fb8f41de7a6eee71 -md5: 818aa2c9f6b3c808da5e7be22a9a424c -depends: -- libgcc >=14 -- python >=3.14,<3.15.0a0 -- python >=3.14,<3.15.0a0 *_cp314 -- python_abi 3.14.* *_cp314 -license: Apache-2.0 AND CNRI-Python -license_family: PSF -size: 408097 -timestamp: 1772255205521 -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda -sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 -md5: c65df89a0b2e321045a9e01d1337b182 -depends: -- python >=3.10 -- certifi >=2017.4.17 -- charset-normalizer >=2,<4 -- idna >=2.5,<4 -- urllib3 >=1.21.1,<3 -- python -constrains: -- chardet >=3.0.2,<6 -license: Apache-2.0 -license_family: APACHE -size: 63602 -timestamp: 1766926974520 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.3.3-pyhcf101f3_0.conda -sha256: b06ce84d6a10c266811a7d3adbfa1c11f13393b91cc6f8a5b468277d90be9590 -md5: 7a6289c50631d620652f5045a63eb573 -depends: -- markdown-it-py >=2.2.0 -- pygments >=2.13.0,<3.0.0 -- python >=3.10 -- typing_extensions >=4.0.0,<5.0.0 -- python -license: MIT -license_family: MIT -size: 208472 -timestamp: 1771572730357 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda -sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 -md5: 0c20a8ebcddb24a45da89d5e917e6cb9 -depends: -- python >=3.10 -- rich >=12 -- click >=8 -- typing-extensions >=4 -- __unix -- python -license: MIT -license_family: MIT -size: 64356 -timestamp: 1769850479089 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda -sha256: a587240f16eac7c6a80f9585cef679cd1cb9a287b8dfcdd36dcef1f7e7db15dc -md5: e7f6ed9e60043bb5cbcc527764897f0d -depends: -- python -- libgcc >=14 -- python_abi 3.14.* *_cp314 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 376332 -timestamp: 1764543345455 -- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda -sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 -md5: 472239e4eb7b5a84bb96b3ed7e3a596a -depends: -- colormath >=3.0.0 -- python >=3.9 -license: MIT -license_family: MIT -size: 22284 -timestamp: 1735770589188 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.52.0-hf1c7be2_0.conda -sha256: 4f8523f5341f0d9e1547085206c6c1f71f9fc7c277443ca363a8cf98add8fc01 -md5: d9634079df93a65ee045b3c75f35cae1 -depends: -- icu >=78.2,<79.0a0 -- libgcc >=14 -- libsqlite 3.52.0 h10b116e_0 -- libzlib >=1.3.1,<2.0a0 -- ncurses >=6.5,<7.0a0 -- readline >=8.3,<9.0a0 -license: blessing -size: 209416 -timestamp: 1772818891689 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda -sha256: c1da41c79262b27efa168407cfecc47b20270e5fc071a8307f95a2c85fb94170 -md5: 55bf7b559202236157b14323b40f19e6 -depends: -- libgcc >=14 -- libstdcxx >=14 -- python >=3.14,<3.15.0a0 -- python_abi 3.14.* *_cp314 -- regex >=2022.1.18 -- requests >=2.26.0 -constrains: -- __glibc >=2.17 -license: MIT -license_family: MIT -size: 914402 -timestamp: 1764030357702 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda -sha256: e25c314b52764219f842b41aea2c98a059f06437392268f09b03561e4f6e5309 -md5: 7fc6affb9b01e567d2ef1d05b84aa6ed -depends: -- libgcc >=14 -- libzlib >=1.3.1,<2.0a0 -constrains: -- xorg-libx11 >=1.8.12,<2.0a0 -license: TCL -license_family: BSD -size: 3368666 -timestamp: 1769464148928 -- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda -sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 -md5: e5ce43272193b38c2e9037446c1d9206 -depends: -- python >=3.10 -- __unix -- python -license: MPL-2.0 and MIT -size: 94132 -timestamp: 1770153424136 -- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda -sha256: 39d8ae33c43cdb8f771373e149b0b4fae5a08960ac58dcca95b2f1642bb17448 -md5: 260af1b0a94f719de76b4e14094e9a3b -depends: -- importlib-metadata >=3.6 -- python >=3.10 -- typing-extensions >=4.10.0 -- typing_extensions >=4.14.0 -constrains: -- pytest >=7 -license: MIT -license_family: MIT -size: 36838 -timestamp: 1771532971545 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda -sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c -md5: edd329d7d3a4ab45dcf905899a7a6115 -depends: -- typing_extensions ==4.15.0 pyhcf101f3_0 -license: PSF-2.0 -license_family: PSF -size: 91383 -timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda -sha256: 70db27de58a97aeb7ba7448366c9853f91b21137492e0b4430251a1870aa8ff4 -md5: a0a4a3035667fc34f29bfbd5c190baa6 -depends: -- python >=3.10 -- typing_extensions >=4.12.0 -license: MIT -license_family: MIT -size: 18923 -timestamp: 1764158430324 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda -sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 -md5: 0caa1af407ecff61170c9437a808404d -depends: -- python >=3.10 -- python -license: PSF-2.0 -license_family: PSF -size: 51692 -timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda -sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c -md5: ad659d0a2b3e47e38d829aa8cad2d610 -license: LicenseRef-Public-Domain -size: 119135 -timestamp: 1767016325805 -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda -sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a -md5: 9272daa869e03efe68833e3dc7a02130 -depends: -- backports.zstd >=1.0.0 -- brotli-python >=1.2.0 -- h2 >=4,<5 -- pysocks >=1.5.6,<2.0,!=1.5.7 -- python >=3.10 -license: MIT -license_family: MIT -size: 103172 -timestamp: 1767817860341 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda -sha256: e9f6e931feeb2f40e1fdbafe41d3b665f1ab6cb39c5880a1fcf9f79a3f3c84a5 -md5: 1c246e1105000c3660558459e2fd6d43 -depends: -- libgcc >=14 -license: MIT -license_family: MIT -size: 16317 -timestamp: 1762977521691 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda -sha256: 128d72f36bcc8d2b4cdbec07507542e437c7d67f677b7d77b71ed9eeac7d6df1 -md5: bff06dcde4a707339d66d45d96ceb2e2 -depends: -- libgcc >=14 -license: MIT -license_family: MIT -size: 21039 -timestamp: 1762979038025 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda -sha256: 66265e943f32ce02396ad214e27cb35f5b0490b3bd4f064446390f9d67fa5d88 -md5: 032d8030e4a24fe1f72c74423a46fb88 -depends: -- libgcc >=14 -license: MIT -license_family: MIT -size: 88088 -timestamp: 1753484092643 -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda -sha256: b4533f7d9efc976511a73ef7d4a2473406d7f4c750884be8e8620b0ce70f4dae -md5: 30cd29cb87d819caead4d55184c1d115 -depends: -- python >=3.10 -- python -license: MIT -license_family: MIT -size: 24194 -timestamp: 1764460141901 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda -sha256: 638a3a41a4fbfed52d3c60c8ef5a3693b3f12a5b1a3f58fa29f5698d0a0702e2 -md5: f731af71c723065d91b4c01bb822641b -depends: -- libgcc >=14 -- libstdcxx >=14 -license: Zlib -license_family: Other -size: 121046 -timestamp: 1770167944449 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda -sha256: 569990cf12e46f9df540275146da567d9c618c1e9c7a0bc9d9cfefadaed20b75 -md5: c3655f82dcea2aa179b291e7099c1fcc -depends: -- libzlib >=1.3.1,<2.0a0 -license: BSD-3-Clause -license_family: BSD -size: 614429 -timestamp: 1764777145593 diff --git a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt b/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt deleted file mode 100644 index f787dbe..0000000 --- a/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt +++ /dev/null @@ -1,125 +0,0 @@ - -# This file may be used to create an environment using: -# $ conda create --name --file -# platform: linux-aarch64 -@EXPLICIT -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda#4faa39bf919939602e594253bd673958 -https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda#552567ea2b61e3a3035759b2fdb3f9a6 -https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda#840d8fc0d7b3209be93080bc20e07f2d -https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda#502006882cf5461adced436e410046d1 -https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc -https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda#a21644fc4a83da26452a718dc9468d5f -https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda#05d1e0b30acd816a192c03dc6e164f4d -https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a -https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda#76298a9e6d71ee6e832a8d0d7373b261 -https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda#7b9813e885482e3ccb1fa212b86d7fd0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0.conda#86db4036fd08bf34e991bf48a8af405d -https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab -https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda#3b129669089e4d6a5c6871dbb4669b99 -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda#3d49cad61f829f4f0e0611547a9cda12 -https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.4-hfd9ac0a_100_cp314.conda#3cfbe780f0f51cc8cba41db9f8a28bfe -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda#2934f256a8acfe48f6ebb4fce6cde29c -https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 -https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 -https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda#a1b5c571a0923a205d663d8678df4792 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c -https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda#7fe569c10905402ed47024fc481bb371 -https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda#b866ff7007b934d564961066c8195983 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b -https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.32-pthreads_h9d3fd7e_0.conda#5d2ce5cf40443d055ec6d33840192265 -https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce -https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py314haac167e_0.conda#25d896c331481145720a21e5145fad65 -https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda#071cf7b0ce333c81718b054066c15102 -https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.5-hfae3067_0.conda#d2bb0c889d94f2fdc5856392c3002976 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 -https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb -https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda#f51503ac45a4888bce71af9027a2ecc9 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda#b99ed99e42dafb27889483b3098cace7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 -https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db -https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e -https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda#daddf757c3ecd6067b9af1df1f25d89e -https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda#e5de3c36dd548b35ff2a8aa49208dcb3 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda#e7f6ed9e60043bb5cbcc527764897f0d -https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab -https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 -https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2#7b08314a6867a9d5648a1c3265e9eb8e -https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda#6dd4f07147774bf720075a210f8026b9 -https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda#4540f9570d12db2150f42ba036154552 -https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.53.0-he8854b5_0.conda#ad8164bdeece883b825c50639c0c4725 -https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2#4f0d284f5d11e04277b552eb1c172c7f -https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda#a85ba48648f6868016f2741fd9170250 -https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda#d13423b06447113a90b5b1366d4da171 -https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c -https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af -https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d -https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c -https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 -https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 -https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda#ba0a9221ce1063f31692c07370d062f3 -https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 -https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda#e941e85e273121222580723010bd4fa2 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 -https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py314hac3e5ec_0.conda#87d58d103b47c4a8567b3d7666647684 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 -https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a -https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.40.0-py310hff09b76_0.conda#d5628a33ce7652511e38fc98643dc910 -https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 -https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.40.0-py310hf00a4a2_0.conda#a82af0fcbb72db253dc89a7a45279372 -https://conda.anaconda.org/conda-forge/noarch/polars-lts-cpu-1.34.0.deprecated-hc364b38_0.conda#ef0340e75068ac8ff96462749b5c98e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda#032d8030e4a24fe1f72c74423a46fb88 -https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda#9ae2c92975118058bd720e9ba2bb7c58 -https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda#e17be1016bcc3516827b836cd3e4d9dc -https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.3-py314h451b6cc_0.conda#1a2cb55be9a153ad6203bff6b787c240 -https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_1.conda#a0a4a3035667fc34f29bfbd5c190baa6 -https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.3-pyhcf101f3_0.conda#f690e6f204efd2e5c06b57518a383d98 -https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda#130584ad9f3a513cdd71b1fdc1244e9c -https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2#310259a5b03ff02289d7705f39e2b1d2 -https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 -https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda#0242025a3c804966bf71aa04eee82f66 -https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda#0c20a8ebcddb24a45da89d5e917e6cb9 -https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda#472239e4eb7b5a84bb96b3ed7e3a596a -https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.4.4-py314h51f160d_0.conda#88a3dbd279e6b1faf0cddb8397866864 -https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda#55bf7b559202236157b14323b40f19e6 -https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda#e5ce43272193b38c2e9037446c1d9206 -https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.1-pyhd8ed1ab_0.conda#260af1b0a94f719de76b4e14094e9a3b -https://conda.anaconda.org/bioconda/noarch/multiqc-1.34-pyhdfd78af_0.conda#a7111ab9a6a6146b40cbce16655ac873 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f -https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda#ab7288cc39545556d1bc5e71ab2df9a9 diff --git a/modules/nf-core/rgi/bwt/environment.yml b/modules/nf-core/rgi/bwt/environment.yml new file mode 100644 index 0000000..58b301d --- /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::kma=1.6.11 + - bioconda::rgi=6.0.8 diff --git a/modules/nf-core/rgi/bwt/main.nf b/modules/nf-core/rgi/bwt/main.nf new file mode 100644 index 0000000..b92b667 --- /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 | sed 's/KMA-//'"), 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..f18ccd2 --- /dev/null +++ b/modules/nf-core/rgi/bwt/meta.yml @@ -0,0 +1,160 @@ +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 # FASTQ + - 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 # JSON + 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 | sed 's/KMA-//': + 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 | sed 's/KMA-//': + 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..a31672c --- /dev/null +++ b/modules/nf-core/rgi/bwt/tests/main.nf.test @@ -0,0 +1,98 @@ +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 ], + [ + 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 { + def outDir = file(process.out.tsv[0][1][0]).parentFile + def mappingFile = outDir.listFiles().find { + it.name.endsWith(".gene_mapping_data.txt") + } + + assert process.success + assertAll( + { assert snapshot( + sanitizeOutput(process.out, unstableKeys: ["tsv", "json"]), + mappingFile.readLines().sort() + ).match() }, + ) + } + } + + test("rgi/bwt - minigut - test_fastq_gz - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + [ + 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 { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(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..01c0c63 --- /dev/null +++ b/modules/nf-core/rgi/bwt/tests/main.nf.test.snap @@ -0,0 +1,146 @@ +{ + "rgi/bwt - minigut - test_fastq_gz - stub": { + "content": [ + { + "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", + "1.6.11" + ] + ], + "versions_rgi": [ + [ + "RGI_BWT", + "rgi", + "6.0.8" + ] + ] + } + ], + "timestamp": "2026-08-17T08:23:55.264483205", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + }, + "rgi/bwt - minigut - test_fastq_gz": { + "content": [ + { + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.allele_mapping_data.json" + ] + ], + "tmp": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.temp.sam.temp.fsa:md5,bd47f4f8e6eefb9f9e70deb5cd42e7f9" + ] + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.allele_mapping_data.txt", + "test.artifacts_mapping_stats.txt", + "test.coverage.temp.txt", + "test.coverage_all_positions.summary.temp.txt", + "test.coverage_all_positions.temp.txt", + "test.gene_mapping_data.txt", + "test.overall_mapping_stats.txt", + "test.reference_mapping_stats.txt", + "test.seqs.temp.txt", + "test.temp.txt" + ] + ] + ], + "versions_db": [ + [ + "RGI_BWT", + "rgi-database", + "4.0.1" + ] + ], + "versions_kma": [ + [ + "RGI_BWT", + "kma", + "1.6.11" + ] + ], + "versions_rgi": [ + [ + "RGI_BWT", + "rgi", + "6.0.8" + ] + ] + }, + [ + "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" + ] + ], + "timestamp": "2026-08-17T12:30:32.794546461", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.6" + } + } +} \ 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 38b661e..154f6cf 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 @@ -37,9 +32,7 @@ params { show_hidden = false version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' - trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') - - // Config options + trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')// Config options config_profile_name = null config_profile_description = null @@ -50,6 +43,23 @@ params { // Schema validation default options validate_params = true + // Databases + databases = null + save_untarred_databases = 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 @@ -94,7 +104,7 @@ 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' } arm64 { process.arch = 'arm64' @@ -181,8 +191,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 @@ -193,9 +202,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. @@ -240,39 +246,39 @@ 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: '', + + name: 'Vini Salazar', + affiliation: 'University of Melbourne', email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + github: 'vinisalazar', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') orcid: '' ], [ - name: ' Yixuan Yang', - affiliation: '', + name: 'Mirae B', + affiliation: 'MSKCC', email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + github: 'miraep8', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') orcid: '' ], [ - name: ' Mirae Baichoo', - affiliation: '', + name: 'Yixuan Yang', + affiliation: 'NC State', email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + 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""" diff --git a/nextflow_schema.json b/nextflow_schema.json index 53763ba..44e40e0 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 utilise the same input style as nf-core/taxprofiler, with 2 main differences: long-read platforms are not supported, nor is `fasta` input. See [usage docs](https://nf-co.re/funcprofiler/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,41 +60,46 @@ } } }, - "reference_genome_options": { - "title": "Reference genome options", + "profiling_options": { + "title": "Profiling 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." + "run_fmhfunprofiler": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with FMH FunProfiler. Requires a `fmhfunprofiler`-tagged database to be present in the 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 a `humann_v3`-tagged database to be present in the 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 a `humann_v4`-tagged database to be present in the CSV file passed to --databases" }, - "igenomes_base": { - "type": "string", - "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 `diamond`-tagged database to be present in the CSV file passed to --databases" + }, + "run_rgi": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with RGI. Requires a `rgi`-tagged database to be present in the CSV file passed to --databases" + }, + "run_mifaser": { + "type": "boolean", + "fa_icon": "fas fa-toggle-on", + "description": "Turn on profiling with mi-faser. Requires a `mifaser`-tagged database to be present in the 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 to be present in the CSV file passed to --databases" } } }, @@ -237,7 +259,7 @@ "$ref": "#/$defs/input_output_options" }, { - "$ref": "#/$defs/reference_genome_options" + "$ref": "#/$defs/profiling_options" }, { "$ref": "#/$defs/institutional_config_options" diff --git a/nf-test.config b/nf-test.config index f7aaeb4..d712a84 100644 --- a/nf-test.config +++ b/nf-test.config @@ -17,19 +17,8 @@ config { // run all test with defined profile(s) from the main nextflow.config profile = "test" - // list of filenames or patterns that should be trigger a full test run - triggers = [ - '.github/actions/nf-test/action.yml', - '.github/workflows/nf-test.yml', - 'assets/schema_input.json', - 'bin/*', - 'conf/test.config', - 'nextflow.config', - 'nextflow_schema.json', - 'nf-test.config', - 'tests/.nftignore', - 'tests/nextflow.config', - ] + // 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 plugins { diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 6a88d9f..1845fa5 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2026-09-01T12:58:14+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 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/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\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/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 originally 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\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\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", + "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 already preprocessed short-read 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. Long-read platforms are not supported in this release.\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,ILLUMINA,/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. Reads are expected to arrive already preprocessed: the pipeline performs no read QC, trimming or host decontamination.\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_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 originally 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/" }, @@ -121,8 +124,21 @@ }, { "@id": "main.nf", - "@type": ["File", "SoftwareSourceCode", "ComputationalWorkflow"], - "contributor": [ + "@type": [ + "File", + "SoftwareSourceCode", + "ComputationalWorkflow" + ], + "author": [ + { + "@id": "#02abcbb1-966b-4c2b-9848-c2ef3c65726e" + }, + { + "@id": "#865c248f-67f4-474a-9f1e-8f4ff51cffab" + }, + { + "@id": "#f74f489b-c4bb-4bb1-8e43-fdde330df31c" + }, { "@id": "#7afafb31-7939-4b51-8cca-c73ca161e3e7" }, @@ -139,17 +155,43 @@ "dateCreated": "", "dateModified": "2026-09-01T12:58:14Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", - "keywords": ["nf-core", "nextflow"], - "license": ["MIT"], - "name": ["nf-core/funcprofiler"], + "keywords": [ + "nf-core", + "nextflow" + ], + "license": [ + "MIT" + ], + "maintainer": [ + { + "@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": [ + "nf-core/funcprofiler" + ], "programmingLanguage": { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" }, "sdPublisher": { "@id": "https://nf-co.re/" }, - "url": ["https://github.com/nf-core/funcprofiler", "https://nf-co.re/funcprofiler/1.0.0/"], - "version": ["1.0.0"] + "url": [ + "https://github.com/nf-core/funcprofiler", + "https://nf-co.re/funcprofiler/1.0.0/" + ], + "version": [ + "1.0.0" + ] }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", @@ -219,6 +261,11 @@ "@type": "Dataset", "description": "Modules used by the pipeline" }, + { + "@id": "modules/local/", + "@type": "Dataset", + "description": "Pipeline-specific modules" + }, { "@id": "modules/nf-core/", "@type": "Dataset", @@ -306,25 +353,36 @@ "url": "https://nf-co.re/" }, { - "@id": "#7afafb31-7939-4b51-8cca-c73ca161e3e7", + "@id": "#02abcbb1-966b-4c2b-9848-c2ef3c65726e", "@type": "Person", - "email": "nickp60@users.noreply.github.com", - "name": "Nick Waters" + "affiliation": "MSKCC", + "email": "nickp60@gmail.com", + "name": "Nick Waters", + "url": "https://github.com/nickp60" }, { - "@id": "#c7756996-91be-4b50-92a0-394343896060", + "@id": "#865c248f-67f4-474a-9f1e-8f4ff51cffab", "@type": "Person", - "name": "Vini Salazar" + "affiliation": "University of Melbourne", + "email": "17276653+vinisalazar@users.noreply.github.com", + "name": "Vini Salazar", + "url": "https://github.com/vinisalazar" }, { - "@id": "#66641cd0-9bcf-4871-bb16-e25bd870088a", + "@id": "#f74f489b-c4bb-4bb1-8e43-fdde330df31c", "@type": "Person", - "name": "Yixuan Yang" + "affiliation": "MSKCC", + "email": "miraep8@gmail.com", + "name": "Mirae B", + "url": "https://github.com/miraep8" }, { - "@id": "https://orcid.org/0000-0002-4219-9076", + "@id": "#3f3b690c-5064-46b9-82c3-50d9a35a4502", "@type": "Person", - "name": "Mirae Baichoo" + "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..c7912b8 --- /dev/null +++ b/subworkflows/local/dataprep/main.nf @@ -0,0 +1,74 @@ +// +// Prepare the reads for profiling. +// +// Takes the validated samplesheet channel from PIPELINE_INITIALISATION, merges the sequencing +// runs belonging to the same sample, and emits the two read layouts the profilers need: +// +// reads - 1 file for single-end samples, 2 for paired-end, real endedness preserved. +// reads_concat - always exactly 1 file, R1 and R2 concatenated, `meta.single_end` forced to +// true so that single-FASTQ tools see a single-end sample. +// +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: + reads // channel: [ val(meta), [ path(reads) ] ] + + main: + + // Step 1: Group by meta.id and merge runs if needed + ch_grouped = reads + .map { meta, fastqs -> + // Create grouping key and new meta without run_accession for grouping + def group_key = meta.id + [group_key, meta, fastqs] + } + .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, fastqs -> + merge: (meta.single_end && fastqs.size() > 1) || (!meta.single_end && fastqs.size() > 2) + skip: true + } + + // 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 2: Create concatenated single-file version for tools that need it + ch_for_concat = ch_reads + .map { meta, fastqs -> + // 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, fastqs] + } + .branch { _meta, fastqs -> + concat: fastqs.size() > 1 + skip: true + } + + // Concatenate all reads into single file per sample + ch_concatenated = CAT_FASTQ(ch_for_concat.concat).reads + .mix(ch_for_concat.skip) + .map { meta, fastqs -> + // Ensure reads is always a list + [meta, [fastqs].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..7a46688 --- /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 { + workflow { + """ + input[0] = Channel.fromList([ + [ + [id: '2612', single_end: false, run_accession: 'ERR5766176', instrument_platform: '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', single_end: false, run_accession: 'ERR5766176_B', instrument_platform: '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', single_end: false, run_accession: '1', instrument_platform: '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 2 files per sample for the paired 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..0a7ef07 --- /dev/null +++ b/subworkflows/local/dbprep/main.nf @@ -0,0 +1,68 @@ +// +// Prepare the databases for profiling. +// +// Takes the validated database sheet from PIPELINE_INITIALISATION, drops the rows belonging to +// profilers that are not enabled, decompresses the TAR archives among the rest, and groups the +// remaining paths by [ tool, db_name, db_params ] into a Map of `db_entity -> path`. Tools that +// take a single database leave `db_entity` empty in the sheet and are stored under 'main'. +// +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..467e861 --- /dev/null +++ b/subworkflows/local/profile/main.nf @@ -0,0 +1,295 @@ +// +// 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. + // db_params is checked for its two integers by validateProfilerDatabases() at pipeline initialisation. + fmh_db = getDbPath(ch_input_for_fmhfunprofiler.db, "main", true) + .multiMap { db_meta, db_path -> + def args = db_meta.db_params.split(" ") + db_path: db_path + kmer: args[0] + sketch: args[1] + } + 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) { + 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, + ) + // Join on meta map + ch_humann4_input = ch_input_for_humann_v4.reads.join(MPAHUMANN4.out.profile, by: 0) + 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 + +// +// Make a string safe to use as a channel element id: underscores and whitespace to hyphens, +// anything else that is not a word character or a dot dropped, runs of hyphens collapsed. +// +def sanitizeId(str) { + return str + .toString() + // underscores to hyphens, spaces to hyphens, drop special chars, collapse hyphens + .replaceAll(/_/, '-') + .replaceAll(/\s+/, '-') + .replaceAll(/[^\w\-.]/, '') + .replaceAll(/-+/, '-') +} + +/** +* Combine a reads channel with the databases of one tool, and split the result into the two +* channels a profiler module takes, keeping their element order in sync. +* +* @param pairedreads A channel of [ meta, [ reads ] ] +* @param databases A channel of [ db_meta, [ db_file ] ], as emitted by DBPREP +* @param tool_name Only databases with this `tool` are used +* @param singleFqTool True for tools that take a single FASTQ, i.e. that are fed reads_concat +* @return A multiMap'ed channel with a `.reads` and a `.db` sub-channel +*/ +def prepareInputs(pairedreads, databases, tool_name, singleFqTool = false) { + // 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 +} + +/** +* Pull one component out of a grouped database. +* +* DBPREP hands each tool its database as a Map of `db_entity -> path`, keyed by the `db_entity` +* column of the database sheet. Tools that take a single database file or directory leave that +* column empty and DBPREP stores it under 'main'; HUMAnN and eggNOG-mapper need several +* components and address them by name. +* +* Which components each profiler requires is checked by validateProfilerDatabases() at pipeline +* initialisation. The error below is only a backstop, so that a missing entity fails loudly here +* rather than reaching the module as a null path. +* +* @param groupeddb A channel of [ db_meta, Map[db_entity -> path] ], as emitted by DBPREP +* @param entity The db_entity to look up +* @param asTuple Return [ db_meta, path ] instead of just the path, for tools that need db_params +* @return A channel of the requested database path, or of [ db_meta, path ] +*/ +def getDbPath(groupeddb, entity = 'main', asTuple = false) { + return groupeddb.map { meta_db, files_map -> + if (!files_map.containsKey(entity)) { + error("No entity '${entity}' file found in database ${meta_db.id}") + } + + def db_path = files_map[entity] + asTuple ? [meta_db, db_path] : db_path + } +} 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..8234c8a --- /dev/null +++ b/subworkflows/local/profile/tests/main.nf.test @@ -0,0 +1,356 @@ +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', single_end: false, run_accession: '1', instrument_platform: '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', single_end: false, run_accession: '1', instrument_platform: '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', single_end: false, run_accession: '1', instrument_platform: '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/**"]) + 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', single_end: false, run_accession: '1', instrument_platform: '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', single_end: false, run_accession: '1', instrument_platform: '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..bf7ec56 --- /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", + "1.6.11" + ], + [ + "PROFILE:RGI_BWT", + "rgi", + "6.0.8" + ], + [ + "PROFILE:RGI_BWT", + "rgi-database", + "4.0.1" + ] + ] + ], + "timestamp": "2026-09-02T16:52:53.96173", + "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..3491492 --- /dev/null +++ b/subworkflows/local/profile/tests/prepareInput.nf.test @@ -0,0 +1,241 @@ +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', single_end: false, run_accession: 'ERR5766176', instrument_platform: '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', single_end: false, run_accession: 'ERR5766176_B', instrument_platform: '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', single_end: false, run_accession: '1', instrument_platform: '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 879a21d..3f4a9b3 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 { paramsHelp } 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' +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,17 +24,17 @@ 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 - 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 + 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: @@ -43,19 +43,16 @@ workflow PIPELINE_INITIALISATION { // // 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 // - - def before_text = "" - def after_text = "" before_text = """ -\033[2m----------------------------------------------------\033[0m- \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m @@ -66,20 +63,18 @@ workflow PIPELINE_INITIALISATION { \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" : ""} + 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/main/CITATIONS.md """ - if (monochrome_logs) { - before_text = before_text.replaceAll(/\033\[[0-9;]*m/, '') - } - command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " - - UTILS_NFSCHEMA_PLUGIN ( + // + // Validate parameters and generate parameter summary to stdout + // + UTILS_NFSCHEMA_PLUGIN( workflow, validate_params, null, @@ -95,42 +90,37 @@ workflow PIPELINE_INITIALISATION { // // Check config provided to the pipeline // - UTILS_NFCORE_PIPELINE ( + UTILS_NFCORE_PIPELINE( nextflow_cli_args ) // - // Custom validation for pipeline parameters + // Create channel from input file provided through params.input + // + // Rows are validated and turned into their final [ meta, [ reads ] ] form here, so that + // a malformed samplesheet aborts the run before any task is submitted. // - validateInputParameters() + def samplesheet_list = samplesheetToList(params.input, "assets/schema_input.json") + .collect { meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta -> + validateInputSamplesheet(meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta) + } + validateRunEndedness(samplesheet_list) + ch_samplesheet = channel.fromList(samplesheet_list) // - // Create channel from input file provided through params.input + // Create channel from databases file provided through params.databases // - - channel - .fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) - .map { - meta, fastq_1, fastq_2 -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } - } - .groupTuple() - .map { samplesheet -> - validateInputSamplesheet(samplesheet) - } - .map { - meta, fastqs -> - return [ meta, fastqs.flatten() ] - } - .set { ch_samplesheet } + // The list is materialised before it becomes a channel so that the database sheet can be + // checked against the enabled profilers up front rather than partway through the run. + // + def databases_list = samplesheetToList(params.databases, "assets/schema_database.json") + validateProfilerDatabases(databases_list) + ch_databases = channel.fromList(databases_list) emit: - samplesheet = ch_samplesheet - versions = ch_versions + reads = ch_samplesheet + databases = ch_databases + versions = ch_versions } /* @@ -140,14 +130,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 - 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") @@ -170,11 +160,10 @@ workflow PIPELINE_COMPLETION { } completionSummary(monochrome_logs) - } workflow.onError { - log.error "Pipeline failed. Please refer to troubleshooting docs for common issues: https://nf-co.re/docs/running/troubleshooting" + log.error("Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting") } } @@ -183,77 +172,165 @@ workflow PIPELINE_COMPLETION { FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +// Validate one samplesheet row and build the meta map the rest of the pipeline uses. // -// Check and validate pipeline parameters +// The sample name, run accession, instrument platform and FASTQ paths are already checked by +// `assets/schema_input.json`, which also rejects the long-read platforms the profilers cannot +// handle. Only the FastA column needs checking here, because JSON schema cannot express +// "this column exists for nf-core/taxprofiler compatibility but must be left empty". // -def validateInputParameters() { - genomeExistsError() -} +def validateInputSamplesheet(meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta) { + if (fasta) { + error("Please check input samplesheet: FastA input is not supported, supply FastQ reads instead (sample: ${meta.id}).") + } -// -// Validate channels from input samplesheet -// -def validateInputSamplesheet(input) { - def (metas, fastqs) = input[1..2] + meta.single_end = !fastq_2 + meta.run_accession = run_accession + meta.instrument_platform = instrument_platform - // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 - if (!endedness_ok) { - error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") - } + return [meta, fastq_2 ? [fastq_1, fastq_2] : [fastq_1]] +} - return [ metas[0], fastqs ] +// Runs of the same sample must all be single-end or all paired-end, otherwise DATAPREP cannot +// interpret the read list it merges them into. +// +def validateRunEndedness(samplesheet_list) { + samplesheet_list + .groupBy { meta, _reads -> meta.id } + .each { id, rows -> + if (rows.collect { meta, _reads -> meta.single_end }.unique().size() != 1) { + error("Please check input samplesheet: multiple runs of a sample must all be single-end or all paired-end (sample: ${id}).") + } + } } + // -// Get attribute from genome config file e.g. fasta +// The database components each profiler needs, as `db_entity` names. Tools that take a single +// database file or directory leave `db_entity` empty, which DBPREP stores as the 'main' entity. // -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 +def profilerDatabaseEntities() { + return [ + 'humann_v3': ['humann_metaphlan', 'humann_nucleotide', 'humann_protein', 'humann_utility'], + 'humann_v4': ['humann_metaphlan', 'humann_nucleotide', 'humann_protein', 'humann_utility'], + 'eggnogmapper': ['eggnogmapper_db', 'eggnogmapper_data_dir'], + 'fmhfunprofiler': ['main'], + 'mifaser': ['main'], + 'diamond': ['main'], + 'rgi': ['main'], + ] } // -// Exit pipeline if incorrect --genome key provided +// Check that every enabled profiler has a complete database in the database sheet. // -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) +// Without this the pipeline starts, runs whatever else is enabled, and only fails once the +// incomplete database reaches the profiler, so it is done here before any task is submitted. +// +def validateProfilerDatabases(databases) { + def entities_by_db = [:] + databases.each { db_meta, _db_path -> + def key = [db_meta.tool, db_meta.db_name] + entities_by_db[key] = (entities_by_db[key] ?: [] as Set) + [db_meta.db_entity ?: 'main'] + } + + profilerDatabaseEntities().each { tool, required_entities -> + if (!params["run_${tool}"]) { + return + } + + def dbs_for_tool = entities_by_db.findAll { key, _entities -> key[0] == tool } + if (!dbs_for_tool) { + error("--run_${tool} is set but the database sheet '${params.databases}' has no row with tool '${tool}'.") + } + + dbs_for_tool.each { key, entities -> + def missing = required_entities - entities + if (missing) { + error("Database '${key[1]}' for --run_${tool} is missing required db_entity row(s): ${missing.join(', ')}.") + } + } + } + + // fmh-funprofiler reads its k-mer size and sketch scale out of db_params at runtime + if (params.run_fmhfunprofiler) { + databases + .findAll { db_meta, _db_path -> db_meta.tool == 'fmhfunprofiler' } + .each { db_meta, _db_path -> + def db_params = (db_meta.db_params ?: '').trim().split(/\s+/).findAll { arg -> arg } + if (db_params.size() != 2) { + error("fmhfunprofiler database '${db_meta.db_name}' must set db_params to two integers (k-mer size and sketch scale), but got '${db_meta.db_params}'.") + } + } } } + // // Generate methods description for MultiQC // def toolCitationText() { - // TODO nf-core: Optionally add in-text citation tools to this list. - // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", - // Uncomment function in methodsDescriptionText to render in MultiQC report + def 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.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_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_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 } @@ -261,6 +338,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() @@ -275,21 +353,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_nfcore_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test deleted file mode 100644 index 8940d32..0000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test +++ /dev/null @@ -1,29 +0,0 @@ -nextflow_workflow { - - name "Test Workflow UTILS_NFCORE_PIPELINE" - script "../main.nf" - config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config" - workflow "UTILS_NFCORE_PIPELINE" - tag "subworkflows" - tag "subworkflows_nfcore" - tag "utils_nfcore_pipeline" - tag "subworkflows/utils_nfcore_pipeline" - - test("Should run without failures") { - - when { - workflow { - """ - input[0] = [] - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert snapshot(workflow.out).match() } - ) - } - } -} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap deleted file mode 100644 index 859d103..0000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Should run without failures": { - "content": [ - { - "0": [ - true - ], - "valid_config": [ - true - ] - } - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-28T12:03:25.726491" - } -} \ No newline at end of file diff --git a/tests/.nftignore b/tests/.nftignore index e128a12..968874a 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -1,5 +1,4 @@ .DS_Store -multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt multiqc/multiqc_data/multiqc.parquet multiqc/multiqc_data/multiqc.log multiqc/multiqc_data/multiqc_data.json @@ -8,5 +7,21 @@ multiqc/multiqc_data/multiqc_software_versions.txt multiqc/multiqc_data/llms-full.txt multiqc/multiqc_plots/{svg,pdf,png}/*.{svg,pdf,png} multiqc/multiqc_report.html -fastqc/*_fastqc.{html,zip} +multiqc/multiqc_data/llms-full.txt +multiqc/multiqc_data/multiqc.parquet 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 f512cc4..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") { @@ -21,7 +22,7 @@ nextflow_pipeline { assertAll( { assert snapshot( // 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_path, // All files with stable contents 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 722a4be..6e088f1 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -4,11 +4,9 @@ ======================================================================================== */ -// 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/funcprofiler/' + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' } // Fixes S3 access issues on self-hosted runners diff --git a/workflows/funcprofiler.nf b/workflows/funcprofiler.nf index 6655096..226845a 100644 --- a/workflows/funcprofiler.nf +++ b/workflows/funcprofiler.nf @@ -3,12 +3,14 @@ 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' +include { DATAPREP } from '../subworkflows/local/dataprep/main' +include { DBPREP } from '../subworkflows/local/dbprep/main' +include { PROFILE } from '../subworkflows/local/profile/main' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -17,9 +19,9 @@ include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_func */ workflow FUNCPROFILER { - take: - ch_samplesheet // channel: samplesheet read in from --input + reads // channel: validated reads read in from --input + databases // channel: databases from --databases multiqc_config multiqc_logo multiqc_methods_description @@ -27,18 +29,27 @@ workflow FUNCPROFILER { main: - def ch_versions = channel.empty() - def ch_multiqc_files = channel.empty() - // - // MODULE: Run FastQC - // - FASTQC(ch_samplesheet) - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.map{ _meta, file -> file }) + ch_versions = Channel.empty() + ch_multiqc_files = Channel.empty() + + DATAPREP( + reads + ) + + DBPREP( + databases + ) + PROFILE( + DATAPREP.out.reads, + DATAPREP.out.reads_concat, + DBPREP.out.dbs, + ) // // Collate and save software versions // - def topic_versions = channel.topic("versions") + def topic_versions = channel + .topic("versions") .distinct() .branch { entry -> versions_file: entry instanceof Path @@ -47,9 +58,9 @@ workflow FUNCPROFILER { def topic_versions_string = topic_versions.versions_tuple .map { process, tool, version -> - [ process[process.lastIndexOf(':')+1..-1], " ${tool}: ${version}" ] + [process[process.lastIndexOf(':') + 1..-1], " ${tool}: ${version}"] } - .groupTuple(by:0) + .groupTuple(by: 0) .map { process, tool_versions -> tool_versions.unique().sort() "${process}:\n${tool_versions.join('\n')}" @@ -59,9 +70,9 @@ workflow FUNCPROFILER { .mix(topic_versions_string) .collectFile( storeDir: "${outdir}/pipeline_info", - name: 'nf_core_' + 'funcprofiler_software_' + 'mqc_' + 'versions.yml', + name: 'nf_core_' + 'funcprofiler_software_' + 'mqc_' + 'versions.yml', sort: true, - newLine: true + newLine: true, ) // @@ -90,12 +101,8 @@ workflow FUNCPROFILER { ] } ) - 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ + emit: + multiqc_report = MULTIQC.out.report.map { _meta, report -> [report] }.toList() // channel: /path/to/multiqc_report.html + versions = ch_versions // channel: [ path(versions.yml) ] +}