diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c46cae01..c47e8cdc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,8 +65,10 @@ jobs: if [[ "${{ matrix.tags }}" == "test_motus" ]]; then wget https://raw.githubusercontent.com/motu-tool/mOTUs/master/motus/downloadDB.py python downloadDB.py --no-download-progress - echo 'tool,db_name,db_params,db_path' > 'database_motus.csv' - echo "motus,db_mOTU,,db_mOTU" >> 'database_motus.csv' + echo 'tool,db_name,db_params,db_type,db_path' > 'database_motus.csv' + echo "motus,db1_mOTU,,short,db_mOTU" >> 'database_motus.csv' + echo "motus,db2_mOTU,,long,db_mOTU" >> 'database_motus.csv' + echo "motus,db3_mOTU,,short;long,db_mOTU" >> 'database_motus.csv' nextflow run ${GITHUB_WORKSPACE} -profile docker,${{ matrix.tags }} --databases ./database_motus.csv --outdir ./results_${{ matrix.tags }}; else nextflow run ${GITHUB_WORKSPACE} -profile docker,${{ matrix.tags }} --outdir ./results_${{ matrix.tags }}; diff --git a/CHANGELOG.md b/CHANGELOG.md index cf4282c8..0a4ff88d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,16 +3,42 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## dev - [unreleased] +## v1.2dev - Bouncy Basenji [unreleased] ### `Added` +- [#417](https://github.com/nf-core/taxprofiler/pull/417) - Added reference-free metagenome estimation with Nonpareil (added by @jfy133) +- [#466](https://github.com/nf-core/taxprofiler/pull/466) - Input database sheets now require a `db_type` column to distinguish between short- and long-read databases (added by @LilyAnderssonLee) +- [#505](https://github.com/nf-core/taxprofiler/pull/505) - Add small files to the file `tower.yml` (added by @LilyAnderssonLee) +- [#508](https://github.com/nf-core/taxprofiler/pull/508) - Add `nanoq` as a filtering tool for nanopore reads (added by @LilyAnderssonLee) +- [#511](https://github.com/nf-core/taxprofiler/pull/511) - Add `porechop_abi` as an alternative adapter removal tool for long reads nanopore data (added by @LilyAnderssonLee) +- [#512](https://github.com/nf-core/taxprofiler/pull/512) - Update all tools to the latest version and include nf-test (Updated by @LilyAnderssonLee & @jfy133) + ### `Fixed` - [#518](https://github.com/nf-core/taxprofiler/pull/518) Fixed a bug where Oxford Nanopore FASTA input files would not be processed (❤️ to @ikarls for reporting, fixed by @jfy133) ### `Dependencies` +| Tool | Previous version | New version | +| ------------- | ---------------- | ----------- | +| bbmap | 39.01 | 39.06 | +| bowtie2 | 2.4.4 | 2.5.2 | +| bracken | 2.7 | 2.9 | +| cat/fastq | 8.30 | +| diamond | 2.0.15 | 2.1.8 | +| ganon | 1.5.1 | 2.0.0 | +| kraken2 | 2.1.2 | 2.1.3 | +| krona | 2.8 | 2.8.1 | +| megan | 6.24.20 | 6.25.9 | +| metaphlan | 4.0.6 | 4.1.1 | +| minimap2 | 2.24 | 2.28 | +| motus/profile | 3.0.3 | 3.1.0 | +| multiqc | 1.21 | 1.24.1 | +| nanoq | | 0.10.0 | +| samtools | 1.17 | 1.20 | +| untar | 4.7 | 4.8 | + ### `Deprecated` ## v1.1.8 - Augmented Akita Patch [2024-06-20] diff --git a/CITATIONS.md b/CITATIONS.md index b82fe7d7..9079373f 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -30,14 +30,26 @@ > Schubert, M., Lindgreen, S., & Orlando, L. (2016). AdapterRemoval v2: rapid adapter trimming, identification, and read merging. BMC Research Notes, 9, 88. https://doi.org/10.1186/s13104-016-1900-2 +- [Nonpareil](https://doi.org/10.1128/mSystems.00039-18) + + - Rodriguez-R, L. M., Gunturu, S., Tiedje, J. M., Cole, J. R., & Konstantinidis, K. T. (2018). Nonpareil 3: Fast Estimation of Metagenomic Coverage and Sequence Diversity. mSystems, 3(3). https://doi.org/10.1128/mSystems.00039-18 + - [Porechop](https://github.com/rrwick/Porechop) > Wick, R. R., Judd, L. M., Gorrie, C. L., & Holt, K. E. (2017). Completing bacterial genome assemblies with multiplex MinION sequencing. Microbial Genomics, 3(10), e000132. https://doi.org/10.1099/mgen.0.000132 +- [Porechop_ABI](https://github.com/bonsai-team/Porechop_ABI) + + > Bonenfant, Q., Noé, L., & Touzet, H. (2023). Porechop_ABI: discovering unknown adapters in Oxford Nanopore Technology sequencing reads for downstream trimming. Bioinformatics Advances, 3(1):vbac085. https://10.1093/bioadv/vbac085 + - [Filtlong](https://github.com/rrwick/Filtlong) > Wick R (2021) Filtlong, URL: https://github.com/rrwick/Filtlong +- [nanoq](https://github.com/esteinig/nanoq) + + > Steinig, E., & Coin, L. (2022). Nanoq: ultra-fast quality control for nanopore reads. Journal of Open Source Software, 7(69). https://doi.org/10.21105/joss.02991 + - [BBTools](http://sourceforge.net/projects/bbmap/) > Bushnell B. (2022) BBMap, URL: http://sourceforge.net/projects/bbmap/ diff --git a/README.md b/README.md index 980a2212..4bf4174a 100644 --- a/README.md +++ b/README.md @@ -23,17 +23,21 @@ **nf-core/taxprofiler** is a bioinformatics best-practice analysis pipeline for taxonomic classification and profiling of shotgun short- and long-read metagenomic data. It allows for in-parallel taxonomic identification of reads or taxonomic abundance estimation with multiple classification and profiling tools against multiple databases, and produces standardised output tables for facilitating results comparison between different tools and databases. +The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community! + +On release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/scnanoseq/results). + ## Pipeline summary ![](docs/images/taxprofiler_tube.png) 1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) or [`falco`](https://github.com/smithlabcode/falco) as an alternative option) 2. Performs optional read pre-processing - - Adapter clipping and merging (short-read: [fastp](https://github.com/OpenGene/fastp), [AdapterRemoval2](https://github.com/MikkelSchubert/adapterremoval); long-read: [porechop](https://github.com/rrwick/Porechop)) - - Low complexity and quality filtering (short-read: [bbduk](https://jgi.doe.gov/data-and-tools/software-tools/bbtools/), [PRINSEQ++](https://github.com/Adrian-Cantu/PRINSEQ-plus-plus); long-read: [Filtlong](https://github.com/rrwick/Filtlong)) + - Adapter clipping and merging (short-read: [fastp](https://github.com/OpenGene/fastp), [AdapterRemoval2](https://github.com/MikkelSchubert/adapterremoval); long-read: [porechop](https://github.com/rrwick/Porechop), [Porechop_ABI](https://github.com/bonsai-team/Porechop_ABI)) + - Low complexity and quality filtering (short-read: [bbduk](https://jgi.doe.gov/data-and-tools/software-tools/bbtools/), [PRINSEQ++](https://github.com/Adrian-Cantu/PRINSEQ-plus-plus); long-read: [Filtlong](https://github.com/rrwick/Filtlong)), [Nanoq](https://github.com/esteinig/nanoq) - Host-read removal (short-read: [BowTie2](http://bowtie-bio.sourceforge.net/bowtie2/); long-read: [Minimap2](https://github.com/lh3/minimap2)) - Run merging -3. Supports statistics for host-read removal ([Samtools](http://www.htslib.org/)) +3. Supports statistics metagenome coverage estimation ([Nonpareil](https://nonpareil.readthedocs.io/en/latest/)) and for host-read removal ([Samtools](http://www.htslib.org/)) 4. Performs taxonomic classification and/or profiling using one or more of: - [Kraken2](https://ccb.jhu.edu/software/kraken2/) - [MetaPhlAn](https://huttenhower.sph.harvard.edu/metaphlan/) diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 0d892103..c4ea4a0c 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -11,6 +11,48 @@ report_section_order: order: -1001 "nf-core-taxprofiler-summary": order: -1002 + general_stats": + order: 1000 + fastqc: + order: 900 + fastqc-1: + order: 800 + fastp: + order: 700 + adapterRemoval: + order: 600 + nonpareil: + order: 500 + porechop: + order: 400 + porechop_abi: + order: 450 + bbduk: + order: 300 + prinseqplusplus: + order: 200 + filtlong: + order: 100 + nanoq: + order: 95 + bowtie2: + order: 90 + samtools: + order: 80 + kraken: + order: 70 + bracken: + order: 60 + centrifuge: + order: 50 + malt: + order: 40 + diamond: + order: 30 + kaiju: + order: 20 + motus: + order: 10 export_plots: true @@ -22,11 +64,13 @@ custom_logo_title: "nf-core/taxprofiler" run_modules: - fastqc - adapterRemoval - - fastp + - fastp + - nonpareil - bbduk - prinseqplusplus - porechop - filtlong + - nanoq - bowtie2 - minimap2 - samtools @@ -44,6 +88,8 @@ sp: fn_re: ".*(fastqc|falco)_data.txt$" fastqc/zip: fn: "*_fastqc.zip" + nonpareil: + fn: "nonpareil_all_samples.json" top_modules: - "fastqc": @@ -60,13 +106,23 @@ top_modules: path_filters_exclude: - "*raw*" extra: "If used in this run, Falco is a drop-in replacement for FastQC producing the same output, written by Guilherme de Sena Brandine and Andrew D. Smith." - - "fastp" - - "adapterRemoval" + - nonpareil - "porechop": + name: "Porechop" + anchor: "porechop" + target: "Porechop" + path_filters: + - "*porechop.log" extra: "ℹ️: if you get the error message 'Error - was not able to plot data.' this means that porechop did not detect any adapters and therefore no statistics generated." - - "bbduk" - - "prinseqplusplus" - - "filtlong" + - "porechop": + name: "Porechop_ABI" + anchor: "porechop_abi" + target: "Porechop_ABI" + doi: "10.1093/bioadv/vbac085" + info: "find and remove adapters from Oxford Nanopore reads." + path_filters: + - "*porechop_abi.log" + extra: "ℹ️: if you get the error message 'Error - was not able to plot data.' this means that porechop_abi did not detect any adapters and therefore no statistics generated." - "bowtie2": name: "bowtie2" - "samtools": @@ -95,12 +151,11 @@ top_modules: - "*.centrifuge.txt" - "malt": name: "MALT" - - "diamond" - "kaiju": name: "Kaiju" - - "motus" -#It is not possible to set placement for custom kraken and centrifuge columns. +# It is not possible to set placement for custom kraken +# and centrifuge columns. table_columns_placement: FastQC / Falco (pre-Trimming): @@ -130,16 +185,32 @@ table_columns_placement: percent_aligned: 370 percent_collapsed: 380 percent_discarded: 390 + nonpareil: + nonpareil_R: 400 + nonpareil_LR: 410 + nonpareil_kappa: 420 + nonpareil_C: 430 + nonpareil_diversity: 440 Porechop: - Input Reads: 400 - Start Trimmed: 410 - Start Trimmed Percent: 420 - End Trimmed: 430 - End Trimmed Percent: 440 - Middle Split: 450 - Middle Split Percent: 460 + Input Reads: 500 + Start Trimmed: 510 + Start Trimmed Percent: 520 + End Trimmed: 530 + End Trimmed Percent: 540 + Middle Split: 550 + Middle Split Percent: 560 + Porechop_ABI: + Input Reads: 500 + Start Trimmed: 510 + Start Trimmed Percent: 520 + End Trimmed: 530 + End Trimmed Percent: 540 + Middle Split: 550 + Middle Split Percent: 560 Filtlong: - Target bases: 500 + Target bases: 600 + nanoq: + Read N50: 700 BBDuk: Input reads: 800 Total Removed bases percent: 810 @@ -203,6 +274,24 @@ table_columns_visible: percent_duplicates: False percent_gc: False percent_fails: False + Adapter Removal: + aligned_total: True + percent_aligned: True + percent_collapsed: True + percent_discarded: False + fastp: + pct_adapter: True + pct_surviving: True + pct_duplication: False + after_filtering_gc_content: False + after_filtering_q30_rate: False + after_filtering_q30_bases: False + nonpareil: + nonpareil_R: false + nonpareil_LR: false + nonpareil_kappa: true + nonpareil_C: true + nonpareil_diversity: true porechop: Input reads: False Start Trimmed: @@ -211,20 +300,18 @@ table_columns_visible: End Trimmed Percent: True Middle Split: False Middle Split Percent: True - fastp: - pct_adapter: True - pct_surviving: True - pct_duplication: False - after_filtering_gc_content: False - after_filtering_q30_rate: False - after_filtering_q30_bases: False + porechop_abi: + Input reads: False + Start Trimmed: + Start Trimmed Percent: True + End Trimmed: False + End Trimmed Percent: True + Middle Split: False + Middle Split Percent: True Filtlong: Target bases: True - Adapter Removal: - aligned_total: True - percent_aligned: True - percent_collapsed: True - percent_discarded: False + nanoq: + ReadN50: True BBDuk: Input reads: False Total Removed bases Percent: False @@ -276,6 +363,9 @@ extra_fn_clean_exts: - ".bbduk" - ".unmapped" - "_filtered" + - "porechop" + - "porechop_abi" + - "_processed" - type: remove pattern: "_falco" diff --git a/assets/schema_database.json b/assets/schema_database.json index e467b41d..ec04e326 100644 --- a/assets/schema_database.json +++ b/assets/schema_database.json @@ -39,6 +39,12 @@ "errorMessage": "Invalid database db_params entry. No quotes allowed.", "meta": ["db_params"] }, + "db_type": { + "type": "string", + "enum": ["short", "long", "short;long"], + "default": "short;long", + "meta": ["db_type"] + }, "db_path": { "type": "string", "exists": true, diff --git a/assets/schema_input.json b/assets/schema_input.json index cc335436..bfa0e6cd 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -38,18 +38,21 @@ "type": "string", "format": "file-path", "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "unique": true, "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" }, "fastq_2": { "type": "string", "format": "file-path", "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "unique": true, "errorMessage": "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", "format": "file-path", "pattern": "^\\S+\\.(f(ast)?q|fa(sta)?)\\.gz$", + "unique": true, "errorMessage": "FastA file must be provided, cannot contain spaces and must have extension '.fa.gz' or '.fasta.gz'. If not applicable, leave it empty." } }, diff --git a/conf/modules.config b/conf/modules.config index ee0bd5b5..d298a828 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -198,6 +198,43 @@ process { ] } + // Redundancy estimation with nonpareil + withName: NONPAREIL_NONPAREIL { + ext.prefix = { "${meta.id}_${meta.run_accession}" } + publishDir = [ + path: { "${params.outdir}/nonpareil/" }, + mode: params.publish_dir_mode, + pattern: '*.np{a,c,l,o}' + ] + } + + withName: 'NONPAREIL_CURVE' { + ext.prefix = { "${meta.id}_${meta.run_accession}" } + publishDir = [ + path: { "${params.outdir}/nonpareil/" }, + mode: params.publish_dir_mode, + pattern: '*.png' + ] + } + + withName: 'NONPAREIL_SET' { + ext.prefix = { "nonpareil_all_samples_mqc" } + publishDir = [ + path: { "${params.outdir}/nonpareil/" }, + mode: params.publish_dir_mode, + pattern: '*.png' + ] + } + + withName: 'NONPAREIL_NONPAREILCURVESR' { + ext.prefix = { "nonpareil_all_samples" } + publishDir = [ + path: { "${params.outdir}/nonpareil/" }, + mode: params.publish_dir_mode, + pattern: '*.{json,csv,tsv,pdf}' + ] + } + // AdapterRemoval separate output merging withName: CAT_FASTQ { ext.prefix = { "${meta.id}_${meta.run_accession}" } @@ -213,12 +250,12 @@ process { } withName: PORECHOP_PORECHOP { - ext.prefix = { "${meta.id}_${meta.run_accession}" } + ext.prefix = { "${meta.id}_${meta.run_accession}_porechop" } publishDir = [ [ path: { "${params.outdir}/porechop" }, mode: params.publish_dir_mode, - pattern: '*_porechopped.fastq.gz', + pattern: '*.fastq.gz', enabled: params.save_preprocessed_reads ], [ @@ -229,7 +266,31 @@ process { [ path: { "${params.outdir}/analysis_ready_fastqs" }, mode: params.publish_dir_mode, - pattern: '*_porechopped.fastq.gz', + pattern: '*.fastq.gz', + enabled: params.save_analysis_ready_fastqs, + saveAs: { ( params.perform_runmerging == false || ( params.perform_runmerging && !meta.is_multirun ) ) && !params.perform_longread_hostremoval && params.longread_qc_skipqualityfilter && !params.longread_qc_skipadaptertrim && params.perform_longread_qc && params.save_analysis_ready_fastqs ? it : null } + ] + ] + } + + withName: PORECHOP_ABI { + ext.prefix = { "${meta.id}_${meta.run_accession}_porechop_abi" } + publishDir = [ + [ + path: { "${params.outdir}/porechop_abi" }, + mode: params.publish_dir_mode, + pattern: '*.fastq.gz', + enabled: params.save_preprocessed_reads + ], + [ + path: { "${params.outdir}/porechop_abi" }, + mode: params.publish_dir_mode, + pattern: '*.log' + ], + [ + path: { "${params.outdir}/analysis_ready_fastqs" }, + mode: params.publish_dir_mode, + pattern: '*.fastq.gz', enabled: params.save_analysis_ready_fastqs, saveAs: { ( params.perform_runmerging == false || ( params.perform_runmerging && !meta.is_multirun ) ) && !params.perform_longread_hostremoval && params.longread_qc_skipqualityfilter && !params.longread_qc_skipadaptertrim && params.perform_longread_qc && params.save_analysis_ready_fastqs ? it : null } ] @@ -266,6 +327,36 @@ process { ] } + withName: NANOQ { + ext.args = [ + "-vv", + "--min-len ${params.longread_qc_qualityfilter_minlength}", + "--min-qual ${params.longread_qc_qualityfilter_minquality}" + ] + .join(' ').trim() + ext.prefix = { "${meta.id}_${meta.run_accession}_filtered" } + publishDir = [ + [ + path: { "${params.outdir}/nanoq" }, + mode: params.publish_dir_mode, + pattern: '*.fastq.gz', + enabled: params.save_preprocessed_reads + ], + [ + path: { "${params.outdir}/nanoq" }, + mode: params.publish_dir_mode, + pattern: '*.stats' + ], + [ + path: { "${params.outdir}/analysis_ready_fastqs" }, + mode: params.publish_dir_mode, + pattern: '*.fastq.gz', + enabled: params.save_analysis_ready_fastqs, + saveAs: { ( params.perform_runmerging == false || ( params.perform_runmerging && !meta.is_multirun ) ) && !params.perform_longread_hostremoval && !params.longread_qc_skipqualityfilter && params.perform_longread_qc && params.save_analysis_ready_fastqs ? it : null } + ] + ] + } + withName: BBMAP_BBDUK { ext.args = [ "entropy=${params.shortread_complexityfilter_entropy}", @@ -717,12 +808,12 @@ process { withName: GANON_CLASSIFY { tag = {"${meta.db_name}|${meta.id}"} - ext.args = params.ganon_save_readclassifications ? { "${meta.db_params} --output-all --output-lca --output-unclassified" } : { "${meta.db_params}" } + ext.args = params.ganon_save_readclassifications ? { "${meta.db_params} --output-all --output-unclassified" } : { "${meta.db_params}" } ext.prefix = params.perform_runmerging ? { "${meta.id}_${meta.db_name}.ganon" } : { "${meta.id}_${meta.run_accession}_${meta.db_name}.ganon" } publishDir = [ path: { "${params.outdir}/ganon/${meta.db_name}/" }, mode: params.publish_dir_mode, - pattern: '*.{tre,rep,lca,all,unc}' + pattern: '*.{tre,rep,one,all,unc,log}' ] } diff --git a/conf/test.config b/conf/test.config index 042dc2fa..0c6d260d 100644 --- a/conf/test.config +++ b/conf/test.config @@ -20,33 +20,34 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = true - perform_longread_qc = true - shortread_qc_mergepairs = true - perform_shortread_complexityfilter = true - perform_shortread_hostremoval = true - perform_longread_hostremoval = true - perform_runmerging = true - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = true - run_kraken2 = true - run_bracken = true - run_malt = false - run_metaphlan = true - run_centrifuge = true - run_diamond = true - run_krakenuniq = true - run_motus = false - run_ganon = true - run_krona = true - run_kmcp = true - krona_taxonomy_directory = params.pipelines_testdata_base_path + 'modules/data/genomics/sarscov2/metagenome/krona_taxonomy.tab' - malt_save_reads = true - kraken2_save_reads = true - centrifuge_save_reads = true - run_profile_standardisation = true + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = true + perform_shortread_redundancyestimation = true + perform_longread_qc = true + shortread_qc_mergepairs = true + perform_shortread_complexityfilter = true + perform_shortread_hostremoval = true + perform_longread_hostremoval = true + perform_runmerging = true + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = true + run_kraken2 = true + run_bracken = true + run_malt = false + run_metaphlan = true + run_centrifuge = true + run_diamond = true + run_krakenuniq = true + run_motus = false + run_ganon = true + run_krona = true + run_kmcp = true + krona_taxonomy_directory = params.pipelines_testdata_base_path + 'modules/data/genomics/sarscov2/metagenome/krona_taxonomy.tab' + malt_save_reads = true + kraken2_save_reads = true + centrifuge_save_reads = true + run_profile_standardisation = true } process { @@ -60,4 +61,7 @@ process { withName: MEGAN_RMA2INFO_KRONA { maxForks = 1 } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_adapterremoval.config b/conf/test_adapterremoval.config index ee55ba55..f6b2c727 100644 --- a/conf/test_adapterremoval.config +++ b/conf/test_adapterremoval.config @@ -48,4 +48,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_bbduk.config b/conf/test_bbduk.config index d0ff530a..6bb39510 100644 --- a/conf/test_bbduk.config +++ b/conf/test_bbduk.config @@ -48,4 +48,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_falco.config b/conf/test_falco.config index 8bcd9889..8e22cde1 100644 --- a/conf/test_falco.config +++ b/conf/test_falco.config @@ -48,4 +48,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_fastp.config b/conf/test_fastp.config index 81bec14c..48daab96 100644 --- a/conf/test_fastp.config +++ b/conf/test_fastp.config @@ -20,28 +20,29 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = true - perform_longread_qc = true - shortread_qc_tool = 'fastp' - perform_shortread_complexityfilter = true - shortread_complexityfilter_tool = 'fastp' - perform_shortread_hostremoval = true - perform_longread_hostremoval = true - perform_runmerging = true - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = true - run_kraken2 = true - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = false - run_ganon = false - run_kmcp = false + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = true + perform_longread_qc = true + shortread_qc_tool = 'fastp' + perform_shortread_redundancyestimation = true + perform_shortread_complexityfilter = true + shortread_complexityfilter_tool = 'fastp' + perform_shortread_hostremoval = true + perform_longread_hostremoval = true + perform_runmerging = true + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = true + run_kraken2 = true + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = false + run_ganon = false + run_kmcp = false } process { @@ -49,4 +50,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_full.config b/conf/test_full.config index 067940bb..91cb08c7 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -19,60 +19,61 @@ params { // Genome references hostremoval_reference = 'ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/819/615/GCA_000819615.1_ViralProj14015/GCA_000819615.1_ViralProj14015_genomic.fna.gz' - save_preprocessed_reads = false + save_preprocessed_reads = false - perform_shortread_qc = true - shortread_qc_mergepairs = true - perform_shortread_complexityfilter = false - save_complexityfiltered_reads = false + perform_shortread_qc = true + perform_shortread_redundancyestimation = true + shortread_qc_mergepairs = true + perform_shortread_complexityfilter = false + save_complexityfiltered_reads = false - perform_longread_qc = true - perform_shortread_hostremoval = true - perform_longread_hostremoval = true - save_hostremoval_index = false - save_hostremoval_bam = false - save_hostremoval_unmapped = false + perform_longread_qc = true + perform_shortread_hostremoval = true + perform_longread_hostremoval = true + save_hostremoval_index = false + save_hostremoval_bam = false + save_hostremoval_unmapped = false - perform_runmerging = true - save_runmerged_reads = false + perform_runmerging = true + save_runmerged_reads = false - save_analysis_ready_fastqs = true + save_analysis_ready_fastqs = true - run_centrifuge = true - centrifuge_save_reads = false + run_centrifuge = true + centrifuge_save_reads = false - run_diamond = true + run_diamond = true - run_kaiju = true + run_kaiju = true - run_kraken2 = true - kraken2_save_reads = false - kraken2_save_readclassifications = false - kraken2_save_minimizers = false + run_kraken2 = true + kraken2_save_reads = false + kraken2_save_readclassifications = false + kraken2_save_minimizers = false - run_krakenuniq = true - krakenuniq_save_reads = false - krakenuniq_save_readclassifications = false + run_krakenuniq = true + krakenuniq_save_reads = false + krakenuniq_save_readclassifications = false - run_bracken = true + run_bracken = true - run_malt = true - malt_save_reads = false - malt_generate_megansummary = true + run_malt = true + malt_save_reads = false + malt_generate_megansummary = true - run_metaphlan = true + run_metaphlan = true - run_motus = true - motus_save_mgc_read_counts = true + run_motus = true + motus_save_mgc_read_counts = true - run_ganon = true - ganon_save_readclassifications = true + run_ganon = true + ganon_save_readclassifications = true - run_kmcp = true - kmcp_save_search = true + run_kmcp = true + kmcp_save_search = true - run_profile_standardisation = true - run_krona = true + run_profile_standardisation = true + run_krona = true } cleanup = true diff --git a/conf/test_krakenuniq.config b/conf/test_krakenuniq.config index fc6305de..8611ddd6 100644 --- a/conf/test_krakenuniq.config +++ b/conf/test_krakenuniq.config @@ -24,34 +24,35 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_krakenuniq.csv' - perform_shortread_qc = true - perform_longread_qc = true - shortread_qc_mergepairs = true - perform_shortread_complexityfilter = true - perform_shortread_hostremoval = true - perform_longread_hostremoval = true - perform_runmerging = true - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = false - run_kraken2 = false - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = true - run_motus = false - run_kmcp = false - run_ganon = false - run_krona = true - krona_taxonomy_directory = params.pipelines_testdata_base_path + 'modules/data/genomics/sarscov2/metagenome/krona_taxonomy.tab' - malt_save_reads = false - kraken2_save_reads = false - centrifuge_save_reads = false - diamond_save_reads = false - run_profile_standardisation = true + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_krakenuniq.csv' + perform_shortread_qc = true + perform_longread_qc = true + perform_shortread_redundancyestimation = false + shortread_qc_mergepairs = true + perform_shortread_complexityfilter = true + perform_shortread_hostremoval = true + perform_longread_hostremoval = true + perform_runmerging = true + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = false + run_kraken2 = false + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = true + run_motus = false + run_kmcp = false + run_ganon = false + run_krona = true + krona_taxonomy_directory = params.pipelines_testdata_base_path + 'modules/data/genomics/sarscov2/metagenome/krona_taxonomy.tab' + malt_save_reads = false + kraken2_save_reads = false + centrifuge_save_reads = false + diamond_save_reads = false + run_profile_standardisation = true } process { @@ -64,4 +65,7 @@ process { withName: MEGAN_RMA2INFO_KRONA { maxForks = 1 } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_malt.config b/conf/test_malt.config index 7d9bd2b6..496306b9 100644 --- a/conf/test_malt.config +++ b/conf/test_malt.config @@ -24,30 +24,34 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet_malt.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = false - perform_longread_qc = false - perform_shortread_complexityfilter = false - perform_shortread_hostremoval = false - perform_longread_hostremoval = false - perform_runmerging = false - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = false - run_kraken2 = false - run_bracken = false - run_malt = true - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = false - run_ganon = false - run_kmcp = false + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet_malt.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = false + perform_longread_qc = false + perform_shortread_redundancyestimation = false + perform_shortread_complexityfilter = false + perform_shortread_hostremoval = false + perform_longread_hostremoval = false + perform_runmerging = false + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = false + run_kraken2 = false + run_bracken = false + run_malt = true + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = false + run_ganon = false + run_kmcp = false } process { withName: MALT_RUN { maxForks = 1 } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_motus.config b/conf/test_motus.config index c2d4ac22..c592a0a9 100644 --- a/conf/test_motus.config +++ b/conf/test_motus.config @@ -24,28 +24,38 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = 'database_motus.csv' - perform_shortread_qc = false - perform_longread_qc = false - perform_shortread_complexityfilter = false - perform_shortread_hostremoval = false - perform_longread_hostremoval = false - perform_runmerging = false - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = false - run_kraken2 = false - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = true - run_kmcp = false - run_ganon = false - motus_save_mgc_read_counts = false - motus_remove_ncbi_ids = false - motus_use_relative_abundance = false - run_profile_standardisation = true + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = 'database_motus.csv' + perform_shortread_qc = false + perform_longread_qc = false + perform_shortread_redundancyestimation = false + perform_shortread_complexityfilter = false + perform_shortread_hostremoval = false + perform_longread_hostremoval = false + perform_runmerging = false + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = false + run_kraken2 = false + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = true + run_kmcp = false + run_ganon = false + motus_save_mgc_read_counts = false + motus_remove_ncbi_ids = false + motus_use_relative_abundance = false + run_profile_standardisation = true +} + +process { + withName: MALT_RUN { + maxForks = 1 + } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_nopreprocessing.config b/conf/test_nopreprocessing.config index 42014303..267cd533 100644 --- a/conf/test_nopreprocessing.config +++ b/conf/test_nopreprocessing.config @@ -20,27 +20,28 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = false - perform_longread_qc = false - perform_shortread_complexityfilter = false - perform_shortread_hostremoval = false - perform_longread_hostremoval = false - perform_runmerging = false - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = true - run_kraken2 = true - run_bracken = true - run_malt = false // too big with other profiles on GHA - run_metaphlan = true - run_centrifuge = true - run_diamond = true - run_krakenuniq = true - run_motus = false - run_kmcp = true - run_ganon = true - run_krona = true + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = false + perform_longread_qc = false + perform_shortread_redundancyestimation = false + perform_shortread_complexityfilter = false + perform_shortread_hostremoval = false + perform_longread_hostremoval = false + perform_runmerging = false + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = true + run_kraken2 = true + run_bracken = true + run_malt = false // too big with other profiles on GHA + run_metaphlan = true + run_centrifuge = true + run_diamond = true + run_krakenuniq = true + run_motus = false + run_kmcp = true + run_ganon = true + run_krona = true } process { @@ -48,4 +49,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_noprofiling.config b/conf/test_noprofiling.config index 4e917fb9..36f2c3f9 100644 --- a/conf/test_noprofiling.config +++ b/conf/test_noprofiling.config @@ -20,31 +20,36 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = true - perform_longread_qc = true - shortread_qc_mergepairs = true - perform_shortread_complexityfilter = true - perform_shortread_hostremoval = true - perform_longread_hostremoval = true - perform_runmerging = true - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = false - run_kraken2 = false - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = false - run_kmcp = false - run_ganon = false + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = true + perform_longread_qc = true + perform_shortread_redundancyestimation = true + shortread_qc_mergepairs = true + perform_shortread_complexityfilter = true + perform_shortread_hostremoval = true + perform_longread_hostremoval = true + perform_runmerging = true + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = false + run_kraken2 = false + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = false + run_kmcp = false + run_ganon = false } process { withName: MALT_RUN { maxForks = 1 } + + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_nothing.config b/conf/test_nothing.config index d36c76d4..767bf943 100644 --- a/conf/test_nothing.config +++ b/conf/test_nothing.config @@ -20,26 +20,27 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = false - perform_longread_qc = false - perform_shortread_complexityfilter = false - perform_shortread_hostremoval = false - perform_longread_hostremoval = false - perform_runmerging = false - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = false - run_kraken2 = false - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = false - run_kmcp = false - run_ganon = false + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = false + perform_longread_qc = false + perform_shortread_redundancyestimation = false + perform_shortread_complexityfilter = false + perform_shortread_hostremoval = false + perform_longread_hostremoval = false + perform_runmerging = false + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = false + run_kraken2 = false + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = false + run_kmcp = false + run_ganon = false } process { @@ -47,4 +48,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/conf/test_prinseqplusplus.config b/conf/test_prinseqplusplus.config index c7ce2259..147d37cf 100644 --- a/conf/test_prinseqplusplus.config +++ b/conf/test_prinseqplusplus.config @@ -20,27 +20,28 @@ params { max_time = '6.h' // Input data - input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' - databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' - perform_shortread_qc = true - perform_longread_qc = true - perform_shortread_complexityfilter = true - shortread_complexityfilter_tool = 'prinseqplusplus' - perform_shortread_hostremoval = false - perform_longread_hostremoval = false - perform_runmerging = false - hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' - run_kaiju = true - run_kraken2 = true - run_bracken = false - run_malt = false - run_metaphlan = false - run_centrifuge = false - run_diamond = false - run_krakenuniq = false - run_motus = false - run_ganon = false - run_kmcp = false + input = params.pipelines_testdata_base_path + 'taxprofiler/samplesheet.csv' + databases = params.pipelines_testdata_base_path + 'taxprofiler/database_v1.1.csv' + perform_shortread_qc = true + perform_longread_qc = true + perform_shortread_redundancyestimation = false + perform_shortread_complexityfilter = true + shortread_complexityfilter_tool = 'prinseqplusplus' + perform_shortread_hostremoval = false + perform_longread_hostremoval = false + perform_runmerging = false + hostremoval_reference = params.pipelines_testdata_base_path + 'modules/data/genomics/homo_sapiens/genome/genome.fasta' + run_kaiju = true + run_kraken2 = true + run_bracken = false + run_malt = false + run_metaphlan = false + run_centrifuge = false + run_diamond = false + run_krakenuniq = false + run_motus = false + run_ganon = false + run_kmcp = false } process { @@ -48,4 +49,7 @@ process { maxForks = 1 ext.args = { "-m ${params.malt_mode} -J-Xmx12G" } } + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k 5" } + } } diff --git a/docs/images/taxprofiler_tube.pdf b/docs/images/taxprofiler_tube.pdf index 024d4aca..b3550c36 100644 Binary files a/docs/images/taxprofiler_tube.pdf and b/docs/images/taxprofiler_tube.pdf differ diff --git a/docs/images/taxprofiler_tube.png b/docs/images/taxprofiler_tube.png index 301d406a..b5363e39 100644 Binary files a/docs/images/taxprofiler_tube.png and b/docs/images/taxprofiler_tube.png differ diff --git a/docs/images/taxprofiler_tube.svg b/docs/images/taxprofiler_tube.svg index 6914d622..e8e6fc4f 100644 --- a/docs/images/taxprofiler_tube.svg +++ b/docs/images/taxprofiler_tube.svg @@ -26,7 +26,7 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="true" inkscape:document-units="mm" - showgrid="false" + showgrid="true" inkscape:snap-bbox="true" inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="false" @@ -55,7 +55,7 @@ spacingy="1" spacingx="1" units="mm" - visible="false" />QUALITY CONTROL(ADAPTER TRIMMING & (ADAPTER TRIMMING & MERGING)(COMPLEXITY (COMPLEXITY FILTERING)(COVERAGEESTIMATION)(HOST REMOVAL)SUMMARY STATISTICSfastpfastpAdapterRemovalBBDukPRINSEQ++Long ReadsBowtie2samtoolsstatssamtoolsstatscatminimap2samtools statsfalcoFastQCfalcoNonpareilfalcov1.1v1.2 +Output files + +- `nonpareil/` + + - `.npl` - log file of the nonpareil run. + - `.npo` - redundancy summary file. This is the most useful file and contains the information for generating metagenome coverage curves. These six columns are: seq. effort (_n_ reads), average redundancy, standard deviation, quartile 1, median (quartile 2), and quartile 3. + - `.npa` - raw version of npo but with all replicates not just a summary (average) at each point. These three columns are: seq. effort (_n_ reads), replicate ID, redundancy value. + - `.npc` - raw list with the number of reads in the dataset matching a query read. + - `.png` - rendered version of a Nonpareil curve, with extrapolation and sequencing effort information. + - `nonpareil_all_samples_mqc.{png,pdf}` summary of the plot of curves for all samples with sequencing effort information. + - `nonpareil_all_samples_mqc.{json,tsv,csv}` basic summary statistics of model, with additional curve and plotting information in the JSON. + + + + In most cases you will just want to look at the PNG files which contain the extrapolation information for estimating how much of the metagenome 'coverage' you will recover if you sequence more (i.e., to help indicate at what point you will just keep sequencing redundant reads that provide no more new taxonomic information). + + The `.npo` files can be used for re-generating and customising the plots using the companion `Nonpareil` R package. + ### Porechop [Porechop](https://github.com/rrwick/Porechop) is a tool for finding and removing adapters from Oxford Nanopore reads. Adapters on the ends of reads are trimmed and if a read has an adapter in its middle, it is considered a chimeric and it chopped into separate reads. @@ -154,6 +180,23 @@ You will only find the `.fastq` files in the results directory if you provide ` We do **not** recommend using Porechop if you are already trimming the adapters with ONT's basecaller Guppy. ::: +### Porechop_ABI + +[Porechop_ABI](https://github.com/bonsai-team/Porechop_ABI) is an extension of [Porechop](https://github.com/rrwick/Porechop). Porechop_ABI does not use any external knowledge or database for the adapters. Adapters are discovered directly from the reads using approximate k-mers counting and assembly. Then these sequences can be used for trimming, using all standard Porechop options. The software is able to report a combination of distinct sequences if a mix of adapters is used. It can also be used to check whether a dataset has already been trimmed out or not, or to find leftover adapters in datasets that have been previously processed with Guppy. + +
+Output files + +- `porechop_abi/` + - `.log`: Log file containing trimming statistics + - `.fastq.gz`: Adapter-trimmed file + +
+ +The output logs are saved in the output folder and are part of MultiQC report.You do not normally need to check these manually. + +You will only find the `.fastq` files in the results directory if you provide ` --save_preprocessed_reads`. Alternatively, if you wish only to have the 'final' reads that go into classification/profiling (i.e., that may have additional processing), do not specify this flag but rather specify `--save_analysis_ready_reads`, in which case the reads will be in the folder `analysis_ready_reads`. + ### BBDuk [BBDuk](https://jgi.doe.gov/data-and-tools/software-tools/bbtools/bb-tools-user-guide/bbduk-guide/) stands for Decontamination Using Kmers. BBDuk was developed to combine most common data-quality-related trimming, filtering, and masking operations into a single high-performance tool. @@ -204,7 +247,7 @@ The resulting `.fastq` files may _not_ always be the 'final' reads that go into Output files - `filtlong/` - - `_filtered.fastq.gz`: Quality or short read data filtered file + - `_filtered.fastq.gz`: Quality or long read data filtered file - `_filtered.log`: log file containing summary statistics @@ -215,6 +258,21 @@ You will only find the `.fastq` files in the results directory if you provide ` We do _not_ recommend using Filtlong if you are performing filtering of low quality reads with ONT's basecaller Guppy. ::: +### Nanoq + +[nanoq](https://github.com/esteinig/nanoq) is an ultra-fast quality filtering tool that also provides summary reports for nanopore reads. + +
+Output files + +- `nanoq/` + - `_filtered.fastq.gz`: Quality or long read data filtered file + - `_filtered.stats`: Summary statistics report + +
+ +You will only find the `.fastq` files in the results directory if you provide ` --save_preprocessed_reads`. Alternatively, if you wish only to have the 'final' reads that go into classification/profiling (i.e., that may have additional processing), do not specify this flag but rather specify `--save_analysis_ready_reads`, in which case the reads will be in the folder `analysis_ready_reads`. + ### Bowtie2 [Bowtie 2](https://bowtie-bio.sourceforge.net/bowtie2/index.shtml) is an ultrafast and memory-efficient tool for aligning sequencing reads to long reference sequences. It is particularly good at aligning reads of about 50 up to 100s or 1,000s of characters, and particularly good at aligning to relatively long (e.g. mammalian) genomes. @@ -560,9 +618,9 @@ The main taxonomic classification file from KMCP is the `*kmcp.profile` which is - `_report.tre`: output of `ganon report` containing taxonomic classifications with possible formatting and/or filtering depending on options specified. - ``.tre: output of `ganon classify` containing raw taxonomic classifications and abundance estimations with no additional formatting or filtering. - ``.rep: 'raw' report of counts against each taxon. - - ``.all: per-read summary of all hits of each reads. - - ``.lca: per-read summary of the best single hit after LCA for each read. - - ``.unc: list of read IDs with no hits. + - ``.all: per-read summary of all hits of each read. Only generated if `--ganon_save_readclassifications` specified. + - ``.one: per-read summary of the best single hit after the selection by the user specified multiple match method for each read. Only generated if `--ganon_save_readclassifications` specified. + - ``.unc: list of read IDs with no hits. Only generated if `--ganon_save_readclassifications` specified. - ``.log: the stdout console messages printed by `ganon classify`, containing some classification summary information - `ganon__combined_reports.txt`: A combined profile of all samples aligned to a given database (as generated by `ganon table`) @@ -646,8 +704,9 @@ All tools in taxprofiler supported by MultiQC will have a dedicated section show You can expect in the MultiQC reports either sections and/or general stats columns for the following tools: - fastqc -- adapterRemoval +- adapterremoval - fastp +- nonpareil - bbduk - prinseqplusplus - porechop diff --git a/docs/usage.md b/docs/usage.md index 35fede53..cb511840 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -234,6 +234,7 @@ You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-c nf-core/taxprofiler offers four main preprocessing steps for preprocessing raw sequencing reads: - [**Read processing**](#read-processing): adapter clipping and pair-merging. +- [**Redundancy estimation**](#redundancy-estimation): short-read metagenome coverage estimation. - [**Complexity filtering**](#complexity-filtering): removal of low-sequence complexity reads. - [**Host read-removal**](#host-read-removal): removal of reads aligning to reference genome(s) of a host. - [**Run merging**](#run-merging): concatenation of multiple FASTQ chunks/sequencing runs/libraries of a sample. @@ -255,10 +256,45 @@ By default, paired-end merging is not activated. In this case paired-end 'alignm You can also turn off clipping and only perform paired-end merging, if requested. This can be useful when processing data downloaded from the ENA, SRA, or DDBJ (`--shortread_qc_skipadaptertrim`). Both tools support length filtering of reads and can be tuned with `--shortread_qc_minlength`. Performing length filtering can be useful to remove short (often low sequencing complexity) sequences that result in unspecific classification and therefore slow down runtime during classification/profiling, with minimal gain. -There is currently one option for long-read Oxford Nanopore processing: [`porechop`](https://github.com/rrwick/Porechop). +There are currently two options for long-read Oxford Nanopore processing: [`porechop`](https://github.com/rrwick/Porechop), [`porechop_abi`](https://github.com/bonsai-team/Porechop_ABI). For both short-read and long-read preprocessing, you can optionally save the resulting processed reads with `--save_preprocessed_reads`. +#### Redundancy Estimation + +Metagenome 'coverage' or sequencing complexity estimations of short-read datasets can be activated with `--perform_shortread_redundancyestimation`. + +This turns on checking of read redundancy in a sequencing library using [Nonpareil](https://nonpareil.readthedocs.io/en/latest/), to provide an estimation of whether you have sequenced enough to capture all possible genomes present in your metagenomic sample (with the assumption that once you've sequenced enough, you will keep sequencing PCR amplicons rather than unique reads). + +This is only suitable for short-read, and in nf-core/taxprofiler specifically, FASTQ files. + +Nonpareil is performed on processed reads (i.e. after fastp or AdapterRemoval). This will run on either the first read of each read pair (as recommended by the authors), or on merged reads. + +Before using this tool please note the following caveats: + +:::warning + +- It is not recommended to run this on deep sequencing data, or very large datasets + - Nonpareil requires uncompressed FASTQ files, and nf-core/taxprofiler will uncompress these in your working directory, potentially with a extremely large hard-drive footprint. +- Your shortest reads _after_ processing should not go below 24bp (see warning below) +- It is not recommended to keep unmerged (`--shortread_qc_includeunmerged`) reads when using the calculation. + +:::info +If you get errors regarding the 'kmer' value is not correct, make sure your shortest reads _after_ processing is not less than 24bp. + +If this is the case you will need to specify in a custom config + +```nextflow +process { + withName: NONPAREIL_NONPAREIL { + ext.args = { "-k " } + } +} +``` + +Where `` should be at least the shortest read in your library +::: + #### Complexity Filtering Complexity filtering can be activated via the `--perform_shortread_complexityfilter` flag. @@ -267,7 +303,7 @@ Complexity filtering is primarily a run-time optimisation step. It is not necess There are currently three options for short-read complexity filtering: [`bbduk`](https://jgi.doe.gov/data-and-tools/software-tools/bbtools/bb-tools-user-guide/bbduk-guide/), [`prinseq++`](https://github.com/Adrian-Cantu/PRINSEQ-plus-plus), and [`fastp`](https://github.com/OpenGene/fastp#low-complexity-filter). -There is one option for long-read quality filtering: [`Filtlong`](https://github.com/rrwick/Filtlong) +There are two options for long-read quality filtering: [`Filtlong`](https://github.com/rrwick/Filtlong) and [`nanoq`](https://github.com/esteinig/nanoq), with `nanoq` being the default option. The tools offer different algorithms and parameters for removing low complexity reads and quality filtering. We therefore recommend reviewing the pipeline's [parameter documentation](https://nf-co.re/taxprofiler/parameters) and the documentation of the tools (see links above) to decide on optimal methods and parameters for your dataset. @@ -331,6 +367,8 @@ Centrifuge currently does not accept FASTA files as input, therefore no output w ##### DIAMOND +DIAMOND can only accept a single input read file. To run DIAMOND on paired-end reads, please merge the reads (e.g., using `--shortread_qc_mergepairs`). + DIAMOND only allows output of a single file format at a time, therefore parameters such `--diamond_save_reads` supplied will result in only aligned reads in SAM format will be produced, no taxonomic profiles will be available. Be aware of this when setting up your pipeline runs, depending on your particular use case. ##### Kaiju diff --git a/modules.json b/modules.json index b7fc0290..9c8ef6cc 100644 --- a/modules.json +++ b/modules.json @@ -7,238 +7,268 @@ "nf-core": { "adapterremoval": { "branch": "master", - "git_sha": "5add1e8e11af620c779462936ce8bbcc1abcef2d", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "bbmap/bbduk": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "bowtie2/align": { "branch": "master", - "git_sha": "fe54581f8bed20e4c4a51c616c93fd3379d89820", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "bowtie2/build": { "branch": "master", - "git_sha": "6a24fbe314bb2e6fe6306c29a63076ea87e8eb3c", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "bracken/bracken": { "branch": "master", - "git_sha": "093e35505936bce5127e1d14966b6cac91cd137f", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "bracken/combinebrackenoutputs": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "cat/fastq": { "branch": "master", - "git_sha": "5c460c5a4736974abde2843294f35307ee2b0e5e", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "centrifuge/centrifuge": { "branch": "master", - "git_sha": "9a07a1293d9b818d1e06d0f7b58152f74d462012", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "centrifuge/kreport": { "branch": "master", - "git_sha": "9a07a1293d9b818d1e06d0f7b58152f74d462012", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "diamond/blastx": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "falco": { "branch": "master", - "git_sha": "a236d2c2ec9e68db9b8501105d804acb359552b5", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "fastp": { "branch": "master", - "git_sha": "451d49b70f1801a9e5835f111c927104af64481e", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "fastqc": { "branch": "master", - "git_sha": "285a50500f9e02578d90b3ce6382ea3c30216acd", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "filtlong": { "branch": "master", - "git_sha": "b4c8ac68ffcdabac3f63aaa5e7420b175e1d8d76", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "ganon/classify": { "branch": "master", - "git_sha": "3b9d0fd0431442facdc816ca0c731f9807c47ebd", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "ganon/report": { "branch": "master", - "git_sha": "f61e38c82ca2bbb8dfa740822df6f2b75f2d8a86", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "ganon/table": { "branch": "master", - "git_sha": "c02373677641897c9744c0f55f0c12fd79232c71", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "gunzip": { "branch": "master", - "git_sha": "e06548bfa36ee31869b81041879dd6b3a83b1d57", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kaiju/kaiju": { "branch": "master", - "git_sha": "3db50674956b1fb3741a44eb917458d788a50197", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kaiju/kaiju2krona": { "branch": "master", - "git_sha": "3db50674956b1fb3741a44eb917458d788a50197", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kaiju/kaiju2table": { "branch": "master", - "git_sha": "3db50674956b1fb3741a44eb917458d788a50197", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kmcp/profile": { "branch": "master", - "git_sha": "6f56948d0674ad5870035e80c7af209a51d8e243", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kmcp/search": { "branch": "master", - "git_sha": "64cd3f418b191a008b9d362b8ccf0216ae0302d5", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "kraken2/kraken2": { "branch": "master", - "git_sha": "603ecbd9f45300c9788f197d2a15a005685b4220", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "krakentools/combinekreports": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "krakentools/kreport2krona": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "krakenuniq/preloadedkrakenuniq": { "branch": "master", - "git_sha": "9de9365c3ca6071ec01705919f6667c718ef47b4", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "krona/ktimporttaxonomy": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "krona/ktimporttext": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "malt/run": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "megan/rma2info": { "branch": "master", - "git_sha": "dbce8951ff9a39ad08d87e563636bbcc6ef34032", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "metaphlan/mergemetaphlantables": { "branch": "master", - "git_sha": "efae1c431e539d6a6d323ee2e9223c4b81a152ce", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "metaphlan/metaphlan": { "branch": "master", - "git_sha": "1038d3de36263159b4138324a646105941ac271a", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "minimap2/align": { "branch": "master", - "git_sha": "603ecbd9f45300c9788f197d2a15a005685b4220", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "minimap2/index": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "motus/merge": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "e743b2dea725bcfc4b76a209981808987332013a", "installed_by": ["modules"] }, "motus/profile": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "b7ebe95761cd389603f9cc0e0dc384c0f663815a", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "nanoq": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "nonpareil/curve": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "nonpareil/nonpareil": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "nonpareil/nonpareilcurvesr": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "nonpareil/set": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", + "installed_by": ["modules"] + }, + "porechop/abi": { + "branch": "master", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "porechop/porechop": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"], "patch": "modules/nf-core/porechop/porechop/porechop-porechop.diff" }, "prinseqplusplus": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "samtools/fastq": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "samtools/index": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "samtools/stats": { "branch": "master", - "git_sha": "735e1e04e7e01751d2d6e97055bbdb6f70683cc1", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "samtools/view": { "branch": "master", - "git_sha": "3ffae3598260a99e8db3207dead9f73f87f90d1f", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "taxpasta/merge": { "branch": "master", - "git_sha": "4fd9089d3cf904e0b870d5a6a7ab903ee5e1004d", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "taxpasta/standardise": { "branch": "master", - "git_sha": "4fd9089d3cf904e0b870d5a6a7ab903ee5e1004d", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] }, "untar": { "branch": "master", - "git_sha": "d0b4fc03af52a1cc8c6fb4493b921b57352b1dd8", + "git_sha": "06c8865e36741e05ad32ef70ab3fac127486af48", "installed_by": ["modules"] } } @@ -247,12 +277,12 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "5caf7640a9ef1d18d765d55339be751bb0969dfa", + "git_sha": "d20fb2a9cc3e2835e9d067d1046a63252eb17352", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "92de218a329bfc9a9033116eb5f65fd270e72ba3", + "git_sha": "2fdce49d30c0254f76bc0f13c55c17455c1251ab", "installed_by": ["subworkflows"] }, "utils_nfvalidation_plugin": { diff --git a/modules/nf-core/adapterremoval/environment.yml b/modules/nf-core/adapterremoval/environment.yml index 1737b14b..0e089bfb 100644 --- a/modules/nf-core/adapterremoval/environment.yml +++ b/modules/nf-core/adapterremoval/environment.yml @@ -1,7 +1,5 @@ -name: adapterremoval channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::adapterremoval=2.3.2 diff --git a/modules/nf-core/adapterremoval/tests/main.nf.test b/modules/nf-core/adapterremoval/tests/main.nf.test index 91c07b7e..5b5d4227 100644 --- a/modules/nf-core/adapterremoval/tests/main.nf.test +++ b/modules/nf-core/adapterremoval/tests/main.nf.test @@ -15,7 +15,7 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:true, collapse:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = [] """ @@ -39,8 +39,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false, collapse:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['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) ] ] input[1] = [] """ @@ -68,8 +68,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['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) ] ] input[1] = [] """ @@ -96,8 +96,8 @@ nextflow_process { """ input[0] = [ [ id:'test', single_end:false, collapse:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['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) ] ] input[1] = file("https://github.com/nf-core/test-datasets/raw/modules/data/delete_me/adapterremoval/adapterremoval_adapterlist.txt", checkIfExists: true) diff --git a/modules/nf-core/bbmap/bbduk/environment.yml b/modules/nf-core/bbmap/bbduk/environment.yml new file mode 100644 index 00000000..cbe6f2a0 --- /dev/null +++ b/modules/nf-core/bbmap/bbduk/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bbmap=39.06 diff --git a/modules/nf-core/bbmap/bbduk/main.nf b/modules/nf-core/bbmap/bbduk/main.nf index 001e27d4..e5747fe8 100644 --- a/modules/nf-core/bbmap/bbduk/main.nf +++ b/modules/nf-core/bbmap/bbduk/main.nf @@ -2,10 +2,10 @@ process BBMAP_BBDUK { tag "$meta.id" label 'process_medium' - conda "bioconda::bbmap=39.01" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bbmap:39.01--h5c4e2a8_0': - 'biocontainers/bbmap:39.01--h5c4e2a8_0' }" + 'https://depot.galaxyproject.org/singularity/bbmap:39.06--h92535d8_1': + 'biocontainers/bbmap:39.06--h92535d8_1' }" input: tuple val(meta), path(reads) @@ -40,4 +40,18 @@ process BBMAP_BBDUK { bbmap: \$(bbversion.sh | grep -v "Duplicate cpuset") END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def output_command = meta.single_end ? "echo '' | gzip > ${prefix}.fastq.gz" : "echo '' | gzip > ${prefix}_1.fastq.gz ; echo '' | gzip > ${prefix}_2.fastq.gz" + """ + touch ${prefix}.bbduk.log + $output_command + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + bbmap: \$(bbversion.sh | grep -v "Duplicate cpuset") + END_VERSIONS + """ } diff --git a/modules/nf-core/bbmap/bbduk/meta.yml b/modules/nf-core/bbmap/bbduk/meta.yml index c1719918..9a1f0562 100644 --- a/modules/nf-core/bbmap/bbduk/meta.yml +++ b/modules/nf-core/bbmap/bbduk/meta.yml @@ -10,9 +10,7 @@ tools: description: BBMap is a short read aligner, as well as various other bioinformatic tools. homepage: https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/ documentation: https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/ - licence: ["UC-LBL license (see package)"] - input: - meta: type: map @@ -28,7 +26,6 @@ input: type: file description: | Reference files containing adapter and/or contaminant sequences for sequence kmer matching - output: - meta: type: map @@ -47,6 +44,7 @@ output: type: file description: Bbduk log file pattern: "*bbduk.log" - authors: - "@MGordon09" +maintainers: + - "@MGordon09" diff --git a/modules/nf-core/bbmap/bbduk/tests/main.nf.test b/modules/nf-core/bbmap/bbduk/tests/main.nf.test new file mode 100644 index 00000000..0f3e8187 --- /dev/null +++ b/modules/nf-core/bbmap/bbduk/tests/main.nf.test @@ -0,0 +1,169 @@ +nextflow_process { + + name "Test Process BBMAP_BBDUK" + script "../main.nf" + process "BBMAP_BBDUK" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "bbmap" + tag "bbmap/bbduk" + + test("sarscov2 - single end fastq - fastq") { + + when { + process { + """ + input[0] = [ + [ 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] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Input is being processed as unpaired")}, + { assert snapshot(process.out.reads, + process.out.versions).match() } + ) + } + + } + + test("sarscov2 - paired end fastq - fastq") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Input is being processed as paired")}, + { assert snapshot(process.out.reads, + process.out.versions).match() } + + ) + } + } + + test("sarscov2 - single end w/ contams [fastq,fasta] - fastq") { + + when { + process { + """ + input[0] = [ + [ 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] = [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/transcriptome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.reads.get(0).get(1).endsWith("test.trim.fastq.gz") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Input is being processed as unpaired")}, + { assert snapshot(process.out.versions).match() } + + ) + } + } + + test("sarscov2 - paired end w/ contams [fastq,fasta] - fastq") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/transcriptome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.reads.get(0).get(1).get(0).endsWith("test.trim_1.fastq.gz") }, + { assert process.out.reads.get(0).get(1).get(1).endsWith("test.trim_2.fastq.gz") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Input is being processed as paired")}, + { assert snapshot(process.out.versions).match() } + + ) + } + } + + test("sarscov2 - single end fastq - fastq - stub") { + + options "-stub" + when { + process { + """ + input[0] = [ + [ 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] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + + ) + } + + } + + test("sarscov2 - paired end fastq - fastq - 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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/bbmap/bbduk/tests/main.nf.test.snap b/modules/nf-core/bbmap/bbduk/tests/main.nf.test.snap new file mode 100644 index 00000000..2f0ac2b4 --- /dev/null +++ b/modules/nf-core/bbmap/bbduk/tests/main.nf.test.snap @@ -0,0 +1,183 @@ +{ + "sarscov2 - paired end fastq - fastq": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.trim_1.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec", + "test.trim_2.fastq.gz:md5,2ebae722295ea66d84075a3b042e2b42" + ] + ] + ], + [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:11:43.393701616" + }, + "sarscov2 - single end w/ contams [fastq,fasta] - fastq": { + "content": [ + [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:30:39.201243568" + }, + "sarscov2 - paired end w/ contams [fastq,fasta] - fastq": { + "content": [ + [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:48:13.446399236" + }, + "sarscov2 - paired end fastq - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.trim.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.trim.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:12:31.910356296" + }, + "sarscov2 - single end fastq - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:12:22.081697889" + }, + "sarscov2 - single end fastq - fastq": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + [ + "versions.yml:md5,652ed24469a355fbc7a4ca892d23133e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T13:11:31.383328059" + } +} \ No newline at end of file diff --git a/modules/nf-core/bbmap/bbduk/tests/nextflow.config b/modules/nf-core/bbmap/bbduk/tests/nextflow.config new file mode 100644 index 00000000..44c775dc --- /dev/null +++ b/modules/nf-core/bbmap/bbduk/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + + withName: BBMAP_BBDUK { + ext.args = 'trimq=10 qtrim=r' + ext.prefix = { "${meta.id}.trim" } + } + +} diff --git a/modules/nf-core/bbmap/bbduk/tests/tags.yml b/modules/nf-core/bbmap/bbduk/tests/tags.yml new file mode 100644 index 00000000..16d6171a --- /dev/null +++ b/modules/nf-core/bbmap/bbduk/tests/tags.yml @@ -0,0 +1,2 @@ +bbmap/bbduk: + - "modules/nf-core/bbmap/bbduk/**" diff --git a/modules/nf-core/bowtie2/align/environment.yml b/modules/nf-core/bowtie2/align/environment.yml new file mode 100644 index 00000000..9090f218 --- /dev/null +++ b/modules/nf-core/bowtie2/align/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bowtie2=2.5.2 + - bioconda::samtools=1.18 + - conda-forge::pigz=2.6 diff --git a/modules/nf-core/bowtie2/align/main.nf b/modules/nf-core/bowtie2/align/main.nf index a77114d2..809525ad 100644 --- a/modules/nf-core/bowtie2/align/main.nf +++ b/modules/nf-core/bowtie2/align/main.nf @@ -1,22 +1,27 @@ process BOWTIE2_ALIGN { tag "$meta.id" - label "process_high" + label 'process_high' - conda "bioconda::bowtie2=2.4.4 bioconda::samtools=1.16.1 conda-forge::pigz=2.6" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-ac74a7f02cebcfcc07d8e8d1d750af9c83b4d45a:a0ffedb52808e102887f6ce600d092675bf3528a-0' : - 'biocontainers/mulled-v2-ac74a7f02cebcfcc07d8e8d1d750af9c83b4d45a:a0ffedb52808e102887f6ce600d092675bf3528a-0' }" + 'https://depot.galaxyproject.org/singularity/mulled-v2-ac74a7f02cebcfcc07d8e8d1d750af9c83b4d45a:f70b31a2db15c023d641c32f433fb02cd04df5a6-0' : + 'biocontainers/mulled-v2-ac74a7f02cebcfcc07d8e8d1d750af9c83b4d45a:f70b31a2db15c023d641c32f433fb02cd04df5a6-0' }" input: tuple val(meta) , path(reads) tuple val(meta2), path(index) + tuple val(meta3), path(fasta) val save_unaligned val sort_bam output: - tuple val(meta), path("*.{bam,sam}"), emit: aligned + tuple val(meta), path("*.sam") , emit: sam , optional:true + tuple val(meta), path("*.bam") , emit: bam , optional:true + tuple val(meta), path("*.cram") , emit: cram , optional:true + tuple val(meta), path("*.csi") , emit: csi , optional:true + tuple val(meta), path("*.crai") , emit: crai , optional:true tuple val(meta), path("*.log") , emit: log - tuple val(meta), path("*fastq.gz") , emit: fastq, optional:true + tuple val(meta), path("*fastq.gz") , emit: fastq , optional:true path "versions.yml" , emit: versions when: @@ -39,7 +44,10 @@ process BOWTIE2_ALIGN { def samtools_command = sort_bam ? 'sort' : 'view' def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension = (args2 ==~ extension_pattern) ? (args2 =~ extension_pattern)[0][2].toLowerCase() : "bam" + def extension_matcher = (args2 =~ extension_pattern) + def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" + def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" + if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" """ INDEX=`find -L ./ -name "*.rev.1.bt2" | sed "s/\\.rev.1.bt2\$//"` @@ -52,8 +60,8 @@ process BOWTIE2_ALIGN { --threads $task.cpus \\ $unaligned \\ $args \\ - 2> ${prefix}.bowtie2.log \\ - | samtools $samtools_command $args2 --threads $task.cpus -o ${prefix}.${extension} - + 2> >(tee ${prefix}.bowtie2.log >&2) \\ + | samtools $samtools_command $args2 --threads $task.cpus ${reference} -o ${prefix}.${extension} - if [ -f ${prefix}.unmapped.fastq.1.gz ]; then mv ${prefix}.unmapped.fastq.1.gz ${prefix}.unmapped_1.fastq.gz @@ -76,12 +84,27 @@ process BOWTIE2_ALIGN { def prefix = task.ext.prefix ?: "${meta.id}" def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ def extension = (args2 ==~ extension_pattern) ? (args2 =~ extension_pattern)[0][2].toLowerCase() : "bam" + def create_unmapped = "" + if (meta.single_end) { + create_unmapped = save_unaligned ? "touch ${prefix}.unmapped.fastq.gz" : "" + } else { + create_unmapped = save_unaligned ? "touch ${prefix}.unmapped_1.fastq.gz && touch ${prefix}.unmapped_2.fastq.gz" : "" + } + def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" + if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + + def create_index = "" + if (extension == "cram") { + create_index = "touch ${prefix}.crai" + } else if (extension == "bam") { + create_index = "touch ${prefix}.csi" + } """ touch ${prefix}.${extension} + ${create_index} touch ${prefix}.bowtie2.log - touch ${prefix}.unmapped_1.fastq.gz - touch ${prefix}.unmapped_2.fastq.gz + ${create_unmapped} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bowtie2/align/meta.yml b/modules/nf-core/bowtie2/align/meta.yml index 60d04c12..38610e0e 100644 --- a/modules/nf-core/bowtie2/align/meta.yml +++ b/modules/nf-core/bowtie2/align/meta.yml @@ -36,6 +36,15 @@ input: type: file description: Bowtie2 genome index files pattern: "*.ebwt" + - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Bowtie2 genome fasta file + pattern: "*.fasta" - save_unaligned: type: boolean description: | @@ -46,22 +55,41 @@ input: description: use samtools sort (true) or samtools view (false) pattern: "true or false" output: - - aligned: + - sam: type: file - description: Output BAM/SAM file containing read alignments - pattern: "*.{bam,sam}" - - versions: + description: Output SAM file containing read alignments + pattern: "*.sam" + - bam: type: file - description: File containing software versions - pattern: "versions.yml" - - fastq: + description: Output BAM file containing read alignments + pattern: "*.bam" + - cram: type: file - description: Unaligned FastQ files - pattern: "*.fastq.gz" + description: Output CRAM file containing read alignments + pattern: "*.cram" + - csi: + type: file + description: Output SAM/BAM index for large inputs + pattern: "*.csi" + - crai: + type: file + description: Output CRAM index + pattern: "*.crai" - log: type: file description: Aligment log pattern: "*.log" + - fastq: + type: file + description: Unaligned FastQ files + pattern: "*.fastq.gz" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@joseespinosa" - "@drpatelh" +maintainers: + - "@joseespinosa" + - "@drpatelh" diff --git a/modules/nf-core/bowtie2/align/tests/cram_crai.config b/modules/nf-core/bowtie2/align/tests/cram_crai.config new file mode 100644 index 00000000..03f1d5e5 --- /dev/null +++ b/modules/nf-core/bowtie2/align/tests/cram_crai.config @@ -0,0 +1,5 @@ +process { + withName: BOWTIE2_ALIGN { + ext.args2 = '--output-fmt cram --write-index' + } +} diff --git a/modules/nf-core/bowtie2/align/tests/large_index.config b/modules/nf-core/bowtie2/align/tests/large_index.config new file mode 100644 index 00000000..fdc1c59d --- /dev/null +++ b/modules/nf-core/bowtie2/align/tests/large_index.config @@ -0,0 +1,5 @@ +process { + withName: BOWTIE2_BUILD { + ext.args = '--large-index' + } +} \ No newline at end of file diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test b/modules/nf-core/bowtie2/align/tests/main.nf.test new file mode 100644 index 00000000..0de5950f --- /dev/null +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test @@ -0,0 +1,623 @@ +nextflow_process { + + name "Test Process BOWTIE2_ALIGN" + script "../main.nf" + process "BOWTIE2_ALIGN" + tag "modules" + tag "modules_nfcore" + tag "bowtie2" + tag "bowtie2/build" + tag "bowtie2/align" + + test("sarscov2 - fastq, index, fasta, false, false - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, false, false - sam") { + + config "./sam.config" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.sam[0][1]).readLines()[0..4], + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, false, false - sam2") { + + config "./sam2.config" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.sam[0][1]).readLines()[0..4], + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, false, true - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, false, false - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, false, true - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, large_index, fasta, false, false - bam") { + + config "./large_index.config" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], large_index, fasta, false, false - bam") { + + config "./large_index.config" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, true, false - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, true, false - bam") { + + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + process.out.log, + process.out.fastq, + process.out.versions + ).match() } + + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, true, true - cram") { + + config "./cram_crai.config" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = true //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.cram[0][1]).name, + file(process.out.crai[0][1]).name + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], index, fasta, false, false - stub") { + + options "-stub" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + file(process.out.csi[0][1]).name, + file(process.out.log[0][1]).name, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, index, fasta, true, false - stub") { + + options "-stub" + setup { + run("BOWTIE2_BUILD") { + script "../../build/main.nf" + process { + """ + input[0] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ 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] = BOWTIE2_BUILD.out.index + input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false //save_unaligned + input[4] = false //sort + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + file(process.out.csi[0][1]).name, + file(process.out.log[0][1]).name, + process.out.fastq, + process.out.versions + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test.snap b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap new file mode 100644 index 00000000..028e7da6 --- /dev/null +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap @@ -0,0 +1,311 @@ +{ + "sarscov2 - [fastq1, fastq2], large_index, fasta, false, false - bam": { + "content": [ + "test.bam", + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2.log:md5,bd89ce1b28c93bf822bae391ffcedd19" + ] + ], + [ + + ], + [ + "versions.yml:md5,01d18ab035146ea790e9a0f70adb758f" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-03-18T13:19:25.337323" + }, + "sarscov2 - fastq, index, fasta, false, false - sam2": { + "content": [ + [ + "ERR5069949.2151832\t16\tMT192765.1\t17453\t42\t150M\t*\t0\t0\tACGCACATTGCTAACTAAGGGCACACTAGAACCAGAATATTTCAATTCAGTGTGTAGACTTATGAAAACTATAGGTCCAGACATGTTCCTCGGAACTTGTCGGCGTTGTCCTGCTGAAATTGTTGACACTGTGAGTGCTTTGGTTTATGA\tAAAA versions.yml "${task.process}": - bracken: ${VERSION} + bracken: \$(echo \$(bracken -v) | cut -f2 -d'v') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + bracken_report = "${prefix}.tsv" + bracken_kraken_style_report = "${prefix}.kraken2.report_bracken.txt" + """ + touch ${prefix}.tsv + touch ${bracken_kraken_style_report} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + bracken: \$(echo \$(bracken -v) | cut -f2 -d'v') END_VERSIONS """ } diff --git a/modules/nf-core/bracken/bracken/meta.yml b/modules/nf-core/bracken/bracken/meta.yml index 43f0455a..b7ff4489 100644 --- a/modules/nf-core/bracken/bracken/meta.yml +++ b/modules/nf-core/bracken/bracken/meta.yml @@ -13,7 +13,6 @@ tools: tool_dev_url: https://github.com/jenniferlu717/Bracken doi: "10.7717/peerj-cs.104" licence: ["GPL v3"] - input: - meta: type: map @@ -28,7 +27,6 @@ input: type: file description: Directory containing the kraken2/Bracken files for analysis pattern: "*" - output: - meta: type: map @@ -47,6 +45,7 @@ output: type: file description: TXT file of bracken corrected results of Kraken2 report output pattern: "*.txt" - authors: - "@Midnighter" +maintainers: + - "@Midnighter" diff --git a/modules/nf-core/bracken/bracken/tests/genus_test.config b/modules/nf-core/bracken/bracken/tests/genus_test.config new file mode 100644 index 00000000..bc5f63ae --- /dev/null +++ b/modules/nf-core/bracken/bracken/tests/genus_test.config @@ -0,0 +1,5 @@ +process { + withName: BRACKEN_BRACKEN { + ext.args = "-l G -t 10 -r 150" + } +} diff --git a/modules/nf-core/bracken/bracken/tests/main.nf.test b/modules/nf-core/bracken/bracken/tests/main.nf.test new file mode 100644 index 00000000..9d2105de --- /dev/null +++ b/modules/nf-core/bracken/bracken/tests/main.nf.test @@ -0,0 +1,167 @@ +nextflow_process { + + name "Test Process BRACKEN_BRACKEN" + script "../main.nf" + process "BRACKEN_BRACKEN" + + tag "modules" + tag "modules_nfcore" + tag "bracken" + tag "bracken/bracken" + tag "kraken2/kraken2" + tag "untar" + + setup { + run ("UNTAR") { + script "../../../untar/main.nf" + process { + """ + input[0] = [[],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2_bracken.tar.gz', checkIfExists: true)] + """ + } + } + } + + test("sarscov2 - single-end - fastq") { + + config "./nextflow.config" + + setup { + run("KRAKEN2_KRAKEN2") { + script "../../../kraken2/kraken2/main.nf" + 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]} + input[2] = false + input[3] = false + """ + } + } + } + + when { + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + input[1] = UNTAR.out.untar.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - paired-end - fastq - genus config") { + + config "./genus_test.config" + + setup { + run("KRAKEN2_KRAKEN2") { + script "../../../kraken2/kraken2/main.nf" + process { + """ + input[0] = [ + [id: 'test', single_end: false], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = UNTAR.out.untar.map{it[1]} + input[2] = false + input[3] = false + """ + } + } + } + + when { + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + input[1] = UNTAR.out.untar.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - paired-end - fastq") { + + config "./nextflow.config" + + setup { + run("KRAKEN2_KRAKEN2") { + script "../../../kraken2/kraken2/main.nf" + process { + """ + input[0] = [ + [id: 'test', single_end: false], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = UNTAR.out.untar.map{it[1]} + input[2] = false + input[3] = false + """ + } + } + } + + when { + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + input[1] = UNTAR.out.untar.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - stub - fastq") { + + options "-stub" + + when { + process { + """ + input[0] = [[id: 'test'],file(params.modules_testdata_base_path + 'generic/txt/hello.txt', checkIfExists: true)] + input[1] = UNTAR.out.untar.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/bracken/bracken/tests/main.nf.test.snap b/modules/nf-core/bracken/bracken/tests/main.nf.test.snap new file mode 100644 index 00000000..c97a4c71 --- /dev/null +++ b/modules/nf-core/bracken/bracken/tests/main.nf.test.snap @@ -0,0 +1,210 @@ +{ + "sarscov2 - single-end - fastq": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tsv:md5,4a21ae14ff8a0311d55f139af5247838" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.kraken2.report_bracken.txt:md5,ca0fbeedc4353b5fdd081688823a33df" + ] + ], + "2": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ], + "reports": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tsv:md5,4a21ae14ff8a0311d55f139af5247838" + ] + ], + "txt": [ + [ + { + "id": "test", + "single_end": true + }, + "test.kraken2.report_bracken.txt:md5,ca0fbeedc4353b5fdd081688823a33df" + ] + ], + "versions": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-06T11:35:03.995620397" + }, + "sarscov2 - paired-end - fastq - genus config": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv:md5,f609b09d6edb5ebc1ea1435d1dd46cde" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.kraken2.report_bracken.txt:md5,2ce58814420a3690da1f08e10e8d3a30" + ] + ], + "2": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ], + "reports": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv:md5,f609b09d6edb5ebc1ea1435d1dd46cde" + ] + ], + "txt": [ + [ + { + "id": "test", + "single_end": false + }, + "test.kraken2.report_bracken.txt:md5,2ce58814420a3690da1f08e10e8d3a30" + ] + ], + "versions": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-06T12:13:33.399680181" + }, + "sarscov2 - paired-end - fastq": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv:md5,4a21ae14ff8a0311d55f139af5247838" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.kraken2.report_bracken.txt:md5,ca0fbeedc4353b5fdd081688823a33df" + ] + ], + "2": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ], + "reports": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv:md5,4a21ae14ff8a0311d55f139af5247838" + ] + ], + "txt": [ + [ + { + "id": "test", + "single_end": false + }, + "test.kraken2.report_bracken.txt:md5,ca0fbeedc4353b5fdd081688823a33df" + ] + ], + "versions": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-06T12:09:15.465609745" + }, + "sarscov2 - stub - fastq": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.kraken2.report_bracken.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ], + "reports": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "txt": [ + [ + { + "id": "test" + }, + "test.kraken2.report_bracken.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,599fbbf4c1cd5851022a98788f2afdba" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-06T11:35:42.965471207" + } +} \ No newline at end of file diff --git a/modules/nf-core/bracken/bracken/tests/nextflow.config b/modules/nf-core/bracken/bracken/tests/nextflow.config new file mode 100644 index 00000000..b550b748 --- /dev/null +++ b/modules/nf-core/bracken/bracken/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: BRACKEN_BRACKEN { + ext.args = "-l S -t 10 -r 150" + } +} diff --git a/modules/nf-core/bracken/bracken/tests/tags.yml b/modules/nf-core/bracken/bracken/tests/tags.yml new file mode 100644 index 00000000..6a2cbd38 --- /dev/null +++ b/modules/nf-core/bracken/bracken/tests/tags.yml @@ -0,0 +1,2 @@ +bracken/bracken: + - "modules/nf-core/bracken/bracken/**" diff --git a/modules/nf-core/bracken/combinebrackenoutputs/environment.yml b/modules/nf-core/bracken/combinebrackenoutputs/environment.yml new file mode 100644 index 00000000..b96b00d7 --- /dev/null +++ b/modules/nf-core/bracken/combinebrackenoutputs/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::bracken=2.9" diff --git a/modules/nf-core/bracken/combinebrackenoutputs/main.nf b/modules/nf-core/bracken/combinebrackenoutputs/main.nf index 6a3a22e2..4360849f 100644 --- a/modules/nf-core/bracken/combinebrackenoutputs/main.nf +++ b/modules/nf-core/bracken/combinebrackenoutputs/main.nf @@ -2,11 +2,10 @@ process BRACKEN_COMBINEBRACKENOUTPUTS { tag "$meta.id" label 'process_low' - conda "bioconda::bracken=2.7" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bracken:2.7--py39hc16433a_0': - 'biocontainers/bracken:2.7--py39hc16433a_0' }" - + 'https://depot.galaxyproject.org/singularity/bracken:2.9--py38h2494328_0': + 'biocontainers/bracken:2.9--py38h2494328_0' }" input: tuple val(meta), path(input) @@ -22,7 +21,7 @@ process BRACKEN_COMBINEBRACKENOUTPUTS { def prefix = task.ext.prefix ?: "${meta.id}" // WARN: Version information not provided by tool on CLI. // Please update version string below when bumping container versions. - def VERSION = '2.7' + def VERSION = '2.9' """ combine_bracken_outputs.py \\ $args \\ @@ -34,4 +33,19 @@ process BRACKEN_COMBINEBRACKENOUTPUTS { combine_bracken_output: ${VERSION} END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + // WARN: Version information not provided by tool on CLI. + // Please update version string below when bumping container versions. + def VERSION = '2.9' + """ + touch ${prefix}.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + combine_bracken_output: ${VERSION} + END_VERSIONS + """ } diff --git a/modules/nf-core/bracken/combinebrackenoutputs/meta.yml b/modules/nf-core/bracken/combinebrackenoutputs/meta.yml index 9ad53859..426d0099 100644 --- a/modules/nf-core/bracken/combinebrackenoutputs/meta.yml +++ b/modules/nf-core/bracken/combinebrackenoutputs/meta.yml @@ -1,7 +1,10 @@ name: "bracken_combinebrackenoutputs" description: Combine output of metagenomic samples analyzed by bracken. keywords: - - sort + - bracken + - metagenomics + - postprocessing + - reporting tools: - "bracken": description: Bracken (Bayesian Reestimation of Abundance with KrakEN) is a highly accurate statistical method that computes the abundance of species in DNA sequences from a metagenomics sample. @@ -10,7 +13,6 @@ tools: tool_dev_url: https://github.com/jenniferlu717/Bracken doi: "10.7717/peerj-cs.104" licence: ["GPL v3"] - input: - meta: type: map @@ -21,7 +23,6 @@ input: type: file description: List of output files from bracken pattern: "*" - output: - meta: type: map @@ -36,6 +37,7 @@ output: type: file description: Combined output in table format pattern: "*.txt" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test b/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test new file mode 100644 index 00000000..e1504702 --- /dev/null +++ b/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test @@ -0,0 +1,103 @@ +nextflow_process { + + name "Test Process BRACKEN_COMBINEBRACKENOUTPUTS" + script "../main.nf" + process "BRACKEN_COMBINEBRACKENOUTPUTS" + + tag "modules" + tag "modules_nfcore" + tag "bracken" + tag "bracken/combinebrackenoutputs" + tag "bracken/bracken" + tag "kraken2/kraken2" + tag "untar" + + setup { + run ("UNTAR") { + script "../../../untar/main.nf" + process { + """ + input[0] = [[],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2_bracken.tar.gz', checkIfExists: true)] + """ + } + } + + run("KRAKEN2_KRAKEN2") { + script "../../../kraken2/kraken2/main.nf" + 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), + [id: 'test2', single_end: 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 + input[3] = false + """ + } + } + + run("BRACKEN_BRACKEN") { + script "../../bracken/main.nf" + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + input[1] = UNTAR.out.untar.map{it[1]} + """ + } + } + + } + + test("sarscov2 - fastq - fastq") { + + setup { + + } + + when { + process { + """ + input[0] = BRACKEN_BRACKEN.out.reports + .map{it[1]} + .collect() + .map{ [ [id: 'db'], it ] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + test("sarscov2 - fastq - stub") { + + options "-stub" + + when { + process { + """ + input[0] = BRACKEN_BRACKEN.out.reports + .map{it[1]} + .collect() + .map{ [ [id: 'db'], it ] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test.snap b/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test.snap new file mode 100644 index 00000000..4687042c --- /dev/null +++ b/modules/nf-core/bracken/combinebrackenoutputs/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "sarscov2 - fastq - fastq": { + "content": [ + { + "0": [ + [ + { + "id": "db" + }, + "db.txt:md5,fb22ad13f9685d5bf5026542b9b2a6b8" + ] + ], + "1": [ + "versions.yml:md5,8edd746a7a248643d2cbf1b7e576fe38" + ], + "txt": [ + [ + { + "id": "db" + }, + "db.txt:md5,fb22ad13f9685d5bf5026542b9b2a6b8" + ] + ], + "versions": [ + "versions.yml:md5,8edd746a7a248643d2cbf1b7e576fe38" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.03.0" + }, + "timestamp": "2024-04-16T15:11:43.6682881" + }, + "sarscov2 - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "db" + }, + "db.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,8edd746a7a248643d2cbf1b7e576fe38" + ], + "txt": [ + [ + { + "id": "db" + }, + "db.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,8edd746a7a248643d2cbf1b7e576fe38" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.03.0" + }, + "timestamp": "2024-04-16T15:11:50.686596" + } +} \ No newline at end of file diff --git a/modules/nf-core/bracken/combinebrackenoutputs/tests/tags.yml b/modules/nf-core/bracken/combinebrackenoutputs/tests/tags.yml new file mode 100644 index 00000000..0564ea40 --- /dev/null +++ b/modules/nf-core/bracken/combinebrackenoutputs/tests/tags.yml @@ -0,0 +1,2 @@ +bracken/combinebrackenoutputs: + - "modules/nf-core/bracken/combinebrackenoutputs/**" diff --git a/modules/nf-core/cat/fastq/environment.yml b/modules/nf-core/cat/fastq/environment.yml new file mode 100644 index 00000000..c7eb9bd1 --- /dev/null +++ b/modules/nf-core/cat/fastq/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=8.30 diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index 5021e6fc..b68e5f91 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -2,7 +2,7 @@ process CAT_FASTQ { tag "$meta.id" label 'process_single' - conda "conda-forge::sed=4.7" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'nf-core/ubuntu:20.04' }" @@ -53,9 +53,9 @@ process CAT_FASTQ { def prefix = task.ext.prefix ?: "${meta.id}" def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] if (meta.single_end) { - if (readList.size > 1) { + if (readList.size >= 1) { """ - touch ${prefix}.merged.fastq.gz + echo '' | gzip > ${prefix}.merged.fastq.gz cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -64,10 +64,10 @@ process CAT_FASTQ { """ } } else { - if (readList.size > 2) { + if (readList.size >= 2) { """ - touch ${prefix}_1.merged.fastq.gz - touch ${prefix}_2.merged.fastq.gz + echo '' | gzip > ${prefix}_1.merged.fastq.gz + echo '' | gzip > ${prefix}_2.merged.fastq.gz cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -76,5 +76,4 @@ process CAT_FASTQ { """ } } - } diff --git a/modules/nf-core/cat/fastq/meta.yml b/modules/nf-core/cat/fastq/meta.yml index 8a39e309..db4ac3c7 100644 --- a/modules/nf-core/cat/fastq/meta.yml +++ b/modules/nf-core/cat/fastq/meta.yml @@ -34,7 +34,9 @@ output: type: file description: File containing software versions pattern: "versions.yml" - 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 00000000..f88a78b6 --- /dev/null +++ b/modules/nf-core/cat/fastq/tests/main.nf.test @@ -0,0 +1,248 @@ +// NOTE The version snaps may not be consistant +// https://github.com/nf-core/modules/pull/4087#issuecomment-1767948035 +nextflow_process { + + name "Test Process CAT_FASTQ" + script "../main.nf" + process "CAT_FASTQ" + tag "modules" + tag "modules_nfcore" + tag "cat" + tag "cat/fastq" + + 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_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() } + ) + } + } +} 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 00000000..aec119a9 --- /dev/null +++ b/modules/nf-core/cat/fastq/tests/main.nf.test.snap @@ -0,0 +1,376 @@ +{ + "test_cat_fastq_single_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-17T17:30:39.816981" + }, + "test_cat_fastq_single_end_same_name": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-17T17:32:35.229332" + }, + "test_cat_fastq_single_end_single_file": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-17T17:34:00.058829" + }, + "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": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-17T17:33:33.031555" + }, + "test_cat_fastq_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T12:07:28.244999" + }, + "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": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T12:07:57.070911" + }, + "test_cat_fastq_single_end_same_name - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T12:07:46.796254" + }, + "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": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-17T17:32:02.270935" + }, + "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": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T12:07:37.807553" + }, + "test_cat_fastq_single_end_single_file - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,d42d6e24d67004608495883e00bd501b" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T12:14:51.861264" + } +} \ No newline at end of file diff --git a/modules/nf-core/cat/fastq/tests/tags.yml b/modules/nf-core/cat/fastq/tests/tags.yml new file mode 100644 index 00000000..6ac43614 --- /dev/null +++ b/modules/nf-core/cat/fastq/tests/tags.yml @@ -0,0 +1,2 @@ +cat/fastq: + - modules/nf-core/cat/fastq/** diff --git a/modules/nf-core/centrifuge/centrifuge/environment.yml b/modules/nf-core/centrifuge/centrifuge/environment.yml index cf34dc0e..42592891 100644 --- a/modules/nf-core/centrifuge/centrifuge/environment.yml +++ b/modules/nf-core/centrifuge/centrifuge/environment.yml @@ -1,7 +1,5 @@ -name: centrifuge_centrifuge channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::centrifuge=1.0.4.1 diff --git a/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test b/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test index d83b522a..f2713608 100644 --- a/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test +++ b/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test @@ -42,10 +42,10 @@ nextflow_process { file(process.out.results[0][1]).name, file(process.out.fastq_mapped[0][1][0]).name, file(process.out.fastq_unmapped[0][1][0]).name, + process.out.versions ).match() } ) } - } test("sarscov2_fastq_pe") { @@ -56,8 +56,8 @@ nextflow_process { input[0] = [ [ id:'test', single_end:false ], // meta map [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ] - ] + file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ] + ] input[1] = UNTAR.out.untar.map{ it[1] } input[2] = true input[3] = true @@ -73,10 +73,10 @@ nextflow_process { file(process.out.results[0][1]).name, file(process.out.fastq_mapped[0][1][0]).name, file(process.out.fastq_unmapped[0][1][0]).name, + process.out.versions ).match() } ) } - } test("sarscov2_fastq_se_stub") { @@ -100,7 +100,5 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test.snap b/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test.snap index f8a2ef7b..a981e517 100644 --- a/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test.snap +++ b/modules/nf-core/centrifuge/centrifuge/tests/main.nf.test.snap @@ -92,34 +92,40 @@ ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-02T07:47:36.886757827" + "timestamp": "2024-07-09T10:36:42.919054" }, "sarscov2_fastq_se": { "content": [ "test.report.txt", "test.results.txt", "", - "" + "", + [ + "versions.yml:md5,1ce028d9f968eca6df31586fe3b77c84" + ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-02T08:22:31.470316024" + "timestamp": "2024-07-09T10:36:23.087465" }, "sarscov2_fastq_pe": { "content": [ "test.report.txt", "test.results.txt", "test.mapped.fastq.1.gz", - "test.unmapped.fastq.1.gz" + "test.unmapped.fastq.1.gz", + [ + "versions.yml:md5,1ce028d9f968eca6df31586fe3b77c84" + ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-02T08:22:48.866073154" + "timestamp": "2024-07-09T10:36:33.471335" } } \ No newline at end of file diff --git a/modules/nf-core/centrifuge/kreport/environment.yml b/modules/nf-core/centrifuge/kreport/environment.yml index 5c8fb451..42592891 100644 --- a/modules/nf-core/centrifuge/kreport/environment.yml +++ b/modules/nf-core/centrifuge/kreport/environment.yml @@ -1,7 +1,5 @@ -name: centrifuge_kreport channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::centrifuge=1.0.4.1 diff --git a/modules/nf-core/centrifuge/kreport/tests/main.nf.test b/modules/nf-core/centrifuge/kreport/tests/main.nf.test index 6347bd7c..6d4bc6b1 100644 --- a/modules/nf-core/centrifuge/kreport/tests/main.nf.test +++ b/modules/nf-core/centrifuge/kreport/tests/main.nf.test @@ -50,8 +50,9 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.kreport[0][1]).name, + process.out.versions ).match() } - ) + ) } } @@ -75,7 +76,5 @@ nextflow_process { { assert snapshot(process.out).match() } ) } - } - } diff --git a/modules/nf-core/centrifuge/kreport/tests/main.nf.test.snap b/modules/nf-core/centrifuge/kreport/tests/main.nf.test.snap index 4e0aaa79..3d638acd 100644 --- a/modules/nf-core/centrifuge/kreport/tests/main.nf.test.snap +++ b/modules/nf-core/centrifuge/kreport/tests/main.nf.test.snap @@ -30,18 +30,21 @@ ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-02T06:18:36.794405448" + "timestamp": "2024-07-09T10:37:05.883784" }, "sarscov2_fastq_se": { "content": [ - "test.txt" + "test.txt", + [ + "versions.yml:md5,43c766a19f2edf7e05d1a2a0b1816b13" + ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-02T06:28:20.461891873" + "timestamp": "2024-07-09T10:36:53.971559" } } \ No newline at end of file diff --git a/modules/nf-core/diamond/blastx/environment.yml b/modules/nf-core/diamond/blastx/environment.yml new file mode 100644 index 00000000..950c3c5c --- /dev/null +++ b/modules/nf-core/diamond/blastx/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::diamond=2.1.8 diff --git a/modules/nf-core/diamond/blastx/main.nf b/modules/nf-core/diamond/blastx/main.nf index e08fb0d9..bf3f623c 100644 --- a/modules/nf-core/diamond/blastx/main.nf +++ b/modules/nf-core/diamond/blastx/main.nf @@ -1,15 +1,15 @@ process DIAMOND_BLASTX { tag "$meta.id" - label 'process_medium' + label 'process_high' - conda "bioconda::diamond=2.0.15" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/diamond:2.0.15--hb97b32f_0' : - 'biocontainers/diamond:2.0.15--hb97b32f_0' }" + 'https://depot.galaxyproject.org/singularity/diamond:2.1.8--h43eeafb_0' : + 'biocontainers/diamond:2.1.8--h43eeafb_0' }" input: - tuple val(meta), path(fasta) - path db + tuple val(meta) , path(fasta) + tuple val(meta2), path(db) val out_ext val blast_columns @@ -21,8 +21,8 @@ process DIAMOND_BLASTX { 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 - path "versions.yml" , emit: versions + tuple val(meta), path("*.log") , emit: log + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -30,6 +30,8 @@ process DIAMOND_BLASTX { 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}" : '' switch ( out_ext ) { case "blast": outfmt = 0; break @@ -46,15 +48,19 @@ process DIAMOND_BLASTX { break } """ + 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 \\ + --threads ${task.cpus} \\ --db \$DB \\ - --query $fasta \\ + --query ${fasta_name} \\ --outfmt ${outfmt} ${columns} \\ - $args \\ + ${args} \\ --out ${prefix}.${out_ext} \\ --log @@ -65,4 +71,32 @@ process DIAMOND_BLASTX { diamond: \$(diamond --version 2>&1 | tail -n 1 | sed 's/^diamond version //') END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + switch ( out_ext ) { + case "blast": outfmt = 0; break + case "xml": outfmt = 5; break + case "txt": outfmt = 6; break + case "daa": outfmt = 100; break + case "sam": outfmt = 101; break + case "tsv": outfmt = 102; break + case "paf": outfmt = 103; break + default: + outfmt = '6'; + out_ext = 'txt'; + log.warn("Unknown output file format provided (${out_ext}): selecting DIAMOND default of tabular BLAST output (txt)"); + break + } + + """ + touch ${prefix}.${out_ext} + touch ${prefix}.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + diamond: \$(diamond --version 2>&1 | tail -n 1 | sed 's/^diamond version //') + END_VERSIONS + """ } diff --git a/modules/nf-core/diamond/blastx/meta.yml b/modules/nf-core/diamond/blastx/meta.yml index a2a6013d..17106548 100644 --- a/modules/nf-core/diamond/blastx/meta.yml +++ b/modules/nf-core/diamond/blastx/meta.yml @@ -13,7 +13,6 @@ tools: tool_dev_url: https://github.com/bbuchfink/diamond doi: "10.1038/s41592-021-01101-x" licence: ["GPL v3.0"] - input: - meta: type: map @@ -23,11 +22,16 @@ input: - fasta: type: file description: Input fasta file containing query sequences - pattern: "*.{fa,fasta}" + pattern: "*.{fa,fasta,fa.gz,fasta.gz}" + - meta2: + type: map + description: | + Groovy Map containing db information + e.g. [ id:'test2', single_end:false ] - db: - type: directory - description: Directory containing the nucelotide blast database - pattern: "*" + type: file + description: File of the indexed DIAMOND database + pattern: "*.dmnd" - out_ext: type: string description: | @@ -36,8 +40,18 @@ input: `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: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - blast: type: file description: File containing blastp hits @@ -66,16 +80,20 @@ output: type: file description: File containing aligned reads in pairwise mapping format format pattern: "*.{paf}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - log: type: file description: Log file containing stdout information pattern: "*.{log}" - + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@spficklin" - "@jfy133" - "@mjamy" +maintainers: + - "@spficklin" + - "@jfy133" + - "@mjamy" + - "@vagkaratzas" 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 00000000..b8757403 --- /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.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.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 00000000..8a128c99 --- /dev/null +++ b/modules/nf-core/diamond/blastx/tests/main.nf.test.snap @@ -0,0 +1,34 @@ +{ + "Should search for transcriptome hits against a DIAMOND db and return the daa format output file of hits": { + "content": [ + [ + "versions.yml:md5,733d944fb173eaf1d1cdf280cd1b3b9c" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-29T14:49:26.843747" + }, + "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.yml:md5,733d944fb173eaf1d1cdf280cd1b3b9c" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-29T14:49:20.769093" + } +} \ No newline at end of file diff --git a/modules/nf-core/diamond/blastx/tests/tags.yml b/modules/nf-core/diamond/blastx/tests/tags.yml new file mode 100644 index 00000000..a0e2964b --- /dev/null +++ b/modules/nf-core/diamond/blastx/tests/tags.yml @@ -0,0 +1,3 @@ +diamond/blastx: + - modules/nf-core/diamond/blastx/** + - modules/nf-core/diamond/makedb/** diff --git a/modules/nf-core/falco/environment.yml b/modules/nf-core/falco/environment.yml index eeedb5b7..c48809cc 100644 --- a/modules/nf-core/falco/environment.yml +++ b/modules/nf-core/falco/environment.yml @@ -1,7 +1,5 @@ -name: falco channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::falco=1.2.1 diff --git a/modules/nf-core/falco/falco.diff b/modules/nf-core/falco/falco.diff deleted file mode 100644 index 4c726b9a..00000000 --- a/modules/nf-core/falco/falco.diff +++ /dev/null @@ -1,16 +0,0 @@ -Changes in module 'nf-core/falco' ---- modules/nf-core/falco/main.nf -+++ modules/nf-core/falco/main.nf -@@ -33,7 +33,9 @@ - """ - } else { - """ -- falco $args --threads $task.cpus ${reads} -+ [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz -+ [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz -+ falco $args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - -************************************************************ diff --git a/modules/nf-core/fastp/environment.yml b/modules/nf-core/fastp/environment.yml new file mode 100644 index 00000000..26d4aca5 --- /dev/null +++ b/modules/nf-core/fastp/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::fastp=0.23.4 diff --git a/modules/nf-core/fastp/main.nf b/modules/nf-core/fastp/main.nf index 831b7f12..e1b9f565 100644 --- a/modules/nf-core/fastp/main.nf +++ b/modules/nf-core/fastp/main.nf @@ -2,7 +2,7 @@ process FASTP { tag "$meta.id" label 'process_medium' - conda "bioconda::fastp=0.23.4" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/fastp:0.23.4--h5f740d0_0' : 'biocontainers/fastp:0.23.4--h5f740d0_0' }" @@ -10,6 +10,7 @@ process FASTP { input: tuple val(meta), path(reads) path adapter_fasta + val discard_trimmed_pass val save_trimmed_fail val save_merged @@ -18,9 +19,9 @@ process FASTP { tuple val(meta), path('*.json') , emit: json tuple val(meta), path('*.html') , emit: html tuple val(meta), path('*.log') , emit: log - path "versions.yml" , emit: versions tuple val(meta), path('*.fail.fastq.gz') , optional:true, emit: reads_fail tuple val(meta), path('*.merged.fastq.gz'), optional:true, emit: reads_merged + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -29,7 +30,9 @@ process FASTP { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def adapter_list = adapter_fasta ? "--adapter_fasta ${adapter_fasta}" : "" - def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.fastq.gz" : '' + def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--failed_out ${prefix}.paired.fail.fastq.gz --unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.fastq.gz" : '' + def out_fq1 = discard_trimmed_pass ?: ( meta.single_end ? "--out1 ${prefix}.fastp.fastq.gz" : "--out1 ${prefix}_1.fastp.fastq.gz" ) + def out_fq2 = discard_trimmed_pass ?: "--out2 ${prefix}_2.fastp.fastq.gz" // Added soft-links to original fastqs for consistent naming in MultiQC // Use single ended for interleaved. Add --interleaved_in in config. if ( task.ext.args?.contains('--interleaved_in') ) { @@ -45,7 +48,7 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> ${prefix}.fastp.log \\ + 2> >(tee ${prefix}.fastp.log >&2) \\ | gzip -c > ${prefix}.fastp.fastq.gz cat <<-END_VERSIONS > versions.yml @@ -59,14 +62,14 @@ process FASTP { fastp \\ --in1 ${prefix}.fastq.gz \\ - --out1 ${prefix}.fastp.fastq.gz \\ + $out_fq1 \\ --thread $task.cpus \\ --json ${prefix}.fastp.json \\ --html ${prefix}.fastp.html \\ $adapter_list \\ $fail_fastq \\ $args \\ - 2> ${prefix}.fastp.log + 2> >(tee ${prefix}.fastp.log >&2) cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -81,8 +84,8 @@ process FASTP { fastp \\ --in1 ${prefix}_1.fastq.gz \\ --in2 ${prefix}_2.fastq.gz \\ - --out1 ${prefix}_1.fastp.fastq.gz \\ - --out2 ${prefix}_2.fastp.fastq.gz \\ + $out_fq1 \\ + $out_fq2 \\ --json ${prefix}.fastp.json \\ --html ${prefix}.fastp.html \\ $adapter_list \\ @@ -91,7 +94,7 @@ process FASTP { --thread $task.cpus \\ --detect_adapter_for_pe \\ $args \\ - 2> ${prefix}.fastp.log + 2> >(tee ${prefix}.fastp.log >&2) cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -99,4 +102,24 @@ process FASTP { END_VERSIONS """ } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def is_single_output = task.ext.args?.contains('--interleaved_in') || meta.single_end + def touch_reads = (discard_trimmed_pass) ? "" : (is_single_output) ? "echo '' | gzip > ${prefix}.fastp.fastq.gz" : "echo '' | gzip > ${prefix}_1.fastp.fastq.gz ; echo '' | gzip > ${prefix}_2.fastp.fastq.gz" + def touch_merged = (!is_single_output && save_merged) ? "echo '' | gzip > ${prefix}.merged.fastq.gz" : "" + def touch_fail_fastq = (!save_trimmed_fail) ? "" : meta.single_end ? "echo '' | gzip > ${prefix}.fail.fastq.gz" : "echo '' | gzip > ${prefix}.paired.fail.fastq.gz ; echo '' | gzip > ${prefix}_1.fail.fastq.gz ; echo '' | gzip > ${prefix}_2.fail.fastq.gz" + """ + $touch_reads + $touch_fail_fastq + $touch_merged + touch "${prefix}.fastp.json" + touch "${prefix}.fastp.html" + touch "${prefix}.fastp.log" + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") + END_VERSIONS + """ } diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml index 197ea7ca..8dfecc18 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -27,13 +27,16 @@ input: type: file description: File in FASTA format containing possible adapters to remove. pattern: "*.{fasta,fna,fas,fa}" + - discard_trimmed_pass: + type: boolean + description: Specify true to not write any reads that pass trimming thresholds. | + This can be used to use fastp for the output report only. - save_trimmed_fail: type: boolean description: Specify true to save files that failed to pass trimming thresholds ending in `*.fail.fastq.gz` - save_merged: type: boolean - description: Specify true to save all merged reads to the a file ending in `*.merged.fastq.gz` - + description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` output: - meta: type: map @@ -71,3 +74,6 @@ output: authors: - "@drpatelh" - "@kevinmenden" +maintainers: + - "@drpatelh" + - "@kevinmenden" diff --git a/modules/nf-core/fastp/tests/main.nf.test b/modules/nf-core/fastp/tests/main.nf.test new file mode 100644 index 00000000..30dbb8aa --- /dev/null +++ b/modules/nf-core/fastp/tests/main.nf.test @@ -0,0 +1,576 @@ +nextflow_process { + + name "Test Process FASTP" + script "../main.nf" + process "FASTP" + tag "modules" + tag "modules_nfcore" + tag "fastp" + + test("test_fastp_single_end") { + + 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("test_fastp_paired_end") { + + when { + + process { + """ + adapter_fasta = [] + save_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("fastp test_fastp_interleaved") { + + config './nextflow.interleaved.config' + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("paired end (151 cycles + 151 cycles)") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 162") }, + { assert process.out.reads_fail == [] }, + { assert process.out.reads_merged == [] }, + { assert snapshot( + process.out.reads, + process.out.json, + process.out.versions).match() } + ) + } + } + + test("test_fastp_single_end_trim_fail") { + + 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] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("test_fastp_paired_end_trim_fail") { + + config './nextflow.save_failed.config' + 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] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 162") }, + { assert snapshot( + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.json, + process.out.versions).match() } + ) + } + } + + test("test_fastp_paired_end_merged") { + + 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] = [] + input[2] = false + input[3] = false + input[4] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("total reads: 75") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.versions).match() }, + ) + } + } + + test("test_fastp_paired_end_merged_adapterlist") { + + 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] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) + input[2] = false + input[3] = false + input[4] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("
") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("total bases: 13683") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("test_fastp_single_end_qc_only") { + + 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) ] + ]) + input[1] = [] + input[2] = true + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads, + process.out.reads_fail, + process.out.reads_fail, + process.out.reads_merged, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("test_fastp_paired_end_qc_only") { + + 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] = [] + input[2] = true + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, + { assert snapshot( + process.out.json, + process.out.reads, + process.out.reads, + process.out.reads_fail, + process.out.reads_fail, + process.out.reads_merged, + process.out.reads_merged, + process.out.versions).match() } + ) + } + } + + test("test_fastp_single_end - 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end - stub") { + + options "-stub" + + when { + + process { + """ + adapter_fasta = [] + save_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("fastp - stub test_fastp_interleaved") { + + options "-stub" + + config './nextflow.interleaved.config' + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_single_end_trim_fail - 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_trim_fail - stub") { + + options "-stub" + + config './nextflow.save_failed.config' + 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] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_merged - 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] = [] + input[2] = false + input[3] = false + input[4] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_merged_adapterlist - 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] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) + input[2] = false + input[3] = false + input[4] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_single_end_qc_only - 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) ] + ]) + input[1] = [] + input[2] = true + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_qc_only - 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] = [] + input[2] = true + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/fastp/tests/main.nf.test.snap b/modules/nf-core/fastp/tests/main.nf.test.snap new file mode 100644 index 00000000..54be7e45 --- /dev/null +++ b/modules/nf-core/fastp/tests/main.nf.test.snap @@ -0,0 +1,1331 @@ +{ + "test_fastp_single_end_qc_only - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T14:31:10.841098" + }, + "test_fastp_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,1e0f8e27e71728e2b63fc64086be95cd" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:43:28.665779" + }, + "test_fastp_paired_end_merged_adapterlist": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,5914ca3f21ce162123a824e33e8564f6" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:44:18.210375" + }, + "test_fastp_single_end_qc_only": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,5cc5f01e449309e0e689ed6f51a2294a" + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:44:27.380974" + }, + "test_fastp_paired_end_trim_fail": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", + "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366", + "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", + "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,4c3268ddb50ea5b33125984776aa3519" + ] + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:43:58.749589" + }, + "fastp - stub test_fastp_interleaved": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:50:00.270029" + }, + "test_fastp_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:49:42.502789" + }, + "test_fastp_paired_end_merged_adapterlist - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:54:53.458252" + }, + "test_fastp_paired_end_merged - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:50:27.689379" + }, + "test_fastp_paired_end_merged": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,b712fd68ed0322f4bec49ff2a5237fcc" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:44:08.68476" + }, + "test_fastp_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:49:51.679221" + }, + "test_fastp_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,c852d7a6dba5819e4ac8d9673bedcacc" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7" + ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:43:18.834322" + }, + "test_fastp_single_end_trim_fail - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T14:05:36.898142" + }, + "test_fastp_paired_end_trim_fail - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T14:05:49.212847" + }, + "fastp test_fastp_interleaved": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,217d62dc13a23e92513a1bd8e1bcea39" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,b24e0624df5cc0b11cd5ba21b726fb22" + ] + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:43:38.910832" + }, + "test_fastp_single_end_trim_fail": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,9a7ee180f000e8d00c7fb67f06293eb5" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd" + ] + ], + [ + + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:43:48.22378" + }, + "test_fastp_paired_end_qc_only": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,623064a45912dac6f2b64e3f2e9901df" + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T13:44:36.334938" + }, + "test_fastp_paired_end_qc_only - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-05T14:31:27.096468" + } +} \ No newline at end of file diff --git a/modules/nf-core/fastp/tests/nextflow.interleaved.config b/modules/nf-core/fastp/tests/nextflow.interleaved.config new file mode 100644 index 00000000..4be8dbd2 --- /dev/null +++ b/modules/nf-core/fastp/tests/nextflow.interleaved.config @@ -0,0 +1,5 @@ +process { + withName: FASTP { + ext.args = "--interleaved_in -e 30" + } +} diff --git a/modules/nf-core/fastp/tests/nextflow.save_failed.config b/modules/nf-core/fastp/tests/nextflow.save_failed.config new file mode 100644 index 00000000..53b61b0c --- /dev/null +++ b/modules/nf-core/fastp/tests/nextflow.save_failed.config @@ -0,0 +1,5 @@ +process { + withName: FASTP { + ext.args = "-e 30" + } +} diff --git a/modules/nf-core/fastp/tests/tags.yml b/modules/nf-core/fastp/tests/tags.yml new file mode 100644 index 00000000..c1afcce7 --- /dev/null +++ b/modules/nf-core/fastp/tests/tags.yml @@ -0,0 +1,2 @@ +fastp: + - modules/nf-core/fastp/** diff --git a/modules/nf-core/fastqc/environment.yml b/modules/nf-core/fastqc/environment.yml index 1787b38a..691d4c76 100644 --- a/modules/nf-core/fastqc/environment.yml +++ b/modules/nf-core/fastqc/environment.yml @@ -1,7 +1,5 @@ -name: fastqc channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::fastqc=0.12.1 diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index d79f1c86..d8989f48 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -26,7 +26,10 @@ process FASTQC { def rename_to = old_new_pairs*.join(' ').join(' ') def renamed_files = old_new_pairs.collect{ old_name, new_name -> new_name }.join(' ') - def memory_in_mb = MemoryUnit.of("${task.memory}").toUnit('MB') + // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) + // https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 + // Dividing the task.memory by task.cpu allows to stick to requested amount of RAM in the label + def memory_in_mb = MemoryUnit.of("${task.memory}").toUnit('MB') / task.cpus // FastQC memory value allowed range (100 - 10000) def fastqc_memory = memory_in_mb > 10000 ? 10000 : (memory_in_mb < 100 ? 100 : memory_in_mb) diff --git a/modules/nf-core/fastqc/tests/main.nf.test b/modules/nf-core/fastqc/tests/main.nf.test index 83586e4a..e9d79a07 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test +++ b/modules/nf-core/fastqc/tests/main.nf.test @@ -23,17 +23,14 @@ nextflow_process { 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(process.out.versions).match("fastqc_versions_single") } + { 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(process.out.versions).match() } ) } } @@ -54,16 +51,14 @@ nextflow_process { 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(process.out.versions).match("fastqc_versions_paired") } + { 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(process.out.versions).match() } ) } } @@ -83,13 +78,11 @@ nextflow_process { 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(process.out.versions).match("fastqc_versions_interleaved") } + { 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(process.out.versions).match() } ) } } @@ -98,36 +91,70 @@ nextflow_process { when { process { - """ - input[0] = [ - [id: 'test', single_end: false], // meta map - file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) - ] - """ + """ + 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.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(process.out.versions).match() } + ) + } + } - { 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") }, + 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) ] + ]) + """ + } + } - { assert snapshot(process.out.versions).match("versions") } + 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(process.out.versions).match() } ) } } - test("sarscov2 paired-end [bam]") { + test("sarscov2 custom_prefix") { 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) + [ id:'mysample', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]) """ } @@ -135,28 +162,47 @@ nextflow_process { then { assertAll ( - { assert process.success }, + { 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(process.out.versions).match() } + ) + } + } + + test("sarscov2 single-end [fastq] - stub") { - { 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") }, + 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) ] + ]) + """ + } + } - { assert snapshot(process.out.versions).match("fastqc_versions_bam") } + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } - test("sarscov2 multiple [fastq]") { + 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), - 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) ] + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] ]) """ } @@ -164,62 +210,68 @@ nextflow_process { 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(process.out.versions).match("fastqc_versions_multiple") } + { assert process.success }, + { assert snapshot(process.out).match() } ) } } - test("sarscov2 custom_prefix") { + test("sarscov2 interleaved [fastq] - 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) + [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.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 paired-end [bam] - stub") { - { 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") }, + 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) + ]) + """ + } + } - { assert snapshot(process.out.versions).match("fastqc_versions_custom_prefix") } + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } - test("sarscov2 single-end [fastq] - stub") { - - options "-stub" + test("sarscov2 multiple [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) ] + [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) ] ]) """ } @@ -227,12 +279,31 @@ nextflow_process { then { assertAll ( - { assert process.success }, - { assert snapshot(process.out.html.collect { file(it[1]).getName() } + - process.out.zip.collect { file(it[1]).getName() } + - process.out.versions ).match("fastqc_stub") } + { 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 index 86f7c311..d5db3092 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test.snap +++ b/modules/nf-core/fastqc/tests/main.nf.test.snap @@ -1,88 +1,392 @@ { - "fastqc_versions_interleaved": { + "sarscov2 custom_prefix": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:07.293713" + "timestamp": "2024-07-22T11:02:16.374038" }, - "fastqc_stub": { + "sarscov2 single-end [fastq] - stub": { "content": [ - [ - "test.html", - "test.zip", - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:24.993809" + }, + "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": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:31:01.425198" + "timestamp": "2024-07-22T11:03:10.93942" }, - "fastqc_versions_multiple": { + "sarscov2 interleaved [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:55.797907" + "timestamp": "2024-07-22T11:01:42.355718" }, - "fastqc_versions_bam": { + "sarscov2 paired-end [bam]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:26.795862" + "timestamp": "2024-07-22T11:01:53.276274" }, - "fastqc_versions_single": { + "sarscov2 multiple [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:27.043675" + "timestamp": "2024-07-22T11:02:05.527626" }, - "fastqc_versions_paired": { + "sarscov2 paired-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:31.188871" + }, + "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": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:34.273566" + }, + "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": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:47.584191" + "timestamp": "2024-07-22T11:03:02.304411" }, - "fastqc_versions_custom_prefix": { + "sarscov2 single-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:19.095607" + }, + "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": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:44.640184" + }, + "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": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:41:14.576531" + "timestamp": "2024-07-22T11:02:53.550742" } } \ No newline at end of file diff --git a/modules/nf-core/filtlong/environment.yml b/modules/nf-core/filtlong/environment.yml index 0fb7e8b4..746c83a4 100644 --- a/modules/nf-core/filtlong/environment.yml +++ b/modules/nf-core/filtlong/environment.yml @@ -1,7 +1,5 @@ -name: filtlong channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::filtlong=0.2.1 diff --git a/modules/nf-core/filtlong/tests/main.nf.test b/modules/nf-core/filtlong/tests/main.nf.test index b7d73e79..d54ce39c 100644 --- a/modules/nf-core/filtlong/tests/main.nf.test +++ b/modules/nf-core/filtlong/tests/main.nf.test @@ -17,10 +17,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - [], - [ file(params.test_data['sarscov2']['nanopore']['test_fastq_gz'], checkIfExists: true) ] - ] + [ id:'test', single_end:false ], // meta map + [], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) ] + ] """ } } @@ -29,8 +29,11 @@ nextflow_process { assertAll( { assert process.success }, { assert path(process.out.log.get(0).get(1)).readLines().contains("Scoring long reads")}, - { assert snapshot(process.out.reads).match("nanopore") }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot( + process.out.reads, + process.out.versions + ).match() + } ) } @@ -46,10 +49,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ], - [ file(params.test_data['sarscov2']['nanopore']['test_fastq_gz'], checkIfExists: true) ] - ] + [ 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/nanopore/fastq/test.fastq.gz', checkIfExists: true) ] + ] """ } } @@ -58,8 +61,11 @@ nextflow_process { assertAll( { assert process.success }, { assert path(process.out.log.get(0).get(1)).readLines().contains("Scoring long reads")}, - { assert snapshot(process.out.reads).match("nanopore_illumina_se") }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot( + process.out.reads, + process.out.versions + ).match() + } ) } @@ -75,11 +81,13 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ], - [ file(params.test_data['sarscov2']['nanopore']['test_fastq_gz'], checkIfExists: true) ] - ] + [ 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/nanopore/fastq/test.fastq.gz', checkIfExists: true) ] + ] """ } } @@ -88,12 +96,13 @@ nextflow_process { assertAll( { assert process.success }, { assert path(process.out.log.get(0).get(1)).readLines().contains("Scoring long reads")}, - { assert snapshot(process.out.reads).match("nanopore_illumina_pe") }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot( + process.out.reads, + process.out.versions + ).match() + } ) } } - - } diff --git a/modules/nf-core/filtlong/tests/main.nf.test.snap b/modules/nf-core/filtlong/tests/main.nf.test.snap index 49d4bb6c..1a25c3fc 100644 --- a/modules/nf-core/filtlong/tests/main.nf.test.snap +++ b/modules/nf-core/filtlong/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "nanopore": { + "sarscov2 nanopore [fastq]": { "content": [ [ [ @@ -9,19 +9,18 @@ }, "test_lr.fastq.gz:md5,7567d853ada6ac142332619d0b541d76" ] - ] - ], - "timestamp": "2023-12-11T14:23:36.351509" - }, - "versions": { - "content": [ + ], [ "versions.yml:md5,af5988f30157282acdb0ac50ebb4c8cc" ] ], - "timestamp": "2023-12-11T14:23:36.372189" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-08-06T10:51:29.197603" }, - "nanopore_illumina_pe": { + "sarscov2 nanopore [fastq] + Illumina paired-end [fastq]": { "content": [ [ [ @@ -31,11 +30,18 @@ }, "test_lr.fastq.gz:md5,7567d853ada6ac142332619d0b541d76" ] + ], + [ + "versions.yml:md5,af5988f30157282acdb0ac50ebb4c8cc" ] ], - "timestamp": "2023-12-11T14:24:05.202047" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-08-06T10:51:39.68464" }, - "nanopore_illumina_se": { + "sarscov2 nanopore [fastq] + Illumina single-end [fastq]": { "content": [ [ [ @@ -45,8 +51,15 @@ }, "test_lr.fastq.gz:md5,7567d853ada6ac142332619d0b541d76" ] + ], + [ + "versions.yml:md5,af5988f30157282acdb0ac50ebb4c8cc" ] ], - "timestamp": "2023-12-11T14:23:50.607338" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-08-06T10:51:34.404022" } } \ No newline at end of file diff --git a/modules/nf-core/filtlong/tests/nextflow.config b/modules/nf-core/filtlong/tests/nextflow.config index 5e4c9fbb..d366b4c3 100644 --- a/modules/nf-core/filtlong/tests/nextflow.config +++ b/modules/nf-core/filtlong/tests/nextflow.config @@ -1,8 +1,4 @@ process { - - publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - ext.args = "--min_length 10" ext.prefix = "test_lr" - } diff --git a/modules/nf-core/filtlong/tests/tags.yml b/modules/nf-core/filtlong/tests/tags.yml deleted file mode 100644 index bf2cff9d..00000000 --- a/modules/nf-core/filtlong/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -filtlong: - - modules/nf-core/filtlong/** diff --git a/modules/nf-core/ganon/classify/environment.yml b/modules/nf-core/ganon/classify/environment.yml new file mode 100644 index 00000000..98f34de8 --- /dev/null +++ b/modules/nf-core/ganon/classify/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::ganon=2.0.0 diff --git a/modules/nf-core/ganon/classify/main.nf b/modules/nf-core/ganon/classify/main.nf index d4130a01..d6db825e 100644 --- a/modules/nf-core/ganon/classify/main.nf +++ b/modules/nf-core/ganon/classify/main.nf @@ -2,10 +2,10 @@ process GANON_CLASSIFY { tag "$meta.id" label 'process_high' - conda "bioconda::ganon=1.5.1" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ganon:1.5.1--py310h8abeb55_0': - 'biocontainers/ganon:1.5.1--py310h8abeb55_0' }" + 'https://depot.galaxyproject.org/singularity/ganon:2.0.0--py39ha35b9be_0': + 'biocontainers/ganon:2.0.0--py39ha35b9be_0' }" input: tuple val(meta) , path(fastqs) @@ -14,7 +14,7 @@ process GANON_CLASSIFY { output: tuple val(meta), path("*.tre"), emit: tre tuple val(meta), path("*.rep"), emit: report - tuple val(meta), path("*.lca"), emit: lca , optional: true + tuple val(meta), path("*.one"), emit: one , optional: true tuple val(meta), path("*.all"), emit: all , optional: true tuple val(meta), path("*.unc"), emit: unc , optional: true tuple val(meta), path("*.log"), emit: log @@ -28,11 +28,11 @@ process GANON_CLASSIFY { def prefix = task.ext.prefix ?: "${meta.id}" def input = meta.single_end ? "--single-reads ${fastqs}" : "--paired-reads ${fastqs}" """ - dbprefix=\$(find -L . -name '*.ibf' | sed 's/\\.ibf\$//') + dbprefix=\$(find -L . -name '*.*ibf' | sed 's/\\.h\\?ibf\$//') ganon \\ classify \\ - --db-prefix \${dbprefix%%.ibf} \\ + --db-prefix \${dbprefix%%.*ibf} \\ $args \\ --threads $task.cpus \\ --output-prefix ${prefix} \\ @@ -51,10 +51,11 @@ process GANON_CLASSIFY { def input = meta.single_end ? "--single-reads ${fastqs}" : "--paired-reads ${fastqs}" """ touch ${prefix}.tre - touch ${prefix}.report - touch ${prefix}.lca + touch ${prefix}.rep + touch ${prefix}.one touch ${prefix}.all touch ${prefix}.unc + touch ${prefix}.log cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/ganon/classify/meta.yml b/modules/nf-core/ganon/classify/meta.yml index 692d4e56..55a8eae6 100644 --- a/modules/nf-core/ganon/classify/meta.yml +++ b/modules/nf-core/ganon/classify/meta.yml @@ -15,8 +15,7 @@ tools: documentation: "https://github.com/pirovc/ganon" tool_dev_url: "https://github.com/pirovc/ganon" doi: "10.1093/bioinformatics/btaa458" - licence: "['MIT License']" - + licence: ["MIT"] input: - meta: type: map @@ -27,11 +26,10 @@ input: type: file description: Single or paired FASTQ files, optionally gzipped pattern: "*.{fq,fq.gz,fastq,fastq.gz}" - - dbs: + - db: type: file description: Ganon database files from build or build-custom pattern: "*.{ibf,tax}" - output: - meta: type: map @@ -50,10 +48,10 @@ output: type: file description: Plain ganon report file with only targets with match pattern: "*.rep" - - lca: + - one: type: file - description: Information about the lowest common ancestor match of a given read - pattern: "*.lca" + description: Information about a single (best) match of a given read after EM or LCA algorithms + pattern: "*.one" - all: type: file description: Information of all matches to a given read @@ -66,6 +64,7 @@ output: type: file description: Text file containing console output from ganon classify pattern: "*.log" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/ganon/classify/tests/main.nf.test b/modules/nf-core/ganon/classify/tests/main.nf.test new file mode 100644 index 00000000..e581ca06 --- /dev/null +++ b/modules/nf-core/ganon/classify/tests/main.nf.test @@ -0,0 +1,112 @@ +nextflow_process { + + name "Test Process GANON_CLASSIFY" + script "../main.nf" + process "GANON_CLASSIFY" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "ganon" + tag "ganon/buildcustom" + tag "ganon/classify" + + setup { + run("GANON_BUILDCUSTOM") { + script "../../buildcustom/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true), + ] + input[1] = [] + input[2] = [] + """ + } + } + } + + test("sarscov2 single-end [fastq]") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + [ + file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), + ] + ] + input[1] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.tre, + process.out.report).match()}, + { assert file(process.out.log[0][1]).text.contains("Total elapsed time:") } + ) + } + + } + + test("sarscov2 paired-end [fastq]") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), + file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) + ] + ] + input[1] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.tre, + process.out.report).match()}, + { assert file(process.out.log[0][1]).text.contains("Total elapsed time:") } + ) + } + + } + + test("sarscov2 - fastq - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + [ + file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), + ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/ganon/classify/tests/main.nf.test.snap b/modules/nf-core/ganon/classify/tests/main.nf.test.snap new file mode 100644 index 00000000..40b36b14 --- /dev/null +++ b/modules/nf-core/ganon/classify/tests/main.nf.test.snap @@ -0,0 +1,169 @@ +{ + "sarscov2 - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.rep:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.one:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.all:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.unc:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": true + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + "versions.yml:md5,e13af9e126ff4a9ea7ee4b706fbbc0bb" + ], + "all": [ + [ + { + "id": "test", + "single_end": true + }, + "test.all:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "one": [ + [ + { + "id": "test", + "single_end": true + }, + "test.one:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report": [ + [ + { + "id": "test", + "single_end": true + }, + "test.rep:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tre": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "unc": [ + [ + { + "id": "test", + "single_end": true + }, + "test.unc:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e13af9e126ff4a9ea7ee4b706fbbc0bb" + ] + } + ], + "timestamp": "2024-01-06T15:08:06.626813557" + }, + "sarscov2 paired-end [fastq]": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.tre:md5,66c0b9ed247989682fe3bae842d37a76" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.rep:md5,757e5cbf7a978913277401285d743336" + ] + ] + ], + "timestamp": "2024-01-06T15:07:49.528458193" + }, + "sarscov2 single-end [fastq]": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,3d2ef6fe0571d7aa7324539407a59630" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.rep:md5,9b5f8051aa459a80a678e36259a15746" + ] + ] + ], + "timestamp": "2024-01-06T15:07:12.092925016" + } +} \ No newline at end of file diff --git a/modules/nf-core/ganon/classify/tests/nextflow.config b/modules/nf-core/ganon/classify/tests/nextflow.config new file mode 100644 index 00000000..18712875 --- /dev/null +++ b/modules/nf-core/ganon/classify/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: GANON_CLASSIFY { + ext.args = "--output-one --output-all --output-unclassified" + } + +} diff --git a/modules/nf-core/ganon/classify/tests/tags.yml b/modules/nf-core/ganon/classify/tests/tags.yml new file mode 100644 index 00000000..60ebeeea --- /dev/null +++ b/modules/nf-core/ganon/classify/tests/tags.yml @@ -0,0 +1,2 @@ +ganon/classify: + - "modules/nf-core/ganon/classify/**" diff --git a/modules/nf-core/ganon/report/environment.yml b/modules/nf-core/ganon/report/environment.yml new file mode 100644 index 00000000..98f34de8 --- /dev/null +++ b/modules/nf-core/ganon/report/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::ganon=2.0.0 diff --git a/modules/nf-core/ganon/report/main.nf b/modules/nf-core/ganon/report/main.nf index bd0a2207..2b1998f1 100644 --- a/modules/nf-core/ganon/report/main.nf +++ b/modules/nf-core/ganon/report/main.nf @@ -2,10 +2,10 @@ process GANON_REPORT { tag "$meta.id" label 'process_single' - conda "bioconda::ganon=1.5.1" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ganon:1.5.1--py310h8abeb55_0': - 'biocontainers/ganon:1.5.1--py310h8abeb55_0' }" + 'https://depot.galaxyproject.org/singularity/ganon:2.0.0--py39ha35b9be_0': + 'biocontainers/ganon:2.0.0--py39ha35b9be_0' }" input: tuple val(meta), path(rep) @@ -23,13 +23,13 @@ process GANON_REPORT { def prefix = task.ext.prefix ?: "${meta.id}" """ - dbprefix=\$(find -L . -name '*.ibf' | sed 's/\\.ibf\$//') + dbprefix=\$(find -L . -name '*.*ibf' | sed 's/\\.h\\?ibf\$//') ganon \\ report \\ --input ${rep} \\ --output-prefix ${prefix} \\ - --db-prefix \${dbprefix%%.ibf} \\ + --db-prefix \${dbprefix%%.*ibf} \\ $args cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/ganon/report/meta.yml b/modules/nf-core/ganon/report/meta.yml index c7852c8a..c820e9c4 100644 --- a/modules/nf-core/ganon/report/meta.yml +++ b/modules/nf-core/ganon/report/meta.yml @@ -17,8 +17,7 @@ tools: documentation: "https://github.com/pirovc/ganon" tool_dev_url: "https://github.com/pirovc/ganon" doi: "10.1093/bioinformatics/btaa458" - licence: "['MIT License']" - + licence: ["MIT"] input: - meta: type: map @@ -29,11 +28,10 @@ input: type: file description: Input 'repo' files from ganon classify pattern: "*.rep" - - dbs: + - db: type: file description: Ganon database files from build or build-custom pattern: "*.{ibf,tax}" - output: - meta: type: map @@ -48,6 +46,7 @@ output: type: file description: Output ganon report containing taxonomic profile information. Formatting of contents depends on --output-format. pattern: "*.tre" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/ganon/report/tests/main.nf.test b/modules/nf-core/ganon/report/tests/main.nf.test new file mode 100644 index 00000000..d350eed0 --- /dev/null +++ b/modules/nf-core/ganon/report/tests/main.nf.test @@ -0,0 +1,87 @@ +nextflow_process { + + name "Test Process GANON_REPORT" + script "../main.nf" + process "GANON_REPORT" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "ganon" + tag "ganon/buildcustom" + tag "ganon/classify" + tag "ganon/report" + + setup { + run("GANON_BUILDCUSTOM") { + script "../../buildcustom/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[1] = [] + input[2] = [] + """ + } + } + run("GANON_CLASSIFY") { + script "../../classify/main.nf" + process { + """ + input[0] = [ + [ 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] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + } + + test("sarscov2 single-end [fastq]") { + + when { + process { + """ + input[0] = GANON_CLASSIFY.out.report + input[1] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 single-end [fastq] stub") { + + options "-stub" + + when { + process { + """ + input[0] = GANON_CLASSIFY.out.report + input[1] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/ganon/report/tests/main.nf.test.snap b/modules/nf-core/ganon/report/tests/main.nf.test.snap new file mode 100644 index 00000000..abad8035 --- /dev/null +++ b/modules/nf-core/ganon/report/tests/main.nf.test.snap @@ -0,0 +1,64 @@ +{ + "sarscov2 single-end [fastq] stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,7219068902254fbc97f84e8e163213d0" + ], + "tre": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,7219068902254fbc97f84e8e163213d0" + ] + } + ], + "timestamp": "2024-01-06T18:50:07.439069779" + }, + "sarscov2 single-end [fastq]": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,3d2ef6fe0571d7aa7324539407a59630" + ] + ], + "1": [ + "versions.yml:md5,7219068902254fbc97f84e8e163213d0" + ], + "tre": [ + [ + { + "id": "test", + "single_end": true + }, + "test.tre:md5,3d2ef6fe0571d7aa7324539407a59630" + ] + ], + "versions": [ + "versions.yml:md5,7219068902254fbc97f84e8e163213d0" + ] + } + ], + "timestamp": "2024-01-06T18:49:52.505817066" + } +} \ No newline at end of file diff --git a/modules/nf-core/ganon/report/tests/nextflow.config b/modules/nf-core/ganon/report/tests/nextflow.config new file mode 100644 index 00000000..e6dd3131 --- /dev/null +++ b/modules/nf-core/ganon/report/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + withName: GANON_CLASSIFY { + ext.args = "--output-one --output-all --output-unclassified" + } + withName: GANON_REPORT { + ext.args = "--report-type reads --output-format tsv" + } +} diff --git a/modules/nf-core/ganon/report/tests/tags.yml b/modules/nf-core/ganon/report/tests/tags.yml new file mode 100644 index 00000000..c991c0ea --- /dev/null +++ b/modules/nf-core/ganon/report/tests/tags.yml @@ -0,0 +1,2 @@ +ganon/report: + - "modules/nf-core/ganon/report/**" diff --git a/modules/nf-core/ganon/table/environment.yml b/modules/nf-core/ganon/table/environment.yml new file mode 100644 index 00000000..98f34de8 --- /dev/null +++ b/modules/nf-core/ganon/table/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::ganon=2.0.0 diff --git a/modules/nf-core/ganon/table/main.nf b/modules/nf-core/ganon/table/main.nf index 5adaa65c..d8f247c1 100644 --- a/modules/nf-core/ganon/table/main.nf +++ b/modules/nf-core/ganon/table/main.nf @@ -2,10 +2,10 @@ process GANON_TABLE { tag "$meta.id" label 'process_single' - conda "bioconda::ganon=1.5.1" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ganon:1.5.1--py310h8abeb55_0': - 'biocontainers/ganon:1.5.1--py310h8abeb55_0' }" + 'https://depot.galaxyproject.org/singularity/ganon:2.0.0--py39ha35b9be_0': + 'biocontainers/ganon:2.0.0--py39ha35b9be_0' }" input: tuple val(meta), path(tre) diff --git a/modules/nf-core/ganon/table/meta.yml b/modules/nf-core/ganon/table/meta.yml index 4fa19b74..bf15f083 100644 --- a/modules/nf-core/ganon/table/meta.yml +++ b/modules/nf-core/ganon/table/meta.yml @@ -18,8 +18,7 @@ tools: documentation: "https://github.com/pirovc/ganon" tool_dev_url: "https://github.com/pirovc/ganon" doi: "10.1093/bioinformatics/btaa458" - licence: "['MIT License']" - + licence: ["MIT"] input: - meta: type: map @@ -30,7 +29,6 @@ input: type: file description: A list of 'tre' files from ganon report pattern: "*.tre" - output: - meta: type: map @@ -45,6 +43,7 @@ output: type: file description: Output ganon table containing taxonomic profile information of multiple samples. Formatting of contents depends on --output-format. pattern: "*.txt" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/ganon/table/tests/main.nf.test b/modules/nf-core/ganon/table/tests/main.nf.test new file mode 100644 index 00000000..43b6cf0a --- /dev/null +++ b/modules/nf-core/ganon/table/tests/main.nf.test @@ -0,0 +1,95 @@ +nextflow_process { + + name "Test Process GANON_TABLE" + script "../main.nf" + process "GANON_TABLE" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "ganon" + tag "ganon/buildcustom" + tag "ganon/classify" + tag "ganon/report" + tag "ganon/table" + + setup { + run("GANON_BUILDCUSTOM") { + script "../../buildcustom/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[1] = [] + input[2] = [] + """ + } + } + run("GANON_CLASSIFY") { + script "../../classify/main.nf" + process { + """ + input[0] = [ + [ 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] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + run("GANON_REPORT") { + script "../../report/main.nf" + process { + """ + input[0] = GANON_CLASSIFY.out.report + input[1] = GANON_BUILDCUSTOM.out.db.map{it[1]} + """ + } + } + } + + test("sarscov2 single-end [fastq]") { + + when { + process { + """ + input[0] = GANON_REPORT.out.tre.collect{it[1]}.map{[[id: "db1"], it]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 single-end [fastq] stub") { + + options "-stub" + + when { + process { + """ + input[0] = GANON_REPORT.out.tre.collect{it[1]}.map{[[id: "db1"], it]} + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/ganon/table/tests/main.nf.test.snap b/modules/nf-core/ganon/table/tests/main.nf.test.snap new file mode 100644 index 00000000..2c5c312d --- /dev/null +++ b/modules/nf-core/ganon/table/tests/main.nf.test.snap @@ -0,0 +1,60 @@ +{ + "sarscov2 single-end [fastq] stub": { + "content": [ + { + "0": [ + [ + { + "id": "db1" + }, + "db1.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,1cec68ee4a3dcc057d475497732b72c1" + ], + "txt": [ + [ + { + "id": "db1" + }, + "db1.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,1cec68ee4a3dcc057d475497732b72c1" + ] + } + ], + "timestamp": "2024-01-07T14:27:58.631022945" + }, + "sarscov2 single-end [fastq]": { + "content": [ + { + "0": [ + [ + { + "id": "db1" + }, + "db1.txt:md5,c2f38e9f47f8701d8f37a59dffed88a3" + ] + ], + "1": [ + "versions.yml:md5,1cec68ee4a3dcc057d475497732b72c1" + ], + "txt": [ + [ + { + "id": "db1" + }, + "db1.txt:md5,c2f38e9f47f8701d8f37a59dffed88a3" + ] + ], + "versions": [ + "versions.yml:md5,1cec68ee4a3dcc057d475497732b72c1" + ] + } + ], + "timestamp": "2024-01-07T14:27:37.318272937" + } +} \ No newline at end of file diff --git a/modules/nf-core/ganon/table/tests/nextflow.config b/modules/nf-core/ganon/table/tests/nextflow.config new file mode 100644 index 00000000..26114b4c --- /dev/null +++ b/modules/nf-core/ganon/table/tests/nextflow.config @@ -0,0 +1,12 @@ +process { + withName: GANON_CLASSIFY { + ext.args = "--output-one --output-all --output-unclassified" + } + withName: GANON_REPORT { + ext.args = "--report-type reads --output-format tsv" + } + + withName: GANON_TABLE { + ext.args = "--output-format tsv --output-value percentages" + } +} diff --git a/modules/nf-core/ganon/table/tests/tags.yml b/modules/nf-core/ganon/table/tests/tags.yml new file mode 100644 index 00000000..aa88380d --- /dev/null +++ b/modules/nf-core/ganon/table/tests/tags.yml @@ -0,0 +1,2 @@ +ganon/table: + - "modules/nf-core/ganon/table/**" diff --git a/modules/nf-core/gunzip/environment.yml b/modules/nf-core/gunzip/environment.yml new file mode 100644 index 00000000..c7794856 --- /dev/null +++ b/modules/nf-core/gunzip/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::grep=3.11 + - 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 index 73bf08cd..5e67e3b9 100644 --- a/modules/nf-core/gunzip/main.nf +++ b/modules/nf-core/gunzip/main.nf @@ -2,10 +2,10 @@ process GUNZIP { tag "$archive" label 'process_single' - conda "conda-forge::sed=4.7" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'nf-core/ubuntu:20.04' }" + 'https://depot.galaxyproject.org/singularity/ubuntu:22.04' : + 'nf-core/ubuntu:22.04' }" input: tuple val(meta), path(archive) @@ -18,8 +18,11 @@ process GUNZIP { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - gunzip = archive.toString() - '.gz' + def args = task.ext.args ?: '' + def extension = ( archive.toString() - '.gz' ).tokenize('.')[-1] + def name = archive.toString() - '.gz' - ".$extension" + 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 @@ -37,7 +40,11 @@ process GUNZIP { """ stub: - gunzip = archive.toString() - '.gz' + def args = task.ext.args ?: '' + def extension = ( archive.toString() - '.gz' ).tokenize('.')[-1] + def name = archive.toString() - '.gz' - ".$extension" + def prefix = task.ext.prefix ?: name + gunzip = prefix + ".$extension" """ touch $gunzip cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/gunzip/meta.yml b/modules/nf-core/gunzip/meta.yml index 4cdcdf4c..f32973a0 100644 --- a/modules/nf-core/gunzip/meta.yml +++ b/modules/nf-core/gunzip/meta.yml @@ -33,3 +33,8 @@ 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 00000000..776211ad --- /dev/null +++ b/modules/nf-core/gunzip/tests/main.nf.test @@ -0,0 +1,121 @@ +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 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 00000000..069967e7 --- /dev/null +++ b/modules/nf-core/gunzip/tests/main.nf.test.snap @@ -0,0 +1,134 @@ +{ + "Should run without failures - prefix - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ], + "gunzip": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-25T11:35:10.861293" + }, + "Should run without failures - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + "test_1.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ], + "gunzip": [ + [ + [ + + ], + "test_1.fastq:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-25T11:35:05.857145" + }, + "Should run without failures": { + "content": [ + { + "0": [ + [ + [ + + ], + "test_1.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ], + "gunzip": [ + [ + [ + + ], + "test_1.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2023-10-17T15:35:37.690477896" + }, + "Should run without failures - prefix": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ], + "gunzip": [ + [ + { + "id": "test" + }, + "test.xyz.fastq:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions": [ + "versions.yml:md5,54376d32aca20e937a4ec26dac228e84" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-25T11:33:32.921739" + } +} \ 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 00000000..dec77642 --- /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/gunzip/tests/tags.yml b/modules/nf-core/gunzip/tests/tags.yml new file mode 100644 index 00000000..fd3f6915 --- /dev/null +++ b/modules/nf-core/gunzip/tests/tags.yml @@ -0,0 +1,2 @@ +gunzip: + - modules/nf-core/gunzip/** diff --git a/modules/nf-core/kaiju/kaiju/environment.yml b/modules/nf-core/kaiju/kaiju/environment.yml index baac450b..3bb316c1 100644 --- a/modules/nf-core/kaiju/kaiju/environment.yml +++ b/modules/nf-core/kaiju/kaiju/environment.yml @@ -1,7 +1,5 @@ -name: kaiju_kaiju channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::kaiju=1.10.0 diff --git a/modules/nf-core/kaiju/kaiju2krona/environment.yml b/modules/nf-core/kaiju/kaiju2krona/environment.yml index 2905be97..3bb316c1 100644 --- a/modules/nf-core/kaiju/kaiju2krona/environment.yml +++ b/modules/nf-core/kaiju/kaiju2krona/environment.yml @@ -1,7 +1,5 @@ -name: kaiju_kaiju2krona channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::kaiju=1.10.0 diff --git a/modules/nf-core/kaiju/kaiju2krona/main.nf b/modules/nf-core/kaiju/kaiju2krona/main.nf index 85d2dfd2..d75a23d9 100644 --- a/modules/nf-core/kaiju/kaiju2krona/main.nf +++ b/modules/nf-core/kaiju/kaiju2krona/main.nf @@ -49,4 +49,3 @@ process KAIJU_KAIJU2KRONA { END_VERSIONS """ } - diff --git a/modules/nf-core/kaiju/kaiju2table/environment.yml b/modules/nf-core/kaiju/kaiju2table/environment.yml index 18685f41..3bb316c1 100644 --- a/modules/nf-core/kaiju/kaiju2table/environment.yml +++ b/modules/nf-core/kaiju/kaiju2table/environment.yml @@ -1,7 +1,5 @@ -name: kaiju_kaiju2table channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::kaiju=1.10.0 diff --git a/modules/nf-core/kmcp/profile/environment.yml b/modules/nf-core/kmcp/profile/environment.yml index 43de2a64..ae5b9202 100644 --- a/modules/nf-core/kmcp/profile/environment.yml +++ b/modules/nf-core/kmcp/profile/environment.yml @@ -1,7 +1,5 @@ -name: kmcp_profile channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::kmcp=0.9.4 diff --git a/modules/nf-core/kmcp/profile/tests/main.nf.test.snap b/modules/nf-core/kmcp/profile/tests/main.nf.test.snap index 72b41ce8..f4a05eab 100644 --- a/modules/nf-core/kmcp/profile/tests/main.nf.test.snap +++ b/modules/nf-core/kmcp/profile/tests/main.nf.test.snap @@ -30,9 +30,9 @@ ], "meta": { "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nextflow": "24.04.3" }, - "timestamp": "2024-06-07T15:36:20.331533599" + "timestamp": "2024-07-10T15:07:59.876784" }, "sarscov2 - fasta": { "content": [ diff --git a/modules/nf-core/kmcp/search/environment.yml b/modules/nf-core/kmcp/search/environment.yml index 397fcb8a..ae5b9202 100644 --- a/modules/nf-core/kmcp/search/environment.yml +++ b/modules/nf-core/kmcp/search/environment.yml @@ -1,7 +1,5 @@ -name: kmcp_search channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::kmcp=0.9.4 diff --git a/modules/nf-core/kraken2/kraken2/environment.yml b/modules/nf-core/kraken2/kraken2/environment.yml new file mode 100644 index 00000000..ba776d31 --- /dev/null +++ b/modules/nf-core/kraken2/kraken2/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::kraken2=2.1.3" + - "coreutils=9.4" + - "pigz=2.8" diff --git a/modules/nf-core/kraken2/kraken2/main.nf b/modules/nf-core/kraken2/kraken2/main.nf index da8d8c6d..364a6fe2 100644 --- a/modules/nf-core/kraken2/kraken2/main.nf +++ b/modules/nf-core/kraken2/kraken2/main.nf @@ -2,10 +2,10 @@ process KRAKEN2_KRAKEN2 { tag "$meta.id" label 'process_high' - conda "bioconda::kraken2=2.1.2 conda-forge::pigz=2.6" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-5799ab18b5fc681e75923b2450abaa969907ec98:87fc08d11968d081f3e8a37131c1f1f6715b6542-0' : - 'biocontainers/mulled-v2-5799ab18b5fc681e75923b2450abaa969907ec98:87fc08d11968d081f3e8a37131c1f1f6715b6542-0' }" + 'https://depot.galaxyproject.org/singularity/mulled-v2-8706a1dd73c6cc426e12dd4dd33a5e917b3989ae:c8cbdc8ff4101e6745f8ede6eb5261ef98bdaff4-0' : + 'biocontainers/mulled-v2-8706a1dd73c6cc426e12dd4dd33a5e917b3989ae:c8cbdc8ff4101e6745f8ede6eb5261ef98bdaff4-0' }" input: tuple val(meta), path(reads) @@ -55,4 +55,31 @@ process KRAKEN2_KRAKEN2 { pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def paired = meta.single_end ? "" : "--paired" + def classified = meta.single_end ? "${prefix}.classified.fastq.gz" : "${prefix}.classified_1.fastq.gz ${prefix}.classified_2.fastq.gz" + def unclassified = meta.single_end ? "${prefix}.unclassified.fastq.gz" : "${prefix}.unclassified_1.fastq.gz ${prefix}.unclassified_2.fastq.gz" + def readclassification_option = save_reads_assignment ? "--output ${prefix}.kraken2.classifiedreads.txt" : "--output /dev/null" + def compress_reads_command = save_output_fastqs ? "pigz -p $task.cpus *.fastq" : "" + + """ + touch ${prefix}.kraken2.report.txt + if [ "$save_output_fastqs" == "true" ]; then + touch $classified + touch $unclassified + fi + if [ "$save_reads_assignment" == "true" ]; then + touch ${prefix}.kraken2.classifiedreads.txt + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kraken2: \$(echo \$(kraken2 --version 2>&1) | sed 's/^.*Kraken version //; s/ .*\$//') + pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) + END_VERSIONS + """ + } diff --git a/modules/nf-core/kraken2/kraken2/meta.yml b/modules/nf-core/kraken2/kraken2/meta.yml index 4721f45b..7909ffe7 100644 --- a/modules/nf-core/kraken2/kraken2/meta.yml +++ b/modules/nf-core/kraken2/kraken2/meta.yml @@ -73,3 +73,6 @@ output: authors: - "@joseespinosa" - "@drpatelh" +maintainers: + - "@joseespinosa" + - "@drpatelh" diff --git a/modules/nf-core/kraken2/kraken2/tests/main.nf.test b/modules/nf-core/kraken2/kraken2/tests/main.nf.test new file mode 100644 index 00000000..c0843df2 --- /dev/null +++ b/modules/nf-core/kraken2/kraken2/tests/main.nf.test @@ -0,0 +1,143 @@ +nextflow_process { + name "Test Process KRAKEN2_KRAKEN2" + script "../main.nf" + process "KRAKEN2_KRAKEN2" + tag "modules" + tag "modules_nfcore" + tag "untar" + tag "kraken2" + tag "kraken2/kraken2" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( + params.modules_testdata_base_path + "genomics/sarscov2/genome/db/kraken2.tar.gz", + checkIfExists: true + ) + ]) + """ + } + } + } + + test("sarscov2 illumina single end [fastq]") { + when { + process { + """ + input[0] = [ + [ 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] = true + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.report, + process.out.versions, + ).match() + }, + { assert process.out.classified_reads_fastq.get(0).get(1) ==~ ".*/test.classified.fastq.gz" }, + { assert process.out.unclassified_reads_fastq.get(0).get(1) ==~ ".*/test.unclassified.fastq.gz" }, + ) + } + } + + test("sarscov2 illumina paired end [fastq]") { + when { + params { + outdir = "$outputDir" + } + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file( + params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", + checkIfExists: true + ), + file( + params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", + checkIfExists: true + ) + + ] + ] + input[1] = UNTAR.out.untar.map{ it[1] } + input[2] = true + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.report, + process.out.versions, + ).match() + }, + { assert process.out.classified_reads_fastq.get(0).get(1).get(0) + ==~ ".*/test.classified_1.fastq.gz" }, + { assert process.out.classified_reads_fastq.get(0).get(1).get(1) + ==~ ".*/test.classified_2.fastq.gz" }, + { assert process.out.unclassified_reads_fastq.get(0).get(1).get(0) + ==~ ".*/test.unclassified_1.fastq.gz" }, + { assert process.out.unclassified_reads_fastq.get(0).get(1).get(1) + ==~ ".*/test.unclassified_2.fastq.gz" }, + ) + } + } + + test("sarscov2 illumina single end [fastq] + save_reads_assignment") { + when { + params { + outdir = "$outputDir" + } + + process { + """ + input[0] = [ + [ 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 + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.report, + process.out.classified_reads_assignment, + process.out.versions, + ).match() + }, + ) + } + } +} diff --git a/modules/nf-core/kraken2/kraken2/tests/main.nf.test.snap b/modules/nf-core/kraken2/kraken2/tests/main.nf.test.snap new file mode 100644 index 00000000..b432f878 --- /dev/null +++ b/modules/nf-core/kraken2/kraken2/tests/main.nf.test.snap @@ -0,0 +1,74 @@ +{ + "sarscov2 illumina single end [fastq]": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.kraken2.report.txt:md5,4227755fe40478b8d7dc8634b489761e" + ] + ], + [ + "versions.yml:md5,79adf2ca1cfc625cb77e391b27142c43" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-04T18:47:03.745692" + }, + "sarscov2 illumina paired end [fastq]": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.kraken2.report.txt:md5,4227755fe40478b8d7dc8634b489761e" + ] + ], + [ + "versions.yml:md5,79adf2ca1cfc625cb77e391b27142c43" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-04T18:47:13.75649" + }, + "sarscov2 illumina single end [fastq] + save_reads_assignment": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.kraken2.report.txt:md5,4227755fe40478b8d7dc8634b489761e" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.kraken2.classifiedreads.txt:md5,e7a90531f0d8d777316515c36fe4cae0" + ] + ], + [ + "versions.yml:md5,79adf2ca1cfc625cb77e391b27142c43" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-04T18:47:22.459465" + } +} \ No newline at end of file diff --git a/modules/nf-core/kraken2/kraken2/tests/tags.yml b/modules/nf-core/kraken2/kraken2/tests/tags.yml new file mode 100644 index 00000000..9ebfd7ab --- /dev/null +++ b/modules/nf-core/kraken2/kraken2/tests/tags.yml @@ -0,0 +1,3 @@ +kraken2/kraken2: + - modules/nf-core/kraken2/kraken2/** + - modules/nf-core/untar/** diff --git a/modules/nf-core/krakentools/combinekreports/environment.yml b/modules/nf-core/krakentools/combinekreports/environment.yml new file mode 100644 index 00000000..13814bc2 --- /dev/null +++ b/modules/nf-core/krakentools/combinekreports/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::krakentools=1.2 diff --git a/modules/nf-core/krakentools/combinekreports/main.nf b/modules/nf-core/krakentools/combinekreports/main.nf index 43cc3793..6799258b 100644 --- a/modules/nf-core/krakentools/combinekreports/main.nf +++ b/modules/nf-core/krakentools/combinekreports/main.nf @@ -1,7 +1,7 @@ process KRAKENTOOLS_COMBINEKREPORTS { label 'process_single' - conda "bioconda::krakentools=1.2" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/krakentools:1.2--pyh5e36f6f_0': 'biocontainers/krakentools:1.2--pyh5e36f6f_0' }" @@ -31,4 +31,17 @@ process KRAKENTOOLS_COMBINEKREPORTS { combine_kreports.py: ${VERSION} END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '1.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${prefix}.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + combine_kreports.py: ${VERSION} + END_VERSIONS + """ } diff --git a/modules/nf-core/krakentools/combinekreports/meta.yml b/modules/nf-core/krakentools/combinekreports/meta.yml index 213fc8c6..b35d1214 100644 --- a/modules/nf-core/krakentools/combinekreports/meta.yml +++ b/modules/nf-core/krakentools/combinekreports/meta.yml @@ -1,5 +1,5 @@ name: krakentools_combinekreports -description: Takes a Kraken report file and prints out a krona-compatible TEXT file +description: Takes multiple kraken-style reports and combines them into a single report file keywords: - kraken - krakentools @@ -12,7 +12,6 @@ tools: description: KrakenTools is a suite of scripts to be used for post-analysis of Kraken/KrakenUniq/Kraken2/Bracken results. Please cite the relevant paper if using KrakenTools with any of the listed programs. homepage: https://github.com/jenniferlu717/KrakenTools licence: ["GPL v3"] - input: - meta: type: map @@ -23,7 +22,6 @@ input: type: file description: List of kraken-style report files pattern: "*.{txt,kreport}" - output: - meta: type: map @@ -38,6 +36,7 @@ output: type: file description: Combined kreport file of all input files pattern: "*.txt" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/krakentools/combinekreports/tests/main.nf.test b/modules/nf-core/krakentools/combinekreports/tests/main.nf.test new file mode 100644 index 00000000..b287e53b --- /dev/null +++ b/modules/nf-core/krakentools/combinekreports/tests/main.nf.test @@ -0,0 +1,55 @@ +nextflow_process { + + name "Test Process KRAKENTOOLS_COMBINEKREPORTS" + script "../main.nf" + process "KRAKENTOOLS_COMBINEKREPORTS" + + tag "modules" + tag "modules_nfcore" + tag "krakentools" + tag "krakentools/combinekreports" + + test ("sarscov2 - metagenome - kraken report") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out ).match() } + ) + } + + } + + test ("sarscov2 - metagenome - kraken report - stub") { + + options '-stub' + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out ).match() } + ) + } + } +} diff --git a/modules/nf-core/krakentools/combinekreports/tests/main.nf.test.snap b/modules/nf-core/krakentools/combinekreports/tests/main.nf.test.snap new file mode 100644 index 00000000..439f27cb --- /dev/null +++ b/modules/nf-core/krakentools/combinekreports/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "sarscov2 - metagenome - kraken report": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.txt:md5,481c4b987b922979baf74f2ce8d88b02" + ] + ], + "1": [ + "versions.yml:md5,a907962abbd9f5dcd34c9e8a4e6100d0" + ], + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,481c4b987b922979baf74f2ce8d88b02" + ] + ], + "versions": [ + "versions.yml:md5,a907962abbd9f5dcd34c9e8a4e6100d0" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-07T09:12:42.382189" + }, + "sarscov2 - metagenome - kraken report - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,a907962abbd9f5dcd34c9e8a4e6100d0" + ], + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,a907962abbd9f5dcd34c9e8a4e6100d0" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-07T09:12:46.705759" + } +} diff --git a/modules/nf-core/krakentools/combinekreports/tests/tags.yml b/modules/nf-core/krakentools/combinekreports/tests/tags.yml new file mode 100644 index 00000000..28911778 --- /dev/null +++ b/modules/nf-core/krakentools/combinekreports/tests/tags.yml @@ -0,0 +1,2 @@ +krakentools/combinekreports: + - "modules/nf-core/krakentools/combinekreports/**" diff --git a/modules/nf-core/krakentools/kreport2krona/environment.yml b/modules/nf-core/krakentools/kreport2krona/environment.yml new file mode 100644 index 00000000..13814bc2 --- /dev/null +++ b/modules/nf-core/krakentools/kreport2krona/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::krakentools=1.2 diff --git a/modules/nf-core/krakentools/kreport2krona/main.nf b/modules/nf-core/krakentools/kreport2krona/main.nf index a3923afe..f81dee77 100644 --- a/modules/nf-core/krakentools/kreport2krona/main.nf +++ b/modules/nf-core/krakentools/kreport2krona/main.nf @@ -3,7 +3,7 @@ process KRAKENTOOLS_KREPORT2KRONA { label 'process_single' // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. - conda "bioconda::krakentools=1.2" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/krakentools:1.2--pyh5e36f6f_0': 'biocontainers/krakentools:1.2--pyh5e36f6f_0' }" @@ -33,4 +33,17 @@ process KRAKENTOOLS_KREPORT2KRONA { kreport2krona.py: ${VERSION} END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '1.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${prefix}.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kreport2krona.py: ${VERSION} + END_VERSIONS + """ } diff --git a/modules/nf-core/krakentools/kreport2krona/meta.yml b/modules/nf-core/krakentools/kreport2krona/meta.yml index 2f8a163c..ae5bf2f1 100644 --- a/modules/nf-core/krakentools/kreport2krona/meta.yml +++ b/modules/nf-core/krakentools/kreport2krona/meta.yml @@ -10,7 +10,6 @@ tools: description: KrakenTools is a suite of scripts to be used for post-analysis of Kraken/KrakenUniq/Kraken2/Bracken results. Please cite the relevant paper if using KrakenTools with any of the listed programs. homepage: https://github.com/jenniferlu717/KrakenTools licence: ["GPL v3"] - input: - meta: type: map @@ -21,7 +20,6 @@ input: type: file description: Kraken report pattern: "*.{txt,kreport}" - output: - meta: type: map @@ -32,10 +30,11 @@ output: type: file description: File containing software versions pattern: "versions.yml" - - krona: + - txt: type: file description: Krona text-based input file converted from Kraken report pattern: "*.{txt,krona}" - authors: - "@MillironX" +maintainers: + - "@MillironX" diff --git a/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test b/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test new file mode 100644 index 00000000..1d85a0b2 --- /dev/null +++ b/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test @@ -0,0 +1,85 @@ +nextflow_process { + + name "Test Process KRAKENTOOLS_KREPORT2KRONA" + script "modules/nf-core/krakentools/kreport2krona/main.nf" + process "KRAKENTOOLS_KREPORT2KRONA" + tag "modules" + tag "modules_nfcore" + tag "untar" + tag "kraken2" + tag "kraken2/kraken2" + tag "krakentools" + tag "krakentools/kreport2krona" + + setup { + run("UNTAR") { + script "modules/nf-core/untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( + params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2.tar.gz', + checkIfExists: true + ) + ]) + """ + } + } + run("KRAKEN2_KRAKEN2") { + script "modules/nf-core/kraken2/kraken2/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 + input[3] = false + """ + } + } + } + + test("sarscov2 illumina single end [fastq]") { + + when { + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 illumina single end [fastq] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = KRAKEN2_KRAKEN2.out.report + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test.snap b/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test.snap new file mode 100644 index 00000000..c18cee02 --- /dev/null +++ b/modules/nf-core/krakentools/kreport2krona/tests/main.nf.test.snap @@ -0,0 +1,72 @@ +{ + "sarscov2 illumina single end [fastq]": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.txt:md5,c89a9db7acbdba9dea0fe246bcaa85c1" + ] + ], + "1": [ + "versions.yml:md5,f4a5d570efec153ab0de3da130394cbb" + ], + "txt": [ + [ + { + "id": "test", + "single_end": true + }, + "test.txt:md5,c89a9db7acbdba9dea0fe246bcaa85c1" + ] + ], + "versions": [ + "versions.yml:md5,f4a5d570efec153ab0de3da130394cbb" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "23.10.4" + }, + "timestamp": "2024-08-01T21:40:46.959343186" + }, + "sarscov2 illumina single end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,f4a5d570efec153ab0de3da130394cbb" + ], + "txt": [ + [ + { + "id": "test", + "single_end": true + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,f4a5d570efec153ab0de3da130394cbb" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "23.10.4" + }, + "timestamp": "2024-08-02T18:35:32.145822126" + } +} \ No newline at end of file diff --git a/modules/nf-core/krakentools/kreport2krona/tests/tags.yml b/modules/nf-core/krakentools/kreport2krona/tests/tags.yml new file mode 100644 index 00000000..1e582883 --- /dev/null +++ b/modules/nf-core/krakentools/kreport2krona/tests/tags.yml @@ -0,0 +1,4 @@ +krakentools/kreport2krona: + - modules/nf-core/krakentools/kreport2krona/** + - modules/nf-core/kraken2/kraken2/** + - modules/nf-core/untar/** diff --git a/modules/nf-core/krakenuniq/preloadedkrakenuniq/environment.yml b/modules/nf-core/krakenuniq/preloadedkrakenuniq/environment.yml index 11bbb879..bbf85c33 100644 --- a/modules/nf-core/krakenuniq/preloadedkrakenuniq/environment.yml +++ b/modules/nf-core/krakenuniq/preloadedkrakenuniq/environment.yml @@ -1,7 +1,5 @@ -name: krakenuniq_preloadedkrakenuniq channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::krakenuniq=1.0.4 diff --git a/modules/nf-core/krakenuniq/preloadedkrakenuniq/main.nf b/modules/nf-core/krakenuniq/preloadedkrakenuniq/main.nf index 78b2f3ab..d24f75d2 100644 --- a/modules/nf-core/krakenuniq/preloadedkrakenuniq/main.nf +++ b/modules/nf-core/krakenuniq/preloadedkrakenuniq/main.nf @@ -4,8 +4,8 @@ process KRAKENUNIQ_PRELOADEDKRAKENUNIQ { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/krakenuniq:1.0.4--pl5321h19e8d03_0': - 'biocontainers/krakenuniq:1.0.4--pl5321h19e8d03_0' }" + 'https://depot.galaxyproject.org/singularity/krakenuniq:1.0.4--pl5321h6dccd9a_2': + 'biocontainers/krakenuniq:1.0.4--pl5321h6dccd9a_2' }" input: tuple val(meta), path(sequences) diff --git a/modules/nf-core/krona/ktimporttaxonomy/environment.yml b/modules/nf-core/krona/ktimporttaxonomy/environment.yml new file mode 100644 index 00000000..342c5892 --- /dev/null +++ b/modules/nf-core/krona/ktimporttaxonomy/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::krona=2.8.1 diff --git a/modules/nf-core/krona/ktimporttaxonomy/main.nf b/modules/nf-core/krona/ktimporttaxonomy/main.nf index 0758a382..16f3cd98 100644 --- a/modules/nf-core/krona/ktimporttaxonomy/main.nf +++ b/modules/nf-core/krona/ktimporttaxonomy/main.nf @@ -3,10 +3,10 @@ process KRONA_KTIMPORTTAXONOMY { label 'process_single' // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. - conda "bioconda::krona=2.8" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/krona:2.8--pl5262hdfd78af_2' : - 'biocontainers/krona:2.8--pl5262hdfd78af_2' }" + 'https://depot.galaxyproject.org/singularity/krona:2.8.1--pl5321hdfd78af_1': + 'biocontainers/krona:2.8.1--pl5321hdfd78af_1' }" input: tuple val(meta), path(report) @@ -22,7 +22,7 @@ process KRONA_KTIMPORTTAXONOMY { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '2.8' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def VERSION = '2.8.1' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. """ TAXONOMY=\$(find -L . -name '*.tab' -exec dirname {} \\;) echo \$TAXONOMY @@ -38,4 +38,17 @@ process KRONA_KTIMPORTTAXONOMY { krona: $VERSION END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '2.8.1' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${prefix}.html + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + krona: $VERSION + END_VERSIONS + """ } diff --git a/modules/nf-core/krona/ktimporttaxonomy/meta.yml b/modules/nf-core/krona/ktimporttaxonomy/meta.yml index dfcd2f2b..3504b13e 100644 --- a/modules/nf-core/krona/ktimporttaxonomy/meta.yml +++ b/modules/nf-core/krona/ktimporttaxonomy/meta.yml @@ -13,14 +13,13 @@ tools: homepage: https://github.com/marbl/Krona/wiki/KronaTools documentation: http://manpages.ubuntu.com/manpages/impish/man1/ktImportTaxonomy.1.html doi: 10.1186/1471-2105-12-385 - input: - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test'] - - database: + - taxonomy: type: file description: | Path to a Krona taxonomy .tab file normally downloaded and generated by @@ -31,7 +30,6 @@ input: type: file description: "A tab-delimited file with taxonomy IDs and (optionally) query IDs, magnitudes, and scores. Query IDs are taken from column 1, taxonomy IDs from column 2, and scores from column 3. Lines beginning with # will be ignored." pattern: "*.{tsv}" - output: - versions: type: file @@ -41,6 +39,7 @@ output: type: file description: A html file containing an interactive krona plot. pattern: "*.{html}" - authors: - "@mjakobs" +maintainers: + - "@mjakobs" diff --git a/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test b/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test new file mode 100644 index 00000000..1068f305 --- /dev/null +++ b/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test @@ -0,0 +1,61 @@ +nextflow_process { + + name "Test Process KRONA_KTIMPORTTAXONOMY" + script "../main.nf" + process "KRONA_KTIMPORTTAXONOMY" + + tag "modules" + tag "modules_nfcore" + tag "krona" + tag "krona/ktimporttaxonomy" + + test ("sarscov2 - metagenome - kraken report") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + input[1] = Channel.of([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/krona_taxonomy.tab', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out.versions ).match() }, + { assert file(process.out.html.get(0).get(1)).exists() } + ) + } + } + + test ("sarscov2 - metagenome - kraken report - stub") { + + options '-stub' + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + input[1] = Channel.of([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/krona_taxonomy.tab', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } +} diff --git a/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test.snap b/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test.snap new file mode 100644 index 00000000..61fba868 --- /dev/null +++ b/modules/nf-core/krona/ktimporttaxonomy/tests/main.nf.test.snap @@ -0,0 +1,47 @@ +{ + "sarscov2 - metagenome - kraken report": { + "content": [ + [ + "versions.yml:md5,59fc89b6db8fad0aa9aa06f7437a18a7" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-08T10:34:23.760055" + }, + "sarscov2 - metagenome - kraken report - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,59fc89b6db8fad0aa9aa06f7437a18a7" + ], + "html": [ + [ + { + "id": "test" + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,59fc89b6db8fad0aa9aa06f7437a18a7" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-08T10:34:29.695251" + } +} diff --git a/modules/nf-core/krona/ktimporttaxonomy/tests/tags.yml b/modules/nf-core/krona/ktimporttaxonomy/tests/tags.yml new file mode 100644 index 00000000..1112970e --- /dev/null +++ b/modules/nf-core/krona/ktimporttaxonomy/tests/tags.yml @@ -0,0 +1,2 @@ +krona/ktimporttaxonomy: + - "modules/nf-core/krona/ktimporttaxonomy/**" diff --git a/modules/nf-core/krona/ktimporttext/environment.yml b/modules/nf-core/krona/ktimporttext/environment.yml new file mode 100644 index 00000000..342c5892 --- /dev/null +++ b/modules/nf-core/krona/ktimporttext/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::krona=2.8.1 diff --git a/modules/nf-core/krona/ktimporttext/main.nf b/modules/nf-core/krona/ktimporttext/main.nf index 43280191..945f8570 100644 --- a/modules/nf-core/krona/ktimporttext/main.nf +++ b/modules/nf-core/krona/ktimporttext/main.nf @@ -2,7 +2,7 @@ process KRONA_KTIMPORTTEXT { tag "$meta.id" label 'process_single' - conda "bioconda::krona=2.8.1" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/krona:2.8.1--pl5321hdfd78af_1': 'biocontainers/krona:2.8.1--pl5321hdfd78af_1' }" @@ -31,4 +31,16 @@ process KRONA_KTIMPORTTEXT { krona: \$( echo \$(ktImportText 2>&1) | sed 's/^.*KronaTools //g; s/- ktImportText.*\$//g') END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.html + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + krona: \$( echo \$(ktImportText 2>&1) | sed 's/^.*KronaTools //g; s/- ktImportText.*\$//g') + END_VERSIONS + """ } diff --git a/modules/nf-core/krona/ktimporttext/meta.yml b/modules/nf-core/krona/ktimporttext/meta.yml index a7108e0d..5288ea0b 100644 --- a/modules/nf-core/krona/ktimporttext/meta.yml +++ b/modules/nf-core/krona/ktimporttext/meta.yml @@ -15,8 +15,7 @@ tools: documentation: http://manpages.ubuntu.com/manpages/impish/man1/ktImportTaxonomy.1.html tool_dev_url: https://github.com/marbl/Krona doi: 10.1186/1471-2105-12-385 - licence: https://raw.githubusercontent.com/marbl/Krona/master/KronaTools/LICENSE.txt - + licence: ["https://raw.githubusercontent.com/marbl/Krona/master/KronaTools/LICENSE.txt"] input: - meta: type: map @@ -27,7 +26,6 @@ input: type: file description: "Tab-delimited text file. Each line should be a number followed by a list of wedges to contribute to (starting from the highest level). If no wedges are listed (and just a quantity is given), it will contribute to the top level. If the same lineage is listed more than once, the values will be added. Quantities can be omitted if -q is specified. Lines beginning with '#' will be ignored." pattern: "*.{txt}" - output: - meta: type: map @@ -42,6 +40,7 @@ output: type: file description: A html file containing an interactive krona plot. pattern: "*.{html}" - authors: - "@jianhong" +maintainers: + - "@jianhong" diff --git a/modules/nf-core/krona/ktimporttext/tests/main.nf.test b/modules/nf-core/krona/ktimporttext/tests/main.nf.test new file mode 100644 index 00000000..79b4ce90 --- /dev/null +++ b/modules/nf-core/krona/ktimporttext/tests/main.nf.test @@ -0,0 +1,54 @@ +nextflow_process { + + name "Test Process KRONA_KTIMPORTTEXT" + script "../main.nf" + process "KRONA_KTIMPORTTEXT" + tag "modules" + tag "modules_nfcore" + tag "krona" + tag "krona/ktimporttext" + + test ("sarscov2 - metagenome - kraken report") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out.versions ).match() }, + { assert file(process.out.html.get(0).get(1)).exists() } + ) + } + } + + test ("sarscov2 - metagenome - kraken report - stub") { + + options '-stub' + when { + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/metagenome/test_1.kraken2.report.txt', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } +} diff --git a/modules/nf-core/krona/ktimporttext/tests/main.nf.test.snap b/modules/nf-core/krona/ktimporttext/tests/main.nf.test.snap new file mode 100644 index 00000000..3a3c3803 --- /dev/null +++ b/modules/nf-core/krona/ktimporttext/tests/main.nf.test.snap @@ -0,0 +1,47 @@ +{ + "sarscov2 - metagenome - kraken report": { + "content": [ + [ + "versions.yml:md5,b8847bf9b5b00d34a38cf6f774c4c5db" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-08T10:51:50.077935" + }, + "sarscov2 - metagenome - kraken report - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,b8847bf9b5b00d34a38cf6f774c4c5db" + ], + "html": [ + [ + { + "id": "test" + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,b8847bf9b5b00d34a38cf6f774c4c5db" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-08T10:51:56.690617" + } +} diff --git a/modules/nf-core/krona/ktimporttext/tests/tags.yml b/modules/nf-core/krona/ktimporttext/tests/tags.yml new file mode 100644 index 00000000..d1b04dfc --- /dev/null +++ b/modules/nf-core/krona/ktimporttext/tests/tags.yml @@ -0,0 +1,2 @@ +krona/ktimporttext: + - "modules/nf-core/krona/ktimporttext/**" diff --git a/modules/nf-core/malt/run/environment.yml b/modules/nf-core/malt/run/environment.yml new file mode 100644 index 00000000..15a77500 --- /dev/null +++ b/modules/nf-core/malt/run/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::malt=0.61 diff --git a/modules/nf-core/malt/run/main.nf b/modules/nf-core/malt/run/main.nf index 3ece2a45..d2ddd8aa 100644 --- a/modules/nf-core/malt/run/main.nf +++ b/modules/nf-core/malt/run/main.nf @@ -2,7 +2,7 @@ process MALT_RUN { tag "$meta.id" label 'process_high' - conda "bioconda::malt=0.61" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/malt:0.61--hdfd78af_0' : 'biocontainers/malt:0.61--hdfd78af_0' }" @@ -12,10 +12,10 @@ process MALT_RUN { path index output: - tuple val(meta), path("*.rma6") , emit: rma6 - tuple val(meta), path("*.{tab,text,sam}"), optional:true, emit: alignments - tuple val(meta), path("*.log") , emit: log - path "versions.yml" , emit: versions + tuple val(meta), path("*.rma6") , emit: rma6 + tuple val(meta), path("*.{tab,text,sam,tab.gz,text.gz,sam.gz}"), optional:true, emit: alignments + tuple val(meta), path("*.log") , emit: log + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -23,7 +23,6 @@ process MALT_RUN { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - """ malt-run \\ -t $task.cpus \\ @@ -38,4 +37,18 @@ process MALT_RUN { malt: \$(malt-run --help 2>&1 | grep -o 'version.* ' | cut -f 1 -d ',' | cut -f2 -d ' ') END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}-malt-run.log + touch ${prefix}.rma6 + touch ${prefix}.sam + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + malt: \$(malt-run --help 2>&1 | grep -o 'version.* ' | cut -f 1 -d ',' | cut -f2 -d ' ') + END_VERSIONS + """ } diff --git a/modules/nf-core/malt/run/meta.yml b/modules/nf-core/malt/run/meta.yml index f5ee655a..5bb7d9b3 100644 --- a/modules/nf-core/malt/run/meta.yml +++ b/modules/nf-core/malt/run/meta.yml @@ -14,10 +14,8 @@ tools: description: A tool for mapping metagenomic data homepage: https://www.wsi.uni-tuebingen.de/lehrstuehle/algorithms-in-bioinformatics/software/malt/ documentation: https://software-ab.cs.uni-tuebingen.de/download/malt/manual.pdf - doi: "10.1038/s41559-017-0446-6" licence: ["GPL v3"] - input: - meta: type: map @@ -41,7 +39,7 @@ output: type: file description: MEGAN6 RMA6 file pattern: "*.rma6" - - sam: + - alignments: type: file description: Alignment files in Tab, Text or MEGAN-compatible SAM format pattern: "*.{tab,txt,sam}" @@ -49,6 +47,7 @@ output: type: file description: Log of verbose MALT stdout pattern: "*-malt-run.log" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/malt/run/tests/main.nf.test b/modules/nf-core/malt/run/tests/main.nf.test new file mode 100644 index 00000000..304c01d4 --- /dev/null +++ b/modules/nf-core/malt/run/tests/main.nf.test @@ -0,0 +1,94 @@ +nextflow_process { + + name "Test Process MALT_RUN" + script "../main.nf" + process "MALT_RUN" + config './nextflow.config' + + tag "modules" + tag "modules_nfcore" + tag "malt" + tag "malt/run" + tag "malt/build" + tag "unzip" + + setup { + run("UNZIP") { + script "../../../unzip/main.nf" + process { + """ + input[0] = [[], file("s3://ngi-igenomes/test-data/createtaxdb/taxonomy/megan-nucl-Feb2022.db.zip", checkIfExists: true)] + """ + } + } + run("MALT_BUILD") { + script "../../../malt/build/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + input[1] = [] + input[2] = UNZIP.out.unzipped_archive.map { it[1] } + """ + } + } + } + + test("sarscov2 - fastq") { + + when { + process { + """ + input[0] = [ + [ id:'test_1', single_end:false ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) + ] + ] + input[1] = MALT_BUILD.out.index + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.alignments, + process.out.versions, + file(process.out.rma6[0][1]).name + ).match() + }, + { assert path(process.out.log[0][1]).readLines().last().contains("Peak memory") }, + ) + } + + } + + test("sarscov2 - fastq - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test_1', single_end:false ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) + ] + ] + input[1] = MALT_BUILD.out.index + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/malt/run/tests/main.nf.test.snap b/modules/nf-core/malt/run/tests/main.nf.test.snap new file mode 100644 index 00000000..5a6c7a21 --- /dev/null +++ b/modules/nf-core/malt/run/tests/main.nf.test.snap @@ -0,0 +1,95 @@ +{ + "sarscov2 - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1.rma6:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1-malt-run.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,5b91a785e0342f9ef17a634c0452335a" + ], + "alignments": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1-malt-run.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "rma6": [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1.rma6:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,5b91a785e0342f9ef17a634c0452335a" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-01-26T14:15:43.18685293" + }, + "sarscov2 - fastq": { + "content": [ + [ + [ + { + "id": "test_1", + "single_end": false + }, + "test_1.blastn.sam.gz:md5,8ad56803c1674e1a8cd42fe8801e71fd" + ] + ], + [ + "versions.yml:md5,5b91a785e0342f9ef17a634c0452335a" + ], + "test_1.rma6" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-30T07:04:07.674069223" + } +} \ No newline at end of file diff --git a/modules/nf-core/malt/run/tests/nextflow.config b/modules/nf-core/malt/run/tests/nextflow.config new file mode 100644 index 00000000..34fc9b7e --- /dev/null +++ b/modules/nf-core/malt/run/tests/nextflow.config @@ -0,0 +1,13 @@ +process { + + + withName: MALT_RUN { + ext.args = "-m BlastN -J-Xmx8G -a . -f SAM" + memory = 12.GB + } + + withName: MALT_BUILD { + ext.args = "--sequenceType DNA" + } + +} diff --git a/modules/nf-core/malt/run/tests/tags.yml b/modules/nf-core/malt/run/tests/tags.yml new file mode 100644 index 00000000..a5d6b55f --- /dev/null +++ b/modules/nf-core/malt/run/tests/tags.yml @@ -0,0 +1,2 @@ +malt/run: + - "modules/nf-core/malt/run/**" diff --git a/modules/nf-core/megan/rma2info/environment.yml b/modules/nf-core/megan/rma2info/environment.yml index 471e5507..520b771d 100644 --- a/modules/nf-core/megan/rma2info/environment.yml +++ b/modules/nf-core/megan/rma2info/environment.yml @@ -1,6 +1,5 @@ channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::megan=6.21.7 + - bioconda::megan=6.25.9 diff --git a/modules/nf-core/megan/rma2info/main.nf b/modules/nf-core/megan/rma2info/main.nf index e91af504..c132bf04 100644 --- a/modules/nf-core/megan/rma2info/main.nf +++ b/modules/nf-core/megan/rma2info/main.nf @@ -2,10 +2,10 @@ process MEGAN_RMA2INFO { tag "$meta.id" label 'process_single' - conda 'modules/nf-core/megan/rma2info/environment.yml' + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/megan:6.24.20--h9ee0642_0': - 'biocontainers/megan:6.24.20--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/megan:6.25.9--h9ee0642_0': + 'biocontainers/megan:6.25.9--h9ee0642_0' }" input: tuple val(meta), path(rma6) @@ -35,4 +35,17 @@ process MEGAN_RMA2INFO { megan: \$(echo \$(rma2info 2>&1) | grep version | sed 's/.*version //g;s/, built.*//g') END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def summary = megan_summary ? "-es ${prefix}.megan" : "" + """ + echo "" | gzip > ${prefix}.txt.gz + touch ${prefix}.megan + cat <<-END_VERSIONS > versions.yml + "${task.process}": + megan: \$(echo \$(rma2info 2>&1) | grep version | sed 's/.*version //g;s/, built.*//g') + END_VERSIONSs + """ } diff --git a/modules/nf-core/megan/rma2info/meta.yml b/modules/nf-core/megan/rma2info/meta.yml index af3dd96c..158c8674 100644 --- a/modules/nf-core/megan/rma2info/meta.yml +++ b/modules/nf-core/megan/rma2info/meta.yml @@ -12,7 +12,7 @@ tools: documentation: "https://software-ab.cs.uni-tuebingen.de/download/megan6/welcome.html" tool_dev_url: "https://github.com/husonlab/megan-ce" doi: "10.1371/journal.pcbi.1004957" - licence: "['GPL >=3']" + licence: ["GPL >=3"] input: - meta: type: map diff --git a/modules/nf-core/megan/rma2info/tests/main.nf.test b/modules/nf-core/megan/rma2info/tests/main.nf.test new file mode 100644 index 00000000..3a3c807a --- /dev/null +++ b/modules/nf-core/megan/rma2info/tests/main.nf.test @@ -0,0 +1,63 @@ +nextflow_process { + + name "Test Process MEGAN_RMA2INFO" + script "../main.nf" + process "MEGAN_RMA2INFO" + + tag "modules" + tag "modules_nfcore" + tag "megan" + tag "megan/rma2info" + + test("malt - rma") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'delete_me/malt/test.rma6', checkIfExists: true) + ] + + input[1] = 'true' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out.versions ).match() }, + { assert file (process.out.txt.get(0).get(1)).exists() } + ) + } + } + + test("malt - rma - stub") { + + options "-stub" + config "./nextflow.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'delete_me/malt/test.rma6', checkIfExists: true) + ] + + input[1] = 'true' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot ( process.out ).match() }, + ) + } + } +} diff --git a/modules/nf-core/megan/rma2info/tests/main.nf.test.snap b/modules/nf-core/megan/rma2info/tests/main.nf.test.snap new file mode 100644 index 00000000..3acbaf59 --- /dev/null +++ b/modules/nf-core/megan/rma2info/tests/main.nf.test.snap @@ -0,0 +1,67 @@ +{ + "malt - rma": { + "content": [ + [ + "versions.yml:md5,b27ee982b4ec7793e8c3ff9f59e239e5" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-09T14:30:14.141999" + }, + "malt - rma - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.megan:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,13888803285f4a513973f3ced50f26b9" + ], + "megan_summary": [ + [ + { + "id": "test", + "single_end": false + }, + "test.megan:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "txt": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,13888803285f4a513973f3ced50f26b9" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-09T14:30:25.993511" + } +} diff --git a/modules/nf-core/megan/rma2info/tests/nextflow.config b/modules/nf-core/megan/rma2info/tests/nextflow.config new file mode 100644 index 00000000..23108504 --- /dev/null +++ b/modules/nf-core/megan/rma2info/tests/nextflow.config @@ -0,0 +1,3 @@ +process { + ext.args = '-c2c Taxonomy' +} diff --git a/modules/nf-core/megan/rma2info/tests/tags.yml b/modules/nf-core/megan/rma2info/tests/tags.yml new file mode 100644 index 00000000..dbbccf4c --- /dev/null +++ b/modules/nf-core/megan/rma2info/tests/tags.yml @@ -0,0 +1,2 @@ +megan/rma2info: + - "modules/nf-core/megan/rma2info/**" diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/environment.yml b/modules/nf-core/metaphlan/mergemetaphlantables/environment.yml new file mode 100644 index 00000000..709ddf70 --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::metaphlan=4.1.1 diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/main.nf b/modules/nf-core/metaphlan/mergemetaphlantables/main.nf index 0403bee9..7e82a33c 100644 --- a/modules/nf-core/metaphlan/mergemetaphlantables/main.nf +++ b/modules/nf-core/metaphlan/mergemetaphlantables/main.nf @@ -1,10 +1,10 @@ process METAPHLAN_MERGEMETAPHLANTABLES { label 'process_single' - conda "bioconda::metaphlan=4.0.6" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/metaphlan:4.0.6--pyhca03a8a_0' : - 'biocontainers/metaphlan:4.0.6--pyhca03a8a_0' }" + 'https://depot.galaxyproject.org/singularity/metaphlan:4.1.1--pyhdfd78af_0' : + 'biocontainers/metaphlan:4.1.1--pyhdfd78af_0' }" input: tuple val(meta), path(profiles) @@ -30,4 +30,16 @@ process METAPHLAN_MERGEMETAPHLANTABLES { metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') + END_VERSIONS + """ } diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml b/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml index 3c93964b..03aaae06 100644 --- a/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml +++ b/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml @@ -13,7 +13,6 @@ tools: documentation: https://github.com/biobakery/MetaPhlAn doi: "10.1038/s41587-023-01688-w" licence: ["MIT License"] - input: - meta: type: map @@ -24,7 +23,6 @@ input: type: file description: List of per-sample MetaPhlAn4 taxonomic abundance tables pattern: "*" - output: - meta: type: map @@ -39,7 +37,9 @@ output: type: file description: Combined MetaPhlAn4 table pattern: "*.txt" - authors: - "@jfy133" - "@LilyAnderssonLee" +maintainers: + - "@jfy133" + - "@LilyAnderssonLee" diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test b/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test new file mode 100644 index 00000000..17e9400c --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test @@ -0,0 +1,79 @@ +nextflow_process { + + name "Test Process METAPHLAN_MERGEMETAPHLANTABLES" + script "../main.nf" + config "./nextflow.config" + process "METAPHLAN_MERGEMETAPHLANTABLES" + + tag "modules" + tag "modules_nfcore" + tag "untar" + tag "metaphlan" + tag "metaphlan/metaphlan" + tag "metaphlan/mergemetaphlantables" + + setup { + run("UNTAR") { + script "../../../untar/main.nf" + process { + """ + input[0] = Channel.of([ + [], + file( params.modules_testdata_base_path + 'delete_me/metaphlan4_database.tar.gz', checkIfExists: true ) + ]) + """ + } + } + run("METAPHLAN_METAPHLAN") { + script "../../../metaphlan/metaphlan/main.nf" + 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 ) ], + [ [ id: 'test2', single_end: 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] } + """ + } + } + } + + test("sarscov2 - illumina single end [fastq]") { + + when { + process { + """ + input[0] = METAPHLAN_METAPHLAN.out.profile.map{meta, profile -> [[id: 'test'], profile]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } + + + test("sarscov2 - illumina single end [fastq] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = METAPHLAN_METAPHLAN.out.profile.map{meta, profile -> [[id: 'test'], profile]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } +} diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test.snap b/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test.snap new file mode 100644 index 00000000..3ba6d2ff --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "sarscov2 - illumina single end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,4687feab0c102fdc65fe2e174431a7c7" + ], + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,4687feab0c102fdc65fe2e174431a7c7" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-15T07:57:23.888779527" + }, + "sarscov2 - illumina single end [fastq]": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.txt:md5,671ac0cf0c2561154fc44109b6d8b973" + ] + ], + "1": [ + "versions.yml:md5,4687feab0c102fdc65fe2e174431a7c7" + ], + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,671ac0cf0c2561154fc44109b6d8b973" + ] + ], + "versions": [ + "versions.yml:md5,4687feab0c102fdc65fe2e174431a7c7" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-15T07:53:05.914944433" + } +} \ No newline at end of file diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/tests/nextflow.config b/modules/nf-core/metaphlan/mergemetaphlantables/tests/nextflow.config new file mode 100644 index 00000000..e64f0f92 --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/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/metaphlan/mergemetaphlantables/tests/tags.yml b/modules/nf-core/metaphlan/mergemetaphlantables/tests/tags.yml new file mode 100644 index 00000000..508a51b7 --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/tests/tags.yml @@ -0,0 +1,4 @@ +metaphlan/mergemetaphlantables: + - "modules/nf-core/metaphlan/mergemetaphlantables/**" + - "modules/nf-core/metaphlan/metaphlan/**" + - "modules/nf-core/untar/**" diff --git a/modules/nf-core/metaphlan/metaphlan/environment.yml b/modules/nf-core/metaphlan/metaphlan/environment.yml new file mode 100644 index 00000000..709ddf70 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::metaphlan=4.1.1 diff --git a/modules/nf-core/metaphlan/metaphlan/main.nf b/modules/nf-core/metaphlan/metaphlan/main.nf index 24533571..c427efeb 100644 --- a/modules/nf-core/metaphlan/metaphlan/main.nf +++ b/modules/nf-core/metaphlan/metaphlan/main.nf @@ -2,10 +2,10 @@ process METAPHLAN_METAPHLAN { tag "$meta.id" label 'process_medium' - conda "bioconda::metaphlan=4.0.6" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/metaphlan:4.0.6--pyhca03a8a_0' : - 'biocontainers/metaphlan:4.0.6--pyhca03a8a_0' }" + 'https://depot.galaxyproject.org/singularity/metaphlan:4.1.1--pyhdfd78af_0' : + 'biocontainers/metaphlan:4.1.1--pyhdfd78af_0' }" input: tuple val(meta), path(input) @@ -47,4 +47,21 @@ process METAPHLAN_METAPHLAN { metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') END_VERSIONS """ + + stub: + 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" + + """ + touch ${prefix}.biom + touch ${prefix}_profile.txt + + 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 index cb74bd59..d9be48e4 100644 --- a/modules/nf-core/metaphlan/metaphlan/meta.yml +++ b/modules/nf-core/metaphlan/metaphlan/meta.yml @@ -13,7 +13,6 @@ tools: documentation: https://github.com/biobakery/MetaPhlAn doi: "10.1038/s41587-023-01688-w" licence: ["MIT License"] - input: - meta: type: map @@ -24,13 +23,12 @@ 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}" - - metaphlan_db: + - 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: "*/" - output: - meta: type: map @@ -49,11 +47,13 @@ output: type: file description: General-use format for representing biological sample by observation contingency tables pattern: "*.{biom}" - - bowtie2out: + - bt2out: 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}" - 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 00000000..dff5cf71 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test @@ -0,0 +1,136 @@ +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] } + """ + } + } + + 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] } + """ + } + } + + 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] } + """ + } + } + + 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] - 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] } + """ + } + } + + 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 00000000..cbb1798e --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/main.nf.test.snap @@ -0,0 +1,145 @@ +{ + "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": [ + + ], + "3": [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ], + "biom": [ + [ + { + "id": "test", + "single_end": false + }, + "test.biom:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bt2out": [ + + ], + "profile": [ + [ + { + "id": "test", + "single_end": false + }, + "test_profile.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,db17780c9fc65bc70e9641101c47d0e0" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-08-13T12:51:42.549393" + }, + "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" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-27T10:33:32.269571148" + }, + "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" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-27T10:34:10.262604527" + }, + "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" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-27T10:33:51.829732777" + } +} \ 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 00000000..e64f0f92 --- /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/metaphlan/metaphlan/tests/tags.yml b/modules/nf-core/metaphlan/metaphlan/tests/tags.yml new file mode 100644 index 00000000..e90a3771 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/tests/tags.yml @@ -0,0 +1,3 @@ +metaphlan/metaphlan: + - modules/nf-core/metaphlan/metaphlan/** + - modules/nf-core/untar/** diff --git a/modules/nf-core/minimap2/align/environment.yml b/modules/nf-core/minimap2/align/environment.yml new file mode 100644 index 00000000..dc6476b7 --- /dev/null +++ b/modules/nf-core/minimap2/align/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::htslib=1.20 + - bioconda::minimap2=2.28 + - bioconda::samtools=1.20 diff --git a/modules/nf-core/minimap2/align/main.nf b/modules/nf-core/minimap2/align/main.nf index 4da47c18..d82dc14d 100644 --- a/modules/nf-core/minimap2/align/main.nf +++ b/modules/nf-core/minimap2/align/main.nf @@ -1,45 +1,75 @@ process MINIMAP2_ALIGN { tag "$meta.id" - label 'process_medium' + label 'process_high' // Note: the versions here need to match the versions used in the mulled container below and minimap2/index - conda "bioconda::minimap2=2.24 bioconda::samtools=1.14" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-66534bcbb7031a148b13e2ad42583020b9cd25c4:1679e915ddb9d6b4abda91880c4b48857d471bd8-0' : - 'biocontainers/mulled-v2-66534bcbb7031a148b13e2ad42583020b9cd25c4:1679e915ddb9d6b4abda91880c4b48857d471bd8-0' }" + 'https://depot.galaxyproject.org/singularity/mulled-v2-66534bcbb7031a148b13e2ad42583020b9cd25c4:3161f532a5ea6f1dec9be5667c9efc2afdac6104-0' : + 'biocontainers/mulled-v2-66534bcbb7031a148b13e2ad42583020b9cd25c4:3161f532a5ea6f1dec9be5667c9efc2afdac6104-0' }" input: tuple val(meta), path(reads) - path reference + tuple val(meta2), path(reference) val bam_format + val bam_index_extension val cigar_paf_format val cigar_bam output: - tuple val(meta), path("*.paf"), optional: true, emit: paf - tuple val(meta), path("*.bam"), optional: true, emit: bam - path "versions.yml" , emit: versions + tuple val(meta), path("*.paf") , optional: true, emit: paf + tuple val(meta), path("*.bam") , optional: true, emit: bam + tuple val(meta), path("*.bam.${bam_index_extension}"), optional: true, emit: index + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def args3 = task.ext.args3 ?: '' + def args4 = task.ext.args4 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def bam_output = bam_format ? "-a | samtools sort | samtools view -@ ${task.cpus} -b -h -o ${prefix}.bam" : "-o ${prefix}.paf" + def bam_index = bam_index_extension ? "${prefix}.bam##idx##${prefix}.bam.${bam_index_extension} --write-index" : "${prefix}.bam" + def bam_output = bam_format ? "-a | samtools sort -@ ${task.cpus-1} -o ${bam_index} ${args2}" : "-o ${prefix}.paf" def cigar_paf = cigar_paf_format && !bam_format ? "-c" : '' def set_cigar_bam = cigar_bam && bam_format ? "-L" : '' + def bam_input = "${reads.extension}".matches('sam|bam|cram') + def samtools_reset_fastq = bam_input ? "samtools reset --threads ${task.cpus-1} $args3 $reads | samtools fastq --threads ${task.cpus-1} $args4 |" : '' + def query = bam_input ? "-" : reads + def target = reference ?: (bam_input ? error("BAM input requires reference") : reads) + """ + $samtools_reset_fastq \\ minimap2 \\ $args \\ -t $task.cpus \\ - "${reference ?: reads}" \\ - "$reads" \\ + $target \\ + $query \\ $cigar_paf \\ $set_cigar_bam \\ $bam_output + cat <<-END_VERSIONS > versions.yml + "${task.process}": + minimap2: \$(minimap2 --version 2>&1) + samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def output_file = bam_format ? "${prefix}.bam" : "${prefix}.paf" + def bam_index = bam_index_extension ? "touch ${prefix}.bam.${bam_index_extension}" : "" + def bam_input = "${reads.extension}".matches('sam|bam|cram') + def target = reference ?: (bam_input ? error("BAM input requires reference") : reads) + + """ + touch $output_file + ${bam_index} + cat <<-END_VERSIONS > versions.yml "${task.process}": minimap2: \$(minimap2 --version 2>&1) diff --git a/modules/nf-core/minimap2/align/meta.yml b/modules/nf-core/minimap2/align/meta.yml index 991b39a0..8996f881 100644 --- a/modules/nf-core/minimap2/align/meta.yml +++ b/modules/nf-core/minimap2/align/meta.yml @@ -25,6 +25,11 @@ input: description: | List of input FASTA or FASTQ files of size 1 and 2 for single-end and paired-end data, respectively. + - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test_ref'] - reference: type: file description: | @@ -32,6 +37,9 @@ input: - bam_format: type: boolean description: Specify that output should be in BAM format + - bam_index_extension: + type: string + description: BAM alignment index extension (e.g. "bai") - cigar_paf_format: type: boolean description: Specify that output CIGAR should be in PAF format @@ -54,6 +62,10 @@ output: type: file description: Alignment in BAM format pattern: "*.bam" + - index: + type: file + description: BAM alignment index + pattern: "*.bam.*" - versions: type: file description: File containing software versions @@ -63,3 +75,10 @@ authors: - "@sofstam" - "@sateeshperi" - "@jfy133" + - "@fellen31" +maintainers: + - "@heuermh" + - "@sofstam" + - "@sateeshperi" + - "@jfy133" + - "@fellen31" diff --git a/modules/nf-core/minimap2/align/tests/main.nf.test b/modules/nf-core/minimap2/align/tests/main.nf.test new file mode 100644 index 00000000..4072c171 --- /dev/null +++ b/modules/nf-core/minimap2/align/tests/main.nf.test @@ -0,0 +1,441 @@ +nextflow_process { + + name "Test Process MINIMAP2_ALIGN" + script "../main.nf" + process "MINIMAP2_ALIGN" + + tag "modules" + tag "modules_nfcore" + tag "minimap2" + tag "minimap2/align" + + test("sarscov2 - fastq, fasta, true, [], false, false") { + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, fasta, true, 'bai', false, false") { + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = 'bai' + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + file(process.out.index[0][1]).name, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - [fastq1, fastq2], fasta, true, false, false") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + input[1] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - fastq, [], true, false, false") { + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + [] + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - bam, fasta, true, [], false, false") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - bam, fasta, true, 'bai', false, false") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = 'bai' + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + bam(process.out.bam[0][1]).getHeader(), + bam(process.out.bam[0][1]).getReadsMD5(), + file(process.out.index[0][1]).name, + process.out.versions + ).match() } + ) + } + + } + + test("sarscov2 - bam, [], true, false, false") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + [] + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.failed } + ) + } + + } + + test("sarscov2 - fastq, fasta, true, [], false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fastq, fasta, true, 'bai', false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = 'bai' + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fastq, fasta, false, [], false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ 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] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = false + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - bam, fasta, true, [], false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - bam, fasta, true, 'bai', false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = true + input[3] = 'bai' + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - bam, [], true, false, false - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test3.single_end.markduplicates.sorted.bam', checkIfExists: true) + ] + input[1] = [ + [ id:'test_ref' ], // meta map + [] + ] + input[2] = true + input[3] = [] + input[4] = false + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.failed } + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/minimap2/align/tests/main.nf.test.snap b/modules/nf-core/minimap2/align/tests/main.nf.test.snap new file mode 100644 index 00000000..12264a85 --- /dev/null +++ b/modules/nf-core/minimap2/align/tests/main.nf.test.snap @@ -0,0 +1,476 @@ +{ + "sarscov2 - bam, fasta, true, 'bai', false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:MT192765.1\tLN:29829", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a genome.fasta -", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam##idx##test.bam.bai --write-index" + ], + "5d426b9a5f5b2c54f1d7f1e4c238ae94", + "test.bam.bai", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-25T09:03:00.827260362" + }, + "sarscov2 - bam, fasta, true, 'bai', false, false - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "index": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "paf": [ + + ], + "versions": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:21:37.92353539" + }, + "sarscov2 - fastq, fasta, true, 'bai', false, false - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "index": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "paf": [ + + ], + "versions": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T11:29:44.669021368" + }, + "sarscov2 - fastq, fasta, false, [], false, false - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.paf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ], + "bam": [ + + ], + "index": [ + + ], + "paf": [ + [ + { + "id": "test", + "single_end": true + }, + "test.paf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T11:15:52.738781039" + }, + "sarscov2 - fastq, fasta, true, [], false, false - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "index": [ + + ], + "paf": [ + + ], + "versions": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T11:15:23.033808223" + }, + "sarscov2 - [fastq1, fastq2], fasta, true, false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:MT192765.1\tLN:29829", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a genome.fasta test_1.fastq.gz test_2.fastq.gz", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam" + ], + "1bc392244f228bf52cf0b5a8f6a654c9", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:18:18.964586894" + }, + "sarscov2 - fastq, fasta, true, [], false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:MT192765.1\tLN:29829", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a genome.fasta test_1.fastq.gz", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam" + ], + "f194745c0ccfcb2a9c0aee094a08750", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:17:48.667488325" + }, + "sarscov2 - fastq, fasta, true, 'bai', false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:MT192765.1\tLN:29829", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a genome.fasta test_1.fastq.gz", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam##idx##test.bam.bai --write-index" + ], + "f194745c0ccfcb2a9c0aee094a08750", + "test.bam.bai", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:18:02.517416733" + }, + "sarscov2 - bam, fasta, true, [], false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:MT192765.1\tLN:29829", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a genome.fasta -", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam" + ], + "5d426b9a5f5b2c54f1d7f1e4c238ae94", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-25T09:02:49.64829488" + }, + "sarscov2 - bam, fasta, true, [], false, false - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "index": [ + + ], + "paf": [ + + ], + "versions": [ + "versions.yml:md5,98b8f5f36aa54b82210094f0b0d11938" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:21:22.162291795" + }, + "sarscov2 - fastq, [], true, false, false": { + "content": [ + [ + "@HD\tVN:1.6\tSO:coordinate", + "@SQ\tSN:ERR5069949.2151832\tLN:150", + "@SQ\tSN:ERR5069949.576388\tLN:77", + "@SQ\tSN:ERR5069949.501486\tLN:146", + "@SQ\tSN:ERR5069949.1331889\tLN:132", + "@SQ\tSN:ERR5069949.2161340\tLN:80", + "@SQ\tSN:ERR5069949.973930\tLN:79", + "@SQ\tSN:ERR5069949.2417063\tLN:150", + "@SQ\tSN:ERR5069949.376959\tLN:151", + "@SQ\tSN:ERR5069949.1088785\tLN:149", + "@SQ\tSN:ERR5069949.1066259\tLN:147", + "@SQ\tSN:ERR5069949.2832676\tLN:139", + "@SQ\tSN:ERR5069949.2953930\tLN:151", + "@SQ\tSN:ERR5069949.324865\tLN:151", + "@SQ\tSN:ERR5069949.2185111\tLN:150", + "@SQ\tSN:ERR5069949.937422\tLN:151", + "@SQ\tSN:ERR5069949.2431709\tLN:150", + "@SQ\tSN:ERR5069949.1246538\tLN:148", + "@SQ\tSN:ERR5069949.1189252\tLN:98", + "@SQ\tSN:ERR5069949.2216307\tLN:147", + "@SQ\tSN:ERR5069949.3273002\tLN:148", + "@SQ\tSN:ERR5069949.3277445\tLN:151", + "@SQ\tSN:ERR5069949.3022231\tLN:147", + "@SQ\tSN:ERR5069949.184542\tLN:151", + "@SQ\tSN:ERR5069949.540529\tLN:149", + "@SQ\tSN:ERR5069949.686090\tLN:150", + "@SQ\tSN:ERR5069949.2787556\tLN:106", + "@SQ\tSN:ERR5069949.2650879\tLN:150", + "@SQ\tSN:ERR5069949.2064910\tLN:149", + "@SQ\tSN:ERR5069949.2328704\tLN:150", + "@SQ\tSN:ERR5069949.1067032\tLN:150", + "@SQ\tSN:ERR5069949.3338256\tLN:151", + "@SQ\tSN:ERR5069949.1412839\tLN:147", + "@SQ\tSN:ERR5069949.1538968\tLN:150", + "@SQ\tSN:ERR5069949.147998\tLN:94", + "@SQ\tSN:ERR5069949.366975\tLN:106", + "@SQ\tSN:ERR5069949.1372331\tLN:151", + "@SQ\tSN:ERR5069949.1709367\tLN:129", + "@SQ\tSN:ERR5069949.2388984\tLN:150", + "@SQ\tSN:ERR5069949.1132353\tLN:150", + "@SQ\tSN:ERR5069949.1151736\tLN:151", + "@SQ\tSN:ERR5069949.479807\tLN:150", + "@SQ\tSN:ERR5069949.2176303\tLN:151", + "@SQ\tSN:ERR5069949.2772897\tLN:151", + "@SQ\tSN:ERR5069949.1020777\tLN:122", + "@SQ\tSN:ERR5069949.465452\tLN:151", + "@SQ\tSN:ERR5069949.1704586\tLN:149", + "@SQ\tSN:ERR5069949.1258508\tLN:151", + "@SQ\tSN:ERR5069949.986441\tLN:119", + "@SQ\tSN:ERR5069949.2674295\tLN:148", + "@SQ\tSN:ERR5069949.885966\tLN:79", + "@SQ\tSN:ERR5069949.2342766\tLN:151", + "@SQ\tSN:ERR5069949.3122970\tLN:127", + "@SQ\tSN:ERR5069949.3279513\tLN:72", + "@SQ\tSN:ERR5069949.309410\tLN:151", + "@SQ\tSN:ERR5069949.532979\tLN:149", + "@SQ\tSN:ERR5069949.2888794\tLN:151", + "@SQ\tSN:ERR5069949.2205229\tLN:150", + "@SQ\tSN:ERR5069949.786562\tLN:151", + "@SQ\tSN:ERR5069949.919671\tLN:151", + "@SQ\tSN:ERR5069949.1328186\tLN:151", + "@SQ\tSN:ERR5069949.870926\tLN:149", + "@SQ\tSN:ERR5069949.2257580\tLN:151", + "@SQ\tSN:ERR5069949.3249622\tLN:77", + "@SQ\tSN:ERR5069949.611123\tLN:125", + "@SQ\tSN:ERR5069949.651338\tLN:142", + "@SQ\tSN:ERR5069949.169513\tLN:92", + "@SQ\tSN:ERR5069949.155944\tLN:150", + "@SQ\tSN:ERR5069949.2033605\tLN:150", + "@SQ\tSN:ERR5069949.2730382\tLN:142", + "@SQ\tSN:ERR5069949.2125592\tLN:150", + "@SQ\tSN:ERR5069949.1062611\tLN:151", + "@SQ\tSN:ERR5069949.1778133\tLN:151", + "@SQ\tSN:ERR5069949.3057020\tLN:95", + "@SQ\tSN:ERR5069949.2972968\tLN:141", + "@SQ\tSN:ERR5069949.2734474\tLN:149", + "@SQ\tSN:ERR5069949.856527\tLN:151", + "@SQ\tSN:ERR5069949.2098070\tLN:151", + "@SQ\tSN:ERR5069949.1552198\tLN:150", + "@SQ\tSN:ERR5069949.2385514\tLN:150", + "@SQ\tSN:ERR5069949.2270078\tLN:151", + "@SQ\tSN:ERR5069949.114870\tLN:150", + "@SQ\tSN:ERR5069949.2668880\tLN:147", + "@SQ\tSN:ERR5069949.257821\tLN:139", + "@SQ\tSN:ERR5069949.2243023\tLN:150", + "@SQ\tSN:ERR5069949.2605155\tLN:146", + "@SQ\tSN:ERR5069949.1340552\tLN:151", + "@SQ\tSN:ERR5069949.1561137\tLN:150", + "@SQ\tSN:ERR5069949.2361683\tLN:149", + "@SQ\tSN:ERR5069949.2521353\tLN:150", + "@SQ\tSN:ERR5069949.1261808\tLN:149", + "@SQ\tSN:ERR5069949.2734873\tLN:98", + "@SQ\tSN:ERR5069949.3017828\tLN:107", + "@SQ\tSN:ERR5069949.573706\tLN:150", + "@SQ\tSN:ERR5069949.1980512\tLN:151", + "@SQ\tSN:ERR5069949.1014693\tLN:150", + "@SQ\tSN:ERR5069949.3184655\tLN:150", + "@SQ\tSN:ERR5069949.29668\tLN:89", + "@SQ\tSN:ERR5069949.3258358\tLN:151", + "@SQ\tSN:ERR5069949.1476386\tLN:151", + "@SQ\tSN:ERR5069949.2415814\tLN:150", + "@PG\tID:minimap2\tPN:minimap2\tVN:2.28-r1209\tCL:minimap2 -t 2 -a test_1.fastq.gz test_1.fastq.gz", + "@PG\tID:samtools\tPN:samtools\tPP:minimap2\tVN:1.20\tCL:samtools sort -@ 1 -o test.bam" + ], + "16c1c651f8ec67383bcdee3c55aed94f", + [ + "versions.yml:md5,3548eeba9066efbf8d78ea99f8d813fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-23T11:18:34.246998277" + } +} \ No newline at end of file diff --git a/modules/nf-core/minimap2/align/tests/tags.yml b/modules/nf-core/minimap2/align/tests/tags.yml new file mode 100644 index 00000000..39dba374 --- /dev/null +++ b/modules/nf-core/minimap2/align/tests/tags.yml @@ -0,0 +1,2 @@ +minimap2/align: + - "modules/nf-core/minimap2/align/**" diff --git a/modules/nf-core/minimap2/index/environment.yml b/modules/nf-core/minimap2/index/environment.yml new file mode 100644 index 00000000..d1c1b471 --- /dev/null +++ b/modules/nf-core/minimap2/index/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::minimap2=2.28 diff --git a/modules/nf-core/minimap2/index/main.nf b/modules/nf-core/minimap2/index/main.nf index 7a1bb227..38320214 100644 --- a/modules/nf-core/minimap2/index/main.nf +++ b/modules/nf-core/minimap2/index/main.nf @@ -1,11 +1,11 @@ process MINIMAP2_INDEX { - label 'process_medium' + label 'process_low' // Note: the versions here need to match the versions used in minimap2/align - conda "bioconda::minimap2=2.24" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/minimap2:2.24--h7132678_1' : - 'biocontainers/minimap2:2.24--h7132678_1' }" + 'https://depot.galaxyproject.org/singularity/minimap2:2.28--he4a0461_0' : + 'biocontainers/minimap2:2.28--he4a0461_0' }" input: tuple val(meta), path(fasta) @@ -31,4 +31,14 @@ process MINIMAP2_INDEX { minimap2: \$(minimap2 --version 2>&1) END_VERSIONS """ + + stub: + """ + touch ${fasta.baseName}.mmi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + minimap2: \$(minimap2 --version 2>&1) + END_VERSIONS + """ } diff --git a/modules/nf-core/minimap2/index/meta.yml b/modules/nf-core/minimap2/index/meta.yml index b58f35c6..1d29e3f2 100644 --- a/modules/nf-core/minimap2/index/meta.yml +++ b/modules/nf-core/minimap2/index/meta.yml @@ -38,3 +38,6 @@ output: authors: - "@yuukiiwa" - "@drpatelh" +maintainers: + - "@yuukiiwa" + - "@drpatelh" diff --git a/modules/nf-core/minimap2/index/tests/main.nf.test b/modules/nf-core/minimap2/index/tests/main.nf.test new file mode 100644 index 00000000..97840ff7 --- /dev/null +++ b/modules/nf-core/minimap2/index/tests/main.nf.test @@ -0,0 +1,32 @@ +nextflow_process { + + name "Test Process MINIMAP2_INDEX" + script "../main.nf" + process "MINIMAP2_INDEX" + + tag "modules" + tag "modules_nfcore" + tag "minimap2" + tag "minimap2/index" + + test("minimap2 index") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/minimap2/index/tests/main.nf.test.snap b/modules/nf-core/minimap2/index/tests/main.nf.test.snap new file mode 100644 index 00000000..0b098828 --- /dev/null +++ b/modules/nf-core/minimap2/index/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "Should run without failures": { + "content": [ + { + "0": [ + [ + { + "id": "test_ref" + }, + "genome.mmi:md5,72e450f12dc691e763c697463bdb1571" + ] + ], + "1": [ + "versions.yml:md5,0fced0ee8015e7f50b82566e3db8f7b0" + ], + "index": [ + [ + { + "id": "test_ref" + }, + "genome.mmi:md5,72e450f12dc691e763c697463bdb1571" + ] + ], + "versions": [ + "versions.yml:md5,0fced0ee8015e7f50b82566e3db8f7b0" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-03-18T11:46:30.000058092" + }, + "minimap2 index": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "genome.mmi:md5,72e450f12dc691e763c697463bdb1571" + ] + ], + "1": [ + "versions.yml:md5,2f8340380c6741e9261a284262a90bde" + ], + "index": [ + [ + { + "id": "test" + }, + "genome.mmi:md5,72e450f12dc691e763c697463bdb1571" + ] + ], + "versions": [ + "versions.yml:md5,2f8340380c6741e9261a284262a90bde" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-05T10:58:29.828187662" + } +} \ No newline at end of file diff --git a/modules/nf-core/minimap2/index/tests/tags.yml b/modules/nf-core/minimap2/index/tests/tags.yml new file mode 100644 index 00000000..e5ef8e19 --- /dev/null +++ b/modules/nf-core/minimap2/index/tests/tags.yml @@ -0,0 +1,2 @@ +minimap2/index: + - modules/nf-core/minimap2/index/** diff --git a/modules/nf-core/motus/merge/environment.yml b/modules/nf-core/motus/merge/environment.yml new file mode 100644 index 00000000..736a527e --- /dev/null +++ b/modules/nf-core/motus/merge/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::motus=3.0.3 diff --git a/modules/nf-core/motus/merge/main.nf b/modules/nf-core/motus/merge/main.nf index adc60dc8..06cb93cc 100644 --- a/modules/nf-core/motus/merge/main.nf +++ b/modules/nf-core/motus/merge/main.nf @@ -2,7 +2,7 @@ process MOTUS_MERGE { tag "$meta.id" label 'process_single' - conda "bioconda::motus=3.0.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/motus:3.0.3--pyhdfd78af_0': 'biocontainers/motus:3.0.3--pyhdfd78af_0' }" diff --git a/modules/nf-core/motus/merge/meta.yml b/modules/nf-core/motus/merge/meta.yml index 24ae9399..0d7af231 100644 --- a/modules/nf-core/motus/merge/meta.yml +++ b/modules/nf-core/motus/merge/meta.yml @@ -15,8 +15,7 @@ tools: documentation: "https://github.com/motu-tool/mOTUs/wiki" tool_dev_url: "https://github.com/motu-tool/mOTUs" doi: "10.1186/s40168-022-01410-z" - licence: "['GPL v3']" - + licence: ["GPL v3"] input: - input: type: file @@ -35,7 +34,6 @@ input: this itself without having the motus database present and configured with the tool so here we take it from what is already reported by the upstream module. pattern: "versions.yml" - output: - versions: type: file @@ -49,6 +47,7 @@ output: type: file description: OTU table in biom format, if BIOM format requested pattern: "*.biom" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/motus/profile/environment.yml b/modules/nf-core/motus/profile/environment.yml new file mode 100644 index 00000000..b8ef520e --- /dev/null +++ b/modules/nf-core/motus/profile/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::motus=3.1.0 diff --git a/modules/nf-core/motus/profile/main.nf b/modules/nf-core/motus/profile/main.nf index ca61865a..ecb15f9b 100644 --- a/modules/nf-core/motus/profile/main.nf +++ b/modules/nf-core/motus/profile/main.nf @@ -2,10 +2,10 @@ process MOTUS_PROFILE { tag "$meta.id" label 'process_medium' - conda "bioconda::motus=3.0.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/motus:3.0.3--pyhdfd78af_0': - 'biocontainers/motus:3.0.3--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/motus:3.1.0--pyhdfd78af_0': + 'biocontainers/motus:3.1.0--pyhdfd78af_0' }" input: tuple val(meta), path(reads) @@ -38,7 +38,7 @@ process MOTUS_PROFILE { -t $task.cpus \\ -n $prefix \\ -o ${prefix}.out \\ - 2> ${prefix}.log + 2> >(tee ${prefix}.log >&2) ## mOTUs version number is not available from command line. ## mOTUs save the version number in index database folder. @@ -53,4 +53,28 @@ process MOTUS_PROFILE { motus: \$VERSION END_VERSIONS """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def inputs = reads[0].getExtension() == 'bam' ? + "-i ${reads}" : + reads[0].getExtension() == 'mgc' ? "-m $reads" : + meta.single_end ? + "-s $reads" : "-f ${reads[0]} -r ${reads[1]}" + def refdb = db ? "-db ${db}" : "" + """ + touch ${prefix}.out + touch ${prefix}.log + + if [ "$db" == "" ]; then + VERSION=\$(echo \$(motus -h 2>&1) | sed 's/^.*Version: //; s/References.*\$//') + else + VERSION=\$(grep motus $db/db_mOTU_versions | sed 's/motus\\t//g') + fi + cat <<-END_VERSIONS > versions.yml + "${task.process}": + motus: \$VERSION + END_VERSIONS + """ } diff --git a/modules/nf-core/motus/profile/meta.yml b/modules/nf-core/motus/profile/meta.yml index 12020425..d6fffebc 100644 --- a/modules/nf-core/motus/profile/meta.yml +++ b/modules/nf-core/motus/profile/meta.yml @@ -12,8 +12,7 @@ tools: documentation: "https://github.com/motu-tool/mOTUs/wiki" tool_dev_url: "https://github.com/motu-tool/mOTUs" doi: "10.1186/s40168-022-01410-z" - licence: "['GPL v3']" - + licence: ["GPL v3"] input: - meta: type: map @@ -33,7 +32,6 @@ input: type: directory description: | mOTUs database downloaded by `motus downloadDB` - output: - meta: type: map @@ -60,6 +58,7 @@ output: type: file description: Standard error logging file containing summary statistics pattern: "*.log" - authors: - "@jianhong" +maintainers: + - "@jianhong" diff --git a/modules/nf-core/motus/profile/tests/main.nf.test b/modules/nf-core/motus/profile/tests/main.nf.test new file mode 100644 index 00000000..b0f04108 --- /dev/null +++ b/modules/nf-core/motus/profile/tests/main.nf.test @@ -0,0 +1,167 @@ +nextflow_process { + name "Test Process MOTUS_PROFILE" + script "../main.nf" + process "MOTUS_PROFILE" + tag "modules" + tag "modules_nfcore" + tag "motus" + tag "motus/downloaddb" + tag "motus/profile" + + + test("sarscov2 - illumina paired end [fastq]") { + + setup { + run("MOTUS_DOWNLOADDB") { + script "modules/nf-core/motus/downloaddb/main.nf" + process { + """ + input[0] = Channel.of([ + file('https://raw.githubusercontent.com/motu-tool/mOTUs/master/motus/downloadDB.py') + ]) + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true ), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true ) + ] + ] + input[1] = MOTUS_DOWNLOADDB.out.db + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.out[0][1]).readLines()[3..10], + path(process.out.log[0][1]).readLines().last().contains('Reads are filtered for'), + process.out.versions, + ).match() + } + ) + } + } + + test("sarscov2 - illumina paired end [bam]") { + + setup { + run("MOTUS_DOWNLOADDB") { + script "modules/nf-core/motus/downloaddb/main.nf" + process { + """ + input[0] = Channel.of([ + file('https://raw.githubusercontent.com/motu-tool/mOTUs/master/motus/downloadDB.py') + ]) + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true )] + input[1] = MOTUS_DOWNLOADDB.out.db + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.out[0][1]).readLines()[3..10], + path(process.out.log[0][1]).readLines().last().contains('Reads are filtered for'), + process.out.versions + ).match() + } + ) + } + } + + test("sarscov2 - illumina single end [fastq] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ 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] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } + + test("sarscov2 - illumina paired end [fastq] - 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 ), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true ) + ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } + + test("sarscov2 - illumina paired end [bam] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file( params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true )] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( process.out ).match() } + ) + } + } +} diff --git a/modules/nf-core/motus/profile/tests/main.nf.test.snap b/modules/nf-core/motus/profile/tests/main.nf.test.snap new file mode 100644 index 00000000..638885a2 --- /dev/null +++ b/modules/nf-core/motus/profile/tests/main.nf.test.snap @@ -0,0 +1,243 @@ +{ + "sarscov2 - illumina paired end [fastq]": { + "content": [ + [ + "Leptospira alexanderi [ref_mOTU_v31_00001]\t0.0000000000", + "Leptospira weilii [ref_mOTU_v31_00002]\t0.0000000000", + "Chryseobacterium sp. [ref_mOTU_v31_00004]\t0.0000000000", + "Chryseobacterium gallinarum [ref_mOTU_v31_00005]\t0.0000000000", + "Chryseobacterium indologenes [ref_mOTU_v31_00006]\t0.0000000000", + "Chryseobacterium artocarpi/ureilyticum [ref_mOTU_v31_00007]\t0.0000000000", + "Chryseobacterium jejuense [ref_mOTU_v31_00008]\t0.0000000000", + "Chryseobacterium sp. G972 [ref_mOTU_v31_00009]\t0.0000000000" + ], + false, + [ + "versions.yml:md5,0119e45bb894d3205c32fffc0c895d3c" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-09-04T12:54:13.029947" + }, + "sarscov2 - illumina paired end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ], + "bam": [ + + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "mgc": [ + + ], + "out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T07:44:34.702236603" + }, + "sarscov2 - illumina paired end [bam]": { + "content": [ + [ + "Leptospira alexanderi [ref_mOTU_v31_00001]\t0.0000000000", + "Leptospira weilii [ref_mOTU_v31_00002]\t0.0000000000", + "Chryseobacterium sp. [ref_mOTU_v31_00004]\t0.0000000000", + "Chryseobacterium gallinarum [ref_mOTU_v31_00005]\t0.0000000000", + "Chryseobacterium indologenes [ref_mOTU_v31_00006]\t0.0000000000", + "Chryseobacterium artocarpi/ureilyticum [ref_mOTU_v31_00007]\t0.0000000000", + "Chryseobacterium jejuense [ref_mOTU_v31_00008]\t0.0000000000", + "Chryseobacterium sp. G972 [ref_mOTU_v31_00009]\t0.0000000000" + ], + false, + [ + "versions.yml:md5,0119e45bb894d3205c32fffc0c895d3c" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-09-04T12:56:30.49163" + }, + "sarscov2 - illumina single end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ], + "bam": [ + + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "mgc": [ + + ], + "out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T07:44:23.635734599" + }, + "sarscov2 - illumina paired end [bam] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ], + "bam": [ + + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "mgc": [ + + ], + "out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,361e07d24e9faf2fc49f5c3f4e718517" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T07:44:44.53280646" + } +} \ No newline at end of file diff --git a/modules/nf-core/motus/profile/tests/tags.yml b/modules/nf-core/motus/profile/tests/tags.yml new file mode 100644 index 00000000..723998c8 --- /dev/null +++ b/modules/nf-core/motus/profile/tests/tags.yml @@ -0,0 +1,2 @@ +motus/profile: + - modules/nf-core/motus/profile/** diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index ca39fb67..f1cd99b0 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -1,7 +1,5 @@ -name: multiqc channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::multiqc=1.21 + - bioconda::multiqc=1.24.1 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 47ac352f..ceaec139 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -3,14 +3,16 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.21--pyhdfd78af_0' : - 'biocontainers/multiqc:1.21--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.24.1--pyhdfd78af_0' : + 'biocontainers/multiqc:1.24.1--pyhdfd78af_0' }" input: path multiqc_files, stageAs: "?/*" path(multiqc_config) path(extra_multiqc_config) path(multiqc_logo) + path(replace_names) + path(sample_names) output: path "*multiqc_report.html", emit: report @@ -23,16 +25,22 @@ process MULTIQC { script: def args = task.ext.args ?: '' + def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' def config = multiqc_config ? "--config $multiqc_config" : '' def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' - def logo = multiqc_logo ? /--cl-config 'custom_logo: "${multiqc_logo}"'/ : '' + def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' + def replace = replace_names ? "--replace-names ${replace_names}" : '' + def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ $args \\ $config \\ + $prefix \\ $extra_config \\ $logo \\ + $replace \\ + $samples \\ . cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 45a9bc35..382c08cb 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -29,6 +29,19 @@ input: type: file description: Optional logo file for MultiQC pattern: "*.{png}" + - replace_names: + type: file + description: | + Optional two-column sample renaming file. First column a set of + patterns, second column a set of corresponding replacements. Passed via + MultiQC's `--replace-names` option. + pattern: "*.{tsv}" + - sample_names: + type: file + description: | + Optional TSV file with headers, passed to the MultiQC --sample_names + argument. + pattern: "*.{tsv}" output: - report: type: file diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test index f1c4242e..33316a7d 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test +++ b/modules/nf-core/multiqc/tests/main.nf.test @@ -8,6 +8,8 @@ nextflow_process { tag "modules_nfcore" tag "multiqc" + config "./nextflow.config" + test("sarscov2 single-end [fastqc]") { when { @@ -17,6 +19,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -41,6 +45,8 @@ nextflow_process { input[1] = Channel.of(file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true)) input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -66,6 +72,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index bfebd802..83fa080c 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -2,14 +2,14 @@ "multiqc_versions_single": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,6eb13f3b11bbcbfc98ad3166420ff760" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:48:55.657331" + "timestamp": "2024-07-10T12:41:34.562023" }, "multiqc_stub": { "content": [ @@ -17,25 +17,25 @@ "multiqc_report.html", "multiqc_data", "multiqc_plots", - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,6eb13f3b11bbcbfc98ad3166420ff760" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:49:49.071937" + "timestamp": "2024-07-10T11:27:11.933869532" }, "multiqc_versions_config": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,6eb13f3b11bbcbfc98ad3166420ff760" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:49:25.457567" + "timestamp": "2024-07-10T11:26:56.709849369" } -} \ No newline at end of file +} diff --git a/modules/nf-core/multiqc/tests/nextflow.config b/modules/nf-core/multiqc/tests/nextflow.config new file mode 100644 index 00000000..c537a6a3 --- /dev/null +++ b/modules/nf-core/multiqc/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'MULTIQC' { + ext.prefix = null + } +} diff --git a/modules/nf-core/nanoq/environment.yml b/modules/nf-core/nanoq/environment.yml new file mode 100644 index 00000000..1a95d24e --- /dev/null +++ b/modules/nf-core/nanoq/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::nanoq=0.10.0" diff --git a/modules/nf-core/nanoq/main.nf b/modules/nf-core/nanoq/main.nf new file mode 100644 index 00000000..6d35a407 --- /dev/null +++ b/modules/nf-core/nanoq/main.nf @@ -0,0 +1,49 @@ +process NANOQ { + 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/nanoq:0.10.0--h031d066_2' : + 'biocontainers/nanoq:0.10.0--h031d066_2'}" + + input: + tuple val(meta), path(ontreads) + val(output_format) //One of the following: fastq, fastq.gz, fastq.bz2, fastq.lzma, fasta, fasta.gz, fasta.bz2, fasta.lzma. + + output: + tuple val(meta), path("*.{stats,json}") , emit: stats + tuple val(meta), path("*_filtered.${output_format}") , emit: reads + 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}_filtered" + """ + nanoq -i $ontreads \\ + ${args} \\ + -r ${prefix}.stats \\ + -o ${prefix}.$output_format + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nanoq: \$(nanoq --version | sed -e 's/nanoq //g') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}_filtered" + """ + echo "" | gzip > ${prefix}.$output_format + touch ${prefix}.stats + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nanoq: \$(nanoq --version | sed -e 's/nanoq //g') + END_VERSIONS + """ +} diff --git a/modules/nf-core/nanoq/meta.yml b/modules/nf-core/nanoq/meta.yml new file mode 100644 index 00000000..85c0c978 --- /dev/null +++ b/modules/nf-core/nanoq/meta.yml @@ -0,0 +1,60 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "nanoq" +description: Nanoq implements ultra-fast read filters and summary reports for high-throughput nanopore reads. +keywords: + - nanoq + - Read filters + - Read trimming + - Read report +tools: + - "nanoq": + description: "Ultra-fast quality control and summary reports for nanopore reads" + homepage: "https://github.com/esteinig/nanoq" + documentation: "https://github.com/esteinig/nanoq" + tool_dev_url: "https://github.com/esteinig/nanoq" + doi: "10.21105/joss.02991" + licence: ["MIT"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + + - ontreads: + type: file + description: Compressed or uncompressed nanopore reads in fasta or fastq formats. + pattern: "*.{fa,fna,faa,fasta,fq,fastq}{,.gz,.bz2,.xz}" + + - output_format: + type: string + description: "Specifies the output format. One of these formats: fasta, fastq; fasta.gz, fastq.gz; fasta.bz2, fastq.bz2; fasta.lzma, fastq.lzma." + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + + - stats: + type: file + description: Summary report of reads statistics. + pattern: "*.{stats,json}" + + - reads: + type: file + description: Filtered reads. + pattern: "*.{fasta,fastq}{,.gz,.bz2,.lzma}" + + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@LilyAnderssonLee" +maintainers: + - "@LilyAnderssonLee" diff --git a/modules/nf-core/nanoq/tests/main.nf.test b/modules/nf-core/nanoq/tests/main.nf.test new file mode 100644 index 00000000..ef63d12f --- /dev/null +++ b/modules/nf-core/nanoq/tests/main.nf.test @@ -0,0 +1,122 @@ +nextflow_process { + + name "Test Process NANOQ" + script "../main.nf" + process "NANOQ" + + tag "modules" + tag "modules_nfcore" + tag "nanoq" + + test("sarscov2 - nanopore_uncompressed") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + + input[1] = 'fastq' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 - nanopore_compressed_gz") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq.gz' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("sarscov2 - nanopore_compressed_bz2") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq.bz2' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("sarscov2 - nanopore_compressed_lzma") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq.lzma' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 - nanopore_compressed_gz - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq.gz' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } +} diff --git a/modules/nf-core/nanoq/tests/main.nf.test.snap b/modules/nf-core/nanoq/tests/main.nf.test.snap new file mode 100644 index 00000000..b5dda2a7 --- /dev/null +++ b/modules/nf-core/nanoq/tests/main.nf.test.snap @@ -0,0 +1,267 @@ +{ + "sarscov2 - nanopore_compressed_gz": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.gz:md5,7567d853ada6ac142332619d0b541d76" + ] + ], + "2": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.gz:md5,7567d853ada6ac142332619d0b541d76" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "versions": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-11T11:39:32.117229" + }, + "sarscov2 - nanopore_compressed_gz - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "2": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-11T11:42:06.039307" + }, + "sarscov2 - nanopore_compressed_bz2": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.bz2:md5,b53cf14fd4eb5b16c459c41f03cc8a4b" + ] + ], + "2": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.bz2:md5,b53cf14fd4eb5b16c459c41f03cc8a4b" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "versions": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-11T11:39:36.674647" + }, + "sarscov2 - nanopore_compressed_lzma": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.lzma:md5,65dda701689f913734dc245b68c89e07" + ] + ], + "2": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq.lzma:md5,65dda701689f913734dc245b68c89e07" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "versions": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-11T11:39:41.51344" + }, + "sarscov2 - nanopore_uncompressed": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq:md5,7567d853ada6ac142332619d0b541d76" + ] + ], + "2": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.fastq:md5,7567d853ada6ac142332619d0b541d76" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test_filtered.stats:md5,5ab32af3352dfeca8268e10edf6e4dbe" + ] + ], + "versions": [ + "versions.yml:md5,7a40efe417ff7dbb9e91e9c1629a04e6" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-11T11:39:26.868897" + } +} \ No newline at end of file diff --git a/modules/nf-core/nanoq/tests/tags.yml b/modules/nf-core/nanoq/tests/tags.yml new file mode 100644 index 00000000..37457df1 --- /dev/null +++ b/modules/nf-core/nanoq/tests/tags.yml @@ -0,0 +1,2 @@ +nanoq: + - "modules/nf-core/nanoq/**" diff --git a/modules/nf-core/nonpareil/curve/environment.yml b/modules/nf-core/nonpareil/curve/environment.yml new file mode 100644 index 00000000..89d5aa6e --- /dev/null +++ b/modules/nf-core/nonpareil/curve/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::nonpareil=3.5.5 diff --git a/modules/nf-core/nonpareil/curve/main.nf b/modules/nf-core/nonpareil/curve/main.nf new file mode 100644 index 00000000..dbe56b26 --- /dev/null +++ b/modules/nf-core/nonpareil/curve/main.nf @@ -0,0 +1,51 @@ +process NONPAREIL_CURVE { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/nonpareil:3.5.5--r43hdcf5f25_0': + 'biocontainers/nonpareil:3.5.5--r43hdcf5f25_0' }" + + input: + tuple val(meta), path(npo) + + output: + tuple val(meta), path("*.png"), emit: png + 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 args_cmd = args != '' ? ", ${args}" : "" + """ + #!/usr/bin/env Rscript + library(Nonpareil) + + png(file='${prefix}.png') + Nonpareil.curve('${npo}'${args_cmd}) + dev.off() + + version_file_path <- "versions.yml" + version_nonpareil <- paste(unlist(packageVersion("Nonpareil")), collapse = ".") + f <- file(version_file_path, "w") + writeLines('"${task.process}":', f) + writeLines(" nonpareil: ", f, sep = "") + writeLines(version_nonpareil, f) + close(f) + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.png + + cat <<-END_VERSIONS > versions.yml + "${task.process}": \$(Rscript -e 'library('Nonpareil'); cat(paste(unlist(packageVersion("Nonpareil")),collapse="."))') + END_VERSIONS + """ +} diff --git a/modules/nf-core/nonpareil/curve/meta.yml b/modules/nf-core/nonpareil/curve/meta.yml new file mode 100644 index 00000000..87aaa363 --- /dev/null +++ b/modules/nf-core/nonpareil/curve/meta.yml @@ -0,0 +1,48 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +name: "nonpareil_curve" +description: Visualise metagenome redundancy curve in PNG format from a single Nonpareil npo file +keywords: + - metagenomics + - statistics + - coverage + - complexity + - redundancy + - diversity + - visualisation +tools: + - "nonpareil": + description: "Estimate average coverage and create curves for metagenomic datasets" + homepage: "https://github.com/lmrodriguezr/nonpareil" + documentation: "https://nonpareil.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/lmrodriguezr/nonpareil" + doi: "10.1128/msystems.00039-" + licence: ["Artistic License 2.0"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - npo: + type: file + description: Single npo redundancy summary file from nonpareil itself + pattern: "*.npo" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - png: + type: file + description: PNG file of the Nonpareil curve + pattern: "*.png" +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/nonpareil/curve/tests/main.nf.test b/modules/nf-core/nonpareil/curve/tests/main.nf.test new file mode 100644 index 00000000..ee6a16d5 --- /dev/null +++ b/modules/nf-core/nonpareil/curve/tests/main.nf.test @@ -0,0 +1,76 @@ +nextflow_process { + + name "Test Process NONPAREIL_CURVE" + script "../main.nf" + process "NONPAREIL_CURVE" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "nonpareil" + tag "nonpareil/curve" + tag "nonpareil/nonpareil" + + setup { + run("NONPAREIL_NONPAREIL") { + script "../../../nonpareil/nonpareil/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + } + + test("candidatus_portiera_aleyrodidarum") { + + when { + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.versions, + file(process.out.png[0][1]).name, + ).match() + } + ) + } + + } + + test("candidatus_portiera_aleyrodidarum - stub") { + + options "-stub" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/nonpareil/curve/tests/main.nf.test.snap b/modules/nf-core/nonpareil/curve/tests/main.nf.test.snap new file mode 100644 index 00000000..29625d71 --- /dev/null +++ b/modules/nf-core/nonpareil/curve/tests/main.nf.test.snap @@ -0,0 +1,50 @@ +{ + "candidatus_portiera_aleyrodidarum": { + "content": [ + [ + "versions.yml:md5,591a0a74569106b79c101d0059a822ad" + ], + "test.png" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T12:11:37.549218924" + }, + "candidatus_portiera_aleyrodidarum - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,ea8a60928f2d6fb3fe8895b63fba42f4" + ], + "png": [ + [ + { + "id": "test", + "single_end": false + }, + "test.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,ea8a60928f2d6fb3fe8895b63fba42f4" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T14:32:21.066752297" + } +} \ No newline at end of file diff --git a/modules/nf-core/nonpareil/curve/tests/nextflow.config b/modules/nf-core/nonpareil/curve/tests/nextflow.config new file mode 100644 index 00000000..d30ead9c --- /dev/null +++ b/modules/nf-core/nonpareil/curve/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: NONPAREIL_NONPAREIL { + ext.args = '-X 100' + } + + withName: NONPAREIL_CURVE { + ext.args = "col = 'green'" + } + +} diff --git a/modules/nf-core/nonpareil/curve/tests/tags.yml b/modules/nf-core/nonpareil/curve/tests/tags.yml new file mode 100644 index 00000000..b60cd0ec --- /dev/null +++ b/modules/nf-core/nonpareil/curve/tests/tags.yml @@ -0,0 +1,2 @@ +nonpareil/curve: + - modules/nf-core/nonpareil/curve/** diff --git a/modules/nf-core/nonpareil/nonpareil/environment.yml b/modules/nf-core/nonpareil/nonpareil/environment.yml new file mode 100644 index 00000000..89d5aa6e --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::nonpareil=3.5.5 diff --git a/modules/nf-core/nonpareil/nonpareil/main.nf b/modules/nf-core/nonpareil/nonpareil/main.nf new file mode 100644 index 00000000..5c05649b --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/main.nf @@ -0,0 +1,59 @@ +process NONPAREIL_NONPAREIL { + 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/nonpareil:3.5.5--r43hdcf5f25_0': + 'biocontainers/nonpareil:3.5.5--r43hdcf5f25_0' }" + + input: + tuple val(meta), path(reads) + val format + val mode + + output: + tuple val(meta), path("*.npa"), emit: npa + tuple val(meta), path("*.npc"), emit: npc + tuple val(meta), path("*.npl"), emit: npl + tuple val(meta), path("*.npo"), emit: npo + 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 mem_mb = task.memory.toMega() + """ + nonpareil \\ + -s $reads \\ + -f $format \\ + -T ${mode} \\ + -t $task.cpus \\ + -R ${mem_mb} \\ + -b $prefix \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nonpareil: \$(echo \$(nonpareil -V 2>&1) | sed 's/Nonpareil v//' ) + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.npa + touch ${prefix}.npc + touch ${prefix}.npl + touch ${prefix}.npo + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nonpareil: \$(echo \$(nonpareil -V 2>&1) | sed 's/Nonpareil v//' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/nonpareil/nonpareil/meta.yml b/modules/nf-core/nonpareil/nonpareil/meta.yml new file mode 100644 index 00000000..59f8bc05 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/meta.yml @@ -0,0 +1,67 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +name: "nonpareil_nonpareil" +description: Calculate metagenome redundancy curve from FASTQ files +keywords: + - metagenomics + - statistics + - coverage + - redundancy + - diversity + - complexity +tools: + - "nonpareil": + description: "Estimate average coverage and create curves for metagenomic datasets" + homepage: "https://github.com/lmrodriguezr/nonpareil" + documentation: "https://nonpareil.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/lmrodriguezr/nonpareil" + doi: "10.1128/msystems.00039-" + licence: ["Artistic License 2.0"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - reads: + type: file + description: FASTQ or FASTA file (ideally uncompressed, but not required) + pattern: "*.{fasta,fna,fas,fa,fastq,fq,fasta.gz,fna.gz,fas.gz,fa.gz,fastq.gz,fq.gz}" + - format: + type: string + description: File format of input file + pattern: "fasta|fastq" + - mode: + type: string + description: Mode of redundancy estimation + pattern: "kmer|alignment" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - npa: + type: file + description: Raw redundancy values + pattern: "*.npa" + - npc: + type: file + description: Mates distribution file + pattern: "*.npc" + - npl: + type: file + description: Log file + pattern: "*.npl" + - npo: + type: file + description: Redundancy summary file + pattern: "*.npo" +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test b/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test new file mode 100644 index 00000000..be4e2b3f --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test @@ -0,0 +1,114 @@ +nextflow_process { + + name "Test Process NONPAREIL_NONPAREIL" + script "../main.nf" + process "NONPAREIL_NONPAREIL" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "nonpareil" + tag "nonpareil/nonpareil" + tag "gunzip" + + test("candidatus_portiera_aleyrodidarum - gzipped") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.npa[0][1]).name, + file(process.out.npc[0][1]).name, + path(process.out.npo[0][1]).readLines()[0], + path(process.out.npl[0][1]).readLines().last().contains("Everything seems correct"), + process.out.versions + ).match() + } + ) + } + + } + + test("candidatus_portiera_aleyrodidarum - uncompressed") { + + + setup { + run("GUNZIP") { + script "../../../gunzip/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + input[0] = GUNZIP.out.gunzip + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.npa[0][1]).name, + file(process.out.npc[0][1]).name, + path(process.out.npo[0][1]).readLines()[0], + path(process.out.npl[0][1]).readLines().last().contains("Everything seems correct"), + process.out.versions + ).match() + } + ) + } + + } + +test("candidatus_portiera_aleyrodidarum - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + +} diff --git a/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test.snap b/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test.snap new file mode 100644 index 00000000..14f2ad73 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/tests/main.nf.test.snap @@ -0,0 +1,123 @@ +{ + "candidatus_portiera_aleyrodidarum - uncompressed": { + "content": [ + "test.npa", + "test.npc", + "# @impl: Nonpareil", + true, + [ + "versions.yml:md5,5a5e1b70e05a4637015adbfaeac017fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T14:11:57.001694911" + }, + "candidatus_portiera_aleyrodidarum - gzipped": { + "content": [ + "test.npa", + "test.npc", + "# @impl: Nonpareil", + true, + [ + "versions.yml:md5,5a5e1b70e05a4637015adbfaeac017fd" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T14:11:49.888813434" + }, + "candidatus_portiera_aleyrodidarum - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npc:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npo:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,5a5e1b70e05a4637015adbfaeac017fd" + ], + "npa": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "npc": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npc:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "npl": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npl:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "npo": [ + [ + { + "id": "test", + "single_end": false + }, + "test.npo:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,5a5e1b70e05a4637015adbfaeac017fd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T14:38:09.784957219" + } +} \ No newline at end of file diff --git a/modules/nf-core/nonpareil/nonpareil/tests/nextflow.config b/modules/nf-core/nonpareil/nonpareil/tests/nextflow.config new file mode 100644 index 00000000..3dfce831 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/tests/nextflow.config @@ -0,0 +1,9 @@ +process { + + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + + withName: NONPAREIL_NONPAREIL { + ext.args = '-X 100' + } + +} diff --git a/modules/nf-core/nonpareil/nonpareil/tests/tags.yml b/modules/nf-core/nonpareil/nonpareil/tests/tags.yml new file mode 100644 index 00000000..f20ff56f --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareil/tests/tags.yml @@ -0,0 +1,2 @@ +nonpareil/nonpareil: + - modules/nf-core/nonpareil/nonpareil/** diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/environment.yml b/modules/nf-core/nonpareil/nonpareilcurvesr/environment.yml new file mode 100644 index 00000000..78bc8437 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/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::nonpareil=3.5.5" diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/main.nf b/modules/nf-core/nonpareil/nonpareilcurvesr/main.nf new file mode 100644 index 00000000..08d0c487 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/main.nf @@ -0,0 +1,57 @@ +process NONPAREIL_NONPAREILCURVESR { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/nonpareil:3.5.5--r43hdcf5f25_0': + 'biocontainers/nonpareil:3.5.5--r43hdcf5f25_0' }" + + input: + tuple val(meta), path(npos) + + output: + tuple val(meta), path("*.json"), emit: json, optional: true + tuple val(meta), path("*.tsv" ), emit: tsv , optional: true + tuple val(meta), path("*.csv" ), emit: csv , optional: true + tuple val(meta), path("*.pdf" ), emit: pdf , optional: true + + 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}" + + """ + NonpareilCurves.R \\ + $args \\ + --json ${prefix}.json \\ + --tsv ${prefix}.tsv \\ + --csv ${prefix}.csv \\ + --pdf ${prefix}.pdf \\ + $npos + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nonpareil: \$(echo \$(nonpareil -V 2>&1) | sed 's/Nonpareil v//' ) + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.json + touch ${prefix}.tsv + touch ${prefix}.csv + touch ${prefix}.pdf + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + nonpareil: \$(echo \$(nonpareil -V 2>&1) | sed 's/Nonpareil v//' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/meta.yml b/modules/nf-core/nonpareil/nonpareilcurvesr/meta.yml new file mode 100644 index 00000000..a4aeeb63 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/meta.yml @@ -0,0 +1,63 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "nonpareil_nonpareilcurvesr" +description: Generate summary reports with raw data for Nonpareil NPO curves, including MultiQC compatible JSON/TSV files +keywords: + - metagenomics + - statistics + - coverage + - redundancy + - diversity + - complexity + - multiqc +tools: + - "nonpareil": + description: "Estimate average coverage and create curves for metagenomic datasets" + homepage: "https://github.com/lmrodriguezr/nonpareil" + documentation: "https://nonpareil.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/lmrodriguezr/nonpareil" + doi: "10.1128/msystems.00039-" + licence: ["Artistic License 2.0"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - npos: + type: file + description: One or a list of Nonpareil NPO files (From nonpareil/nonpareil) + pattern: "*.{npo}" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - json: + type: file + description: Raw nonpareil data used for generating and plotting curves in JSON format + pattern: "*.json" + - tsv: + type: file + description: Raw nonpareil data used for generating and plotting curves in JSON format + pattern: "*.tsv" + - csv: + type: file + description: Raw nonpareil data used for generating and plotting curves in JSON format + pattern: "*.csv" + - pdf: + type: file + description: Plotted nonpareil curves in PDF format + pattern: "*.pdf" + +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test new file mode 100644 index 00000000..95420207 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test @@ -0,0 +1,76 @@ +nextflow_process { + + name "Test Process NONPAREIL_NONPAREILCURVESR" + script "../main.nf" + process "NONPAREIL_NONPAREILCURVESR" + + tag "modules" + tag "modules_nfcore" + tag "nonpareil" + tag "nonpareil/nonpareilcurvesr" + tag "nonpareil/nonpareil" + + setup { + run("NONPAREIL_NONPAREIL") { + script "../../../nonpareil/nonpareil/main.nf" + process { + """ + input[0] = Channel.fromList([ + [[ id:'test', single_end:false ], file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + [[ id:'test2', single_end:false ], file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + ]) + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + } + + test("candidatus_portiera_aleyrodidarum") { + + when { + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo.map{meta, npo -> [[id:'test'], npo]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.json[0][1]).text.contains("modelR\": 0."), + path(process.out.tsv[0][1]).text.contains("test 0."), + path(process.out.csv[0][1]).text.contains("test\",0."), + file(process.out.pdf[0][1]).name, + process.out.versions + ).match() + } + ) + } + + } + + test("candidatus_portiera_aleyrodidarum - stub") { + + options "-stub" + + when { + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo.map{meta, npo -> [[id:'test'], npo]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test.snap b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test.snap new file mode 100644 index 00000000..acab9a67 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/main.nf.test.snap @@ -0,0 +1,99 @@ +{ + "candidatus_portiera_aleyrodidarum": { + "content": [ + true, + true, + true, + "test.pdf", + [ + "versions.yml:md5,9aae4700a1ceafa37850be8d82d8d6dc" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-08T12:14:04.694169651" + }, + "candidatus_portiera_aleyrodidarum - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,9aae4700a1ceafa37850be8d82d8d6dc" + ], + "csv": [ + [ + { + "id": "test" + }, + "test.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test" + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pdf": [ + [ + { + "id": "test" + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tsv": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,9aae4700a1ceafa37850be8d82d8d6dc" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-08T12:03:11.519050978" + } +} diff --git a/modules/nf-core/nonpareil/nonpareilcurvesr/tests/tags.yml b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/tags.yml new file mode 100644 index 00000000..ba718e06 --- /dev/null +++ b/modules/nf-core/nonpareil/nonpareilcurvesr/tests/tags.yml @@ -0,0 +1,2 @@ +nonpareil/nonpareilcurvesr: + - "modules/nf-core/nonpareil/nonpareilcurvesr/**" diff --git a/modules/nf-core/nonpareil/set/environment.yml b/modules/nf-core/nonpareil/set/environment.yml new file mode 100644 index 00000000..89d5aa6e --- /dev/null +++ b/modules/nf-core/nonpareil/set/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::nonpareil=3.5.5 diff --git a/modules/nf-core/nonpareil/set/main.nf b/modules/nf-core/nonpareil/set/main.nf new file mode 100644 index 00000000..003c8958 --- /dev/null +++ b/modules/nf-core/nonpareil/set/main.nf @@ -0,0 +1,51 @@ +process NONPAREIL_SET { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/nonpareil:3.5.5--r43hdcf5f25_0': + 'biocontainers/nonpareil:3.5.5--r43hdcf5f25_0' }" + + input: + tuple val(meta), path(npos) + + output: + tuple val(meta), path("*.png"), emit: png + 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 args_cmd = args != '' ? ", ${args}" : "" + """ + #!/usr/bin/env Rscript + library(Nonpareil) + + png(file='${prefix}.png') + Nonpareil.set(list.files(pattern='*.npo')${args_cmd}) + dev.off() + + version_file_path <- "versions.yml" + version_nonpareil <- paste(unlist(packageVersion("Nonpareil")), collapse = ".") + f <- file(version_file_path, "w") + writeLines('"${task.process}":', f) + writeLines(" nonpareil: ", f, sep = "") + writeLines(version_nonpareil, f) + close(f) + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.png + + cat <<-END_VERSIONS > versions.yml + "${task.process}": \$(Rscript -e 'library('Nonpareil'); cat(paste(unlist(packageVersion("Nonpareil")),collapse="."))') + END_VERSIONS + """ +} diff --git a/modules/nf-core/nonpareil/set/meta.yml b/modules/nf-core/nonpareil/set/meta.yml new file mode 100644 index 00000000..74a26122 --- /dev/null +++ b/modules/nf-core/nonpareil/set/meta.yml @@ -0,0 +1,48 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +name: "nonpareil_set" +description: Visualise metagenome redundancy curves in PNG format from multiple Nonpareil npo files in a single image +keywords: + - metagenomics + - statistics + - coverage + - complexity + - redundancy + - diversity + - visualisation +tools: + - "nonpareil": + description: "Estimate average coverage and create curves for metagenomic datasets" + homepage: "https://github.com/lmrodriguezr/nonpareil" + documentation: "https://nonpareil.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/lmrodriguezr/nonpareil" + doi: "10.1128/msystems.00039-" + licence: ["Artistic License 2.0"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - npos: + type: file + description: A list of npo redundancy summary files from nonpareil itself + pattern: "*.npo" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - png: + type: file + description: PNG file of all the Nonpareil curves of the input npo files + pattern: "*.png" +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/nonpareil/set/tests/main.nf.test b/modules/nf-core/nonpareil/set/tests/main.nf.test new file mode 100644 index 00000000..23e7fa97 --- /dev/null +++ b/modules/nf-core/nonpareil/set/tests/main.nf.test @@ -0,0 +1,73 @@ +nextflow_process { + + name "Test Process NONPAREIL_SET" + script "../main.nf" + process "NONPAREIL_SET" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "nonpareil" + tag "nonpareil/set" + tag "nonpareil/nonpareil" + + setup { + run("NONPAREIL_NONPAREIL") { + script "../../../nonpareil/nonpareil/main.nf" + process { + """ + input[0] = Channel.fromList([ + [[ id:'test', single_end:false ], file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + [[ id:'test2', single_end:false ], file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + ]) + input[1] = 'fastq' + input[2] = 'kmer' + """ + } + } + } + + test("candidatus_portiera_aleyrodidarum") { + + when { + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo.map{meta, npo -> [[id:'test'], npo]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.png[0][1]).name, + process.out.versions + ).match() + } + ) + } + + } + +test("candidatus_portiera_aleyrodidarum - stub") { + + options "-stub" + + when { + process { + """ + input[0] = NONPAREIL_NONPAREIL.out.npo.map{meta, npo -> [[id:'test'], npo]}.groupTuple() + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/nonpareil/set/tests/main.nf.test.snap b/modules/nf-core/nonpareil/set/tests/main.nf.test.snap new file mode 100644 index 00000000..98ff42aa --- /dev/null +++ b/modules/nf-core/nonpareil/set/tests/main.nf.test.snap @@ -0,0 +1,48 @@ +{ + "candidatus_portiera_aleyrodidarum": { + "content": [ + "test.png", + [ + "versions.yml:md5,99b7abbea8d46b0a3d15ecd35049dc8d" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T12:12:45.998873423" + }, + "candidatus_portiera_aleyrodidarum - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,e12f68cd2102c6ab64e888bec3c7e7aa" + ], + "png": [ + [ + { + "id": "test" + }, + "test.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e12f68cd2102c6ab64e888bec3c7e7aa" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T14:40:53.480864245" + } +} \ No newline at end of file diff --git a/modules/nf-core/nonpareil/set/tests/nextflow.config b/modules/nf-core/nonpareil/set/tests/nextflow.config new file mode 100644 index 00000000..7809cca9 --- /dev/null +++ b/modules/nf-core/nonpareil/set/tests/nextflow.config @@ -0,0 +1,11 @@ +process { + + withName: NONPAREIL_NONPAREIL { + ext.args = '-X 100' + } + + withName: NONPAREIL_SET { + ext.args = "col = c('blue', 'red')" + } + +} diff --git a/modules/nf-core/nonpareil/set/tests/tags.yml b/modules/nf-core/nonpareil/set/tests/tags.yml new file mode 100644 index 00000000..1de9e293 --- /dev/null +++ b/modules/nf-core/nonpareil/set/tests/tags.yml @@ -0,0 +1,2 @@ +nonpareil/set: + - modules/nf-core/nonpareil/set/** diff --git a/modules/nf-core/porechop/abi/environment.yml b/modules/nf-core/porechop/abi/environment.yml new file mode 100644 index 00000000..dabb4921 --- /dev/null +++ b/modules/nf-core/porechop/abi/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::porechop_abi=0.5.0 diff --git a/modules/nf-core/porechop/abi/main.nf b/modules/nf-core/porechop/abi/main.nf new file mode 100644 index 00000000..88ec5bd0 --- /dev/null +++ b/modules/nf-core/porechop/abi/main.nf @@ -0,0 +1,50 @@ +process PORECHOP_ABI { + 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/porechop_abi:0.5.0--py310h590eda1_0': + 'biocontainers/porechop_abi:0.5.0--py310h590eda1_0' }" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.fastq.gz") , emit: reads + tuple val(meta), path("*.log") , emit: log + 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}.porechop_abi" + if ("$reads" == "${prefix}.fastq.gz") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + porechop_abi \\ + --input $reads \\ + --threads $task.cpus \\ + $args \\ + --output ${prefix}.fastq.gz \\ + | tee ${prefix}.log + cat <<-END_VERSIONS > versions.yml + "${task.process}": + porechop_abi: \$( porechop_abi --version ) + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}.porechop_abi" + """ + echo "" | gzip > ${prefix}.fastq.gz + touch ${prefix}.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + porechop_abi: \$( porechop_abi --version ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/porechop/abi/meta.yml b/modules/nf-core/porechop/abi/meta.yml new file mode 100644 index 00000000..a856ffbe --- /dev/null +++ b/modules/nf-core/porechop/abi/meta.yml @@ -0,0 +1,48 @@ +name: "porechop_abi" +description: Extension of Porechop whose purpose is to process adapter sequences in ONT reads. +keywords: + - porechop_abi + - adapter + - nanopore +tools: + - "porechop_abi": + description: Extension of Porechop whose purpose is to process adapter sequences in ONT reads. + homepage: "https://github.com/bonsai-team/Porechop_ABI" + documentation: "https://github.com/bonsai-team/Porechop_ABI" + tool_dev_url: "https://github.com/bonsai-team/Porechop_ABI" + doi: "10.1101/2022.07.07.499093" + licence: ["MIT"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: fastq/fastq.gz file + pattern: "*.{fastq,fastq.gz,fq,fq.gz}" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - reads: + type: file + description: Adapter-trimmed fastq.gz file + pattern: "*.fastq.gz" + - log: + type: file + description: Log file containing stdout information + pattern: "*.log" +authors: + - "@sofstam" + - "LilyAnderssonLee" +maintainers: + - "@sofstam" + - "LilyAnderssonLee" diff --git a/modules/nf-core/porechop/abi/tests/main.nf.test b/modules/nf-core/porechop/abi/tests/main.nf.test new file mode 100644 index 00000000..b5a29f90 --- /dev/null +++ b/modules/nf-core/porechop/abi/tests/main.nf.test @@ -0,0 +1,59 @@ +nextflow_process { + + name "Test Process PORECHOP_ABI" + script "../main.nf" + process "PORECHOP_ABI" + tag "modules" + tag "modules_nfcore" + tag "porechop" + tag "porechop/abi" + + test("sarscov2-nanopore") { + + when { + process { + """ + input[0] = [ + [ id:'test'], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.reads, + file(process.out.log.get(0).get(1)).readLines()[20..40], + process.out.versions).match() + } + ) + } + } + + test("sarscov2-nanopore - stub") { + + options "-stub" + + when { + + process { + """ + input[0] = [ + [ id:'test'], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/porechop/abi/tests/main.nf.test.snap b/modules/nf-core/porechop/abi/tests/main.nf.test.snap new file mode 100644 index 00000000..ad63f4ed --- /dev/null +++ b/modules/nf-core/porechop/abi/tests/main.nf.test.snap @@ -0,0 +1,94 @@ +{ + "sarscov2-nanopore": { + "content": [ + [ + [ + { + "id": "test" + }, + "test.porechop_abi.fastq.gz:md5,886fdb859fb50e0dddd35007bcff043e" + ] + ], + [ + " Best \u001b[0m", + " read Best \u001b[0m", + " start read end\u001b[0m", + " \u001b[4mSet %ID %ID \u001b[0m", + " \u001b[32mSQK-NSK007 100.0 73.1\u001b[0m", + " Rapid 40.4 0.0", + " RBK004_upstream 77.5 0.0", + " SQK-MAP006 75.8 72.7", + " SQK-MAP006 short 65.5 66.7", + " PCR adapters 1 73.9 69.6", + " PCR adapters 2 80.0 72.7", + " PCR adapters 3 70.8 69.6", + " 1D^2 part 1 71.4 70.0", + " 1D^2 part 2 84.8 75.8", + " cDNA SSP 63.0 61.7", + " \u001b[32mBarcode 1 (reverse) 100.0 100.0\u001b[0m", + " Barcode 2 (reverse) 70.8 69.2", + " Barcode 3 (reverse) 76.0 70.4", + " Barcode 4 (reverse) 74.1 71.4", + " Barcode 5 (reverse) 77.8 80.8", + " Barcode 6 (reverse) 73.1 70.8" + ], + [ + "versions.yml:md5,0e9e5e0d35a68ff8e6490c949b257f98" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-29T13:50:49.318599" + }, + "sarscov2-nanopore - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.porechop_abi.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.porechop_abi.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,0e9e5e0d35a68ff8e6490c949b257f98" + ], + "log": [ + [ + { + "id": "test" + }, + "test.porechop_abi.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test" + }, + "test.porechop_abi.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,0e9e5e0d35a68ff8e6490c949b257f98" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.1" + }, + "timestamp": "2024-07-29T13:50:54.425389" + } +} \ No newline at end of file diff --git a/modules/nf-core/porechop/porechop/environment.yml b/modules/nf-core/porechop/porechop/environment.yml new file mode 100644 index 00000000..4defeb33 --- /dev/null +++ b/modules/nf-core/porechop/porechop/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::porechop=0.2.4 diff --git a/modules/nf-core/porechop/porechop/main.nf b/modules/nf-core/porechop/porechop/main.nf index 648f2029..615ade21 100644 --- a/modules/nf-core/porechop/porechop/main.nf +++ b/modules/nf-core/porechop/porechop/main.nf @@ -2,7 +2,7 @@ process PORECHOP_PORECHOP { tag "$meta.id" label 'process_medium' - conda "bioconda::porechop=0.2.4" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/porechop:0.2.4--py39h7cff6ad_2' : 'biocontainers/porechop:0.2.4--py39h7cff6ad_2' }" @@ -11,7 +11,7 @@ process PORECHOP_PORECHOP { tuple val(meta), path(reads) output: - tuple val(meta), path("*_porechopped.fastq.gz"), emit: reads + tuple val(meta), path("*.fastq.gz"), emit: reads tuple val(meta), path("*.log") , emit: log path "versions.yml" , emit: versions @@ -21,16 +21,13 @@ process PORECHOP_PORECHOP { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + if ("$reads" == "${prefix}.fastq.gz") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ - ## To ensure ID matches rest of pipeline based on meta.id rather than input file name - - [[ -f ${prefix}.fastq.gz ]] || ln -s $reads ${prefix}.fastq.gz - porechop \\ - -i ${prefix}.fastq.gz \\ + -i $reads \\ -t $task.cpus \\ $args \\ - -o ${prefix}_porechopped.fastq.gz \\ + -o ${prefix}.fastq.gz \\ > ${prefix}.log cat <<-END_VERSIONS > versions.yml @@ -38,4 +35,16 @@ process PORECHOP_PORECHOP { porechop: \$( porechop --version ) END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.fastq + gzip ${prefix}.fastq + touch ${prefix}.log + cat <<-END_VERSIONS > versions.yml + "${task.process}": + porechop: \$( porechop --version ) + END_VERSIONS + """ } diff --git a/modules/nf-core/porechop/porechop/meta.yml b/modules/nf-core/porechop/porechop/meta.yml index 98b838f6..13be76f2 100644 --- a/modules/nf-core/porechop/porechop/meta.yml +++ b/modules/nf-core/porechop/porechop/meta.yml @@ -12,7 +12,6 @@ tools: tool_dev_url: "https://github.com/rrwick/Porechop" doi: "10.1099/mgen.0.000132" licence: ["GPL v3"] - input: - meta: type: map @@ -23,7 +22,6 @@ input: type: file description: fastq/fastq.gz file pattern: "*.{fastq,fastq.gz,fq,fq.gz}" - output: - meta: type: map @@ -42,7 +40,6 @@ output: type: file description: Log file containing stdout information pattern: "*.log" - authors: - "@ggabernet" - "@jasmezz" @@ -53,3 +50,13 @@ authors: - "@jonoave" - "@GokceOGUZ" - "@jfy133" +maintainers: + - "@ggabernet" + - "@jasmezz" + - "@d4straub" + - "@LaurenceKuhl" + - "@SusiJo" + - "@jonasscheid" + - "@jonoave" + - "@GokceOGUZ" + - "@jfy133" diff --git a/modules/nf-core/porechop/porechop/porechop-porechop.diff b/modules/nf-core/porechop/porechop/porechop-porechop.diff index 5d51f24a..7f734c7b 100644 --- a/modules/nf-core/porechop/porechop/porechop-porechop.diff +++ b/modules/nf-core/porechop/porechop/porechop-porechop.diff @@ -1,30 +1,17 @@ Changes in module 'nf-core/porechop/porechop' --- modules/nf-core/porechop/porechop/main.nf +++ modules/nf-core/porechop/porechop/main.nf -@@ -11,7 +11,7 @@ - tuple val(meta), path(reads) - - output: -- tuple val(meta), path("*.fastq.gz"), emit: reads -+ tuple val(meta), path("*_porechopped.fastq.gz"), emit: reads - tuple val(meta), path("*.log") , emit: log - path "versions.yml" , emit: versions - -@@ -22,12 +22,17 @@ +@@ -21,6 +21,7 @@ + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" ++ if ("$reads" == "${prefix}.fastq.gz") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ -+ ## To ensure ID matches rest of pipeline based on meta.id rather than input file name -+ -+ [[ -f ${prefix}.fastq.gz ]] || ln -s $reads ${prefix}.fastq.gz -+ porechop \\ -- -i $reads \\ -+ -i ${prefix}.fastq.gz \\ - -t $task.cpus \\ + -i $reads \\ +@@ -28,6 +29,7 @@ $args \\ -- -o ${prefix}.fastq.gz \\ -+ -o ${prefix}_porechopped.fastq.gz \\ + -o ${prefix}.fastq.gz \\ > ${prefix}.log + cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/porechop/porechop/tests/main.nf.test b/modules/nf-core/porechop/porechop/tests/main.nf.test new file mode 100644 index 00000000..ed3f6986 --- /dev/null +++ b/modules/nf-core/porechop/porechop/tests/main.nf.test @@ -0,0 +1,62 @@ +nextflow_process { + + name "Test Process PORECHOP_PORECHOP" + script "../main.nf" + process "PORECHOP_PORECHOP" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "porechop" + tag "porechop/porechop" + + test("sarscov2 - nanopore - fastq") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.reads).match("reads") }, + { assert snapshot(process.out.versions).match("versions") }, + // complete log is not stable. These first lines should be stable + { assert snapshot(path(process.out.log.get(0).get(1)).readLines()[0..7]).match("log")} + ) + } + + } + + + test("stub") { + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:true ], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + +} diff --git a/modules/nf-core/porechop/porechop/tests/main.nf.test.snap b/modules/nf-core/porechop/porechop/tests/main.nf.test.snap new file mode 100644 index 00000000..cf544d2d --- /dev/null +++ b/modules/nf-core/porechop/porechop/tests/main.nf.test.snap @@ -0,0 +1,88 @@ +{ + "versions": { + "content": [ + [ + "versions.yml:md5,712c0753b56d0fb530092dfb5bdf2e5c" + ] + ], + "timestamp": "2023-12-18T07:47:16.83444" + }, + "log": { + "content": [ + [ + "", + "\u001b[1m\u001b[4mLoading reads\u001b[0m", + "test.fastq.gz", + "100 reads loaded", + "", + "", + "\u001b[1m\u001b[4mLooking for known adapter sets\u001b[0m", + "" + ] + ], + "timestamp": "2023-12-18T07:47:16.853899" + }, + "reads": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test_porechop.fastq.gz:md5,886fdb859fb50e0dddd35007bcff043e" + ] + ] + ], + "timestamp": "2023-12-18T07:47:16.811393" + }, + "stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_porechop.fastq.gz:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test_porechop.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,712c0753b56d0fb530092dfb5bdf2e5c" + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test_porechop.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test_porechop.fastq.gz:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,712c0753b56d0fb530092dfb5bdf2e5c" + ] + } + ], + "timestamp": "2023-12-18T07:47:37.814949" + } +} \ No newline at end of file diff --git a/modules/nf-core/porechop/porechop/tests/nextflow.config b/modules/nf-core/porechop/porechop/tests/nextflow.config new file mode 100644 index 00000000..a9ecf7b6 --- /dev/null +++ b/modules/nf-core/porechop/porechop/tests/nextflow.config @@ -0,0 +1,9 @@ +process { + + + withName: PORECHOP_PORECHOP { + ext.args = '' + ext.prefix = { "${meta.id}_porechop" } + } + +} diff --git a/modules/nf-core/porechop/porechop/tests/tags.yml b/modules/nf-core/porechop/porechop/tests/tags.yml new file mode 100644 index 00000000..743645c2 --- /dev/null +++ b/modules/nf-core/porechop/porechop/tests/tags.yml @@ -0,0 +1,2 @@ +porechop/porechop: + - "modules/nf-core/porechop/porechop/**" diff --git a/modules/nf-core/prinseqplusplus/environment.yml b/modules/nf-core/prinseqplusplus/environment.yml new file mode 100644 index 00000000..fe598ef1 --- /dev/null +++ b/modules/nf-core/prinseqplusplus/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::prinseq-plus-plus=1.2.3 diff --git a/modules/nf-core/prinseqplusplus/main.nf b/modules/nf-core/prinseqplusplus/main.nf index 63b2c723..6981445e 100644 --- a/modules/nf-core/prinseqplusplus/main.nf +++ b/modules/nf-core/prinseqplusplus/main.nf @@ -2,7 +2,7 @@ process PRINSEQPLUSPLUS { tag "$meta.id" label 'process_low' - conda "bioconda::prinseq-plus-plus=1.2.3" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/prinseq-plus-plus:1.2.3--hc90279e_1': 'biocontainers/prinseq-plus-plus:1.2.3--hc90279e_1' }" diff --git a/modules/nf-core/prinseqplusplus/meta.yml b/modules/nf-core/prinseqplusplus/meta.yml index 8155df93..a978be4a 100644 --- a/modules/nf-core/prinseqplusplus/meta.yml +++ b/modules/nf-core/prinseqplusplus/meta.yml @@ -12,8 +12,7 @@ tools: documentation: "https://github.com/Adrian-Cantu/PRINSEQ-plus-plus" tool_dev_url: "https://github.com/Adrian-Cantu/PRINSEQ-plus-plus" doi: "10.7287/peerj.preprints.27553v1" - licence: "['GPL v2']" - + licence: ["GPL v2"] input: - meta: type: map @@ -25,7 +24,6 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. - output: - meta: type: map @@ -55,6 +53,7 @@ output: description: | Verbose level 2 STDOUT information in a log file pattern: "*.log" - authors: - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/prinseqplusplus/tests/main.nf.test b/modules/nf-core/prinseqplusplus/tests/main.nf.test new file mode 100644 index 00000000..a6708ce9 --- /dev/null +++ b/modules/nf-core/prinseqplusplus/tests/main.nf.test @@ -0,0 +1,74 @@ + +nextflow_process { + + name "Test Process PRINSEQPLUSPLUS" + script "../main.nf" + process "PRINSEQPLUSPLUS" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "prinseqplusplus" + + test("test-prinseqplusplus-single-end") { + + when { + process { + """ + input[0] = [ + [ 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( + file(process.out.good_reads[0][1]).name, // unstable + process.out.single_reads, + process.out.bad_reads, + file(process.out.log[0][1]).name, + process.out.versions + ).match() + } + ) + } + } + + test("test-prinseqplusplus-paired-end") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.good_reads[0][1].collect { file(it).name }, // unstable + process.out.single_reads[0][1].collect { file(it).name }, // empty: d41d8cd98f00b204e9800998ecf8427e + process.out.bad_reads, + file(process.out.log[0][1]).name, + process.out.versions + ).match() + } + ) + } + } + +} diff --git a/modules/nf-core/prinseqplusplus/tests/main.nf.test.snap b/modules/nf-core/prinseqplusplus/tests/main.nf.test.snap new file mode 100644 index 00000000..b9dcd854 --- /dev/null +++ b/modules/nf-core/prinseqplusplus/tests/main.nf.test.snap @@ -0,0 +1,61 @@ +{ + "test-prinseqplusplus-single-end": { + "content": [ + "test_good_out.fastq.gz", + [ + + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_bad_out.fastq.gz:md5,16c592181d7763349c37f5c357374344" + ] + ], + "test.log", + [ + "versions.yml:md5,366e108ac2695a852af440e61fecad5e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-27T14:55:34.731661" + }, + "test-prinseqplusplus-paired-end": { + "content": [ + [ + "test_good_out_R1.fastq.gz", + "test_good_out_R2.fastq.gz" + ], + [ + "test_single_out_R1.fastq.gz", + "test_single_out_R2.fastq.gz" + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_bad_out_R1.fastq.gz:md5,16c592181d7763349c37f5c357374344", + "test_bad_out_R2.fastq.gz:md5,e6c58927d64c132d59a33fd6a3f63951" + ] + ] + ], + "test.log", + [ + "versions.yml:md5,366e108ac2695a852af440e61fecad5e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-27T14:57:53.505032" + } +} \ No newline at end of file diff --git a/modules/nf-core/prinseqplusplus/tests/nextflow.config b/modules/nf-core/prinseqplusplus/tests/nextflow.config new file mode 100644 index 00000000..14bae89f --- /dev/null +++ b/modules/nf-core/prinseqplusplus/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: PRINSEQPLUSPLUS { + ext.args = "-lc_entropy=0.8" + } +} diff --git a/modules/nf-core/samtools/fastq/environment.yml b/modules/nf-core/samtools/fastq/environment.yml new file mode 100644 index 00000000..da2df5e4 --- /dev/null +++ b/modules/nf-core/samtools/fastq/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::samtools=1.20 + - bioconda::htslib=1.20 diff --git a/modules/nf-core/samtools/fastq/main.nf b/modules/nf-core/samtools/fastq/main.nf index 15d89769..6796c02b 100644 --- a/modules/nf-core/samtools/fastq/main.nf +++ b/modules/nf-core/samtools/fastq/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_FASTQ { tag "$meta.id" label 'process_low' - conda "bioconda::samtools=1.17" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.20--h50ea8bc_0' : + 'biocontainers/samtools:1.20--h50ea8bc_0' }" input: tuple val(meta), path(input) @@ -13,7 +13,7 @@ process SAMTOOLS_FASTQ { output: tuple val(meta), path("*_{1,2}.fastq.gz") , optional:true, emit: fastq - tuple val(meta), path("*_interleaved.fastq.gz"), optional:true, emit: interleaved + tuple val(meta), path("*_interleaved.fastq") , optional:true, emit: interleaved tuple val(meta), path("*_singleton.fastq.gz") , optional:true, emit: singleton tuple val(meta), path("*_other.fastq.gz") , optional:true, emit: other path "versions.yml" , emit: versions @@ -24,7 +24,7 @@ process SAMTOOLS_FASTQ { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def output = ( interleave && ! meta.single_end ) ? "> ${prefix}_interleaved.fastq.gz" : + def output = ( interleave && ! meta.single_end ) ? "> ${prefix}_interleaved.fastq" : meta.single_end ? "-1 ${prefix}_1.fastq.gz -s ${prefix}_singleton.fastq.gz" : "-1 ${prefix}_1.fastq.gz -2 ${prefix}_2.fastq.gz -s ${prefix}_singleton.fastq.gz" """ diff --git a/modules/nf-core/samtools/fastq/meta.yml b/modules/nf-core/samtools/fastq/meta.yml index b1a1ed38..c4002a45 100644 --- a/modules/nf-core/samtools/fastq/meta.yml +++ b/modules/nf-core/samtools/fastq/meta.yml @@ -15,7 +15,6 @@ tools: documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] - input: - meta: type: map @@ -29,7 +28,6 @@ input: - interleave: type: boolean description: Set true for interleaved fastq file - output: - meta: type: map @@ -56,7 +54,9 @@ output: type: file description: Compressed FASTQ file with reads with either both READ1 and READ2 flags set or unset pattern: "*_other.fastq.gz" - authors: - "@priyanka-surana" - "@suzannejin" +maintainers: + - "@priyanka-surana" + - "@suzannejin" diff --git a/modules/nf-core/samtools/fastq/tests/main.nf.test b/modules/nf-core/samtools/fastq/tests/main.nf.test new file mode 100644 index 00000000..f6ac1123 --- /dev/null +++ b/modules/nf-core/samtools/fastq/tests/main.nf.test @@ -0,0 +1,67 @@ +nextflow_process { + + name "Test Process SAMTOOLS_FASTQ" + script "../main.nf" + process "SAMTOOLS_FASTQ" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/fastq" + + test("bam") { + + when { + process { + """ + interleave = false + + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ]) + input[1] = interleave + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.fastq[0][1].collect { path(it).linesGzip[0..6] }).match("bam_fastq") }, + { assert snapshot(process.out.interleaved).match("bam_interleaved") }, + { assert snapshot(file(process.out.singleton[0][1]).name).match("bam_singleton") }, + { assert snapshot(file(process.out.other[0][1]).name).match("bam_other") }, + { assert snapshot(process.out.versions).match("bam_versions") } + ) + } + } + + test("bam_interleave") { + + when { + process { + """ + interleave = true + + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ]) + input[1] = interleave + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.fastq).match("bam_interleave_fastq") }, + { assert snapshot(path(process.out.interleaved[0][1]).readLines()[0..6]).match("bam_interlinterleave_eaved") }, + { assert snapshot(process.out.singleton).match("bam_singinterleave_leton") }, + { assert snapshot(file(process.out.other[0][1]).name).match("bam_interleave_other") }, + { assert snapshot(process.out.versions).match("bam_verinterleave_sions") } + ) + } + } +} diff --git a/modules/nf-core/samtools/fastq/tests/main.nf.test.snap b/modules/nf-core/samtools/fastq/tests/main.nf.test.snap new file mode 100644 index 00000000..1ba09d3a --- /dev/null +++ b/modules/nf-core/samtools/fastq/tests/main.nf.test.snap @@ -0,0 +1,139 @@ +{ + "bam_interlinterleave_eaved": { + "content": [ + [ + "@ERR5069949.2151832/1", + "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", + "+", + "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index 8bd2fa6f..01a4ee03 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -51,3 +51,7 @@ authors: - "@drpatelh" - "@ewels" - "@maxulysse" +maintainers: + - "@drpatelh" + - "@ewels" + - "@maxulysse" diff --git a/modules/nf-core/samtools/index/tests/csi.nextflow.config b/modules/nf-core/samtools/index/tests/csi.nextflow.config new file mode 100644 index 00000000..0ed260ef --- /dev/null +++ b/modules/nf-core/samtools/index/tests/csi.nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: SAMTOOLS_INDEX { + ext.args = '-c' + } + +} diff --git a/modules/nf-core/samtools/index/tests/main.nf.test b/modules/nf-core/samtools/index/tests/main.nf.test new file mode 100644 index 00000000..ca34fb5c --- /dev/null +++ b/modules/nf-core/samtools/index/tests/main.nf.test @@ -0,0 +1,140 @@ +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/index" + + test("bai") { + 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("crai") { + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("csi") { + config "./csi.nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.csi[0][1]).name, + process.out.versions + ).match() } + ) + } + } + + test("bai - 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("crai - stub") { + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("csi - stub") { + options "-stub" + config "./csi.nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/samtools/index/tests/main.nf.test.snap b/modules/nf-core/samtools/index/tests/main.nf.test.snap new file mode 100644 index 00000000..799d199c --- /dev/null +++ b/modules/nf-core/samtools/index/tests/main.nf.test.snap @@ -0,0 +1,250 @@ +{ + "csi - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ], + "bai": [ + + ], + "crai": [ + + ], + "csi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:51:53.9057" + }, + "crai - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ], + "bai": [ + + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:51:45.931558" + }, + "bai - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:51:34.807525" + }, + "csi": { + "content": [ + "test.paired_end.sorted.bam.csi", + [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:52:55.688799" + }, + "crai": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + ] + ], + "3": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ], + "bai": [ + + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + ] + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:51:17.609533" + }, + "bai": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + ] + ], + "crai": [ + + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,802c9776d9c5e95314e888cf18e96d77" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T16:51:04.16585" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/index/tests/tags.yml b/modules/nf-core/samtools/index/tests/tags.yml new file mode 100644 index 00000000..e0f58a7a --- /dev/null +++ b/modules/nf-core/samtools/index/tests/tags.yml @@ -0,0 +1,2 @@ +samtools/index: + - modules/nf-core/samtools/index/** diff --git a/modules/nf-core/samtools/stats/environment.yml b/modules/nf-core/samtools/stats/environment.yml new file mode 100644 index 00000000..da2df5e4 --- /dev/null +++ b/modules/nf-core/samtools/stats/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::samtools=1.20 + - bioconda::htslib=1.20 diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 4a2607de..982bc28e 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_STATS { tag "$meta.id" label 'process_single' - conda "bioconda::samtools=1.17" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.20--h50ea8bc_0' : + 'biocontainers/samtools:1.20--h50ea8bc_0' }" input: tuple val(meta), path(input), path(input_index) diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index 90e6345f..735ff812 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -57,3 +57,7 @@ authors: - "@drpatelh" - "@FriederikeHanssen" - "@ramprasadn" +maintainers: + - "@drpatelh" + - "@FriederikeHanssen" + - "@ramprasadn" diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test b/modules/nf-core/samtools/stats/tests/main.nf.test new file mode 100644 index 00000000..5bc89309 --- /dev/null +++ b/modules/nf-core/samtools/stats/tests/main.nf.test @@ -0,0 +1,113 @@ +nextflow_process { + + name "Test Process SAMTOOLS_STATS" + script "../main.nf" + process "SAMTOOLS_STATS" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/stats" + + test("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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("cram") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram.crai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("cram - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram.crai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } +} diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test.snap b/modules/nf-core/samtools/stats/tests/main.nf.test.snap new file mode 100644 index 00000000..3828f378 --- /dev/null +++ b/modules/nf-core/samtools/stats/tests/main.nf.test.snap @@ -0,0 +1,142 @@ +{ + "cram": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,c9d39b38c22de2057fc2f89949090975" + ] + ], + "1": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,c9d39b38c22de2057fc2f89949090975" + ] + ], + "versions": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T14:20:24.885816" + }, + "bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T14:20:39.310713" + }, + "cram - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T14:21:04.771199" + }, + "bam": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d522a1fa016b259d6a55620ae53dcd63" + ] + ], + "1": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d522a1fa016b259d6a55620ae53dcd63" + ] + ], + "versions": [ + "versions.yml:md5,b3b70b126f867fdbb7dcea5e36e49d4a" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T14:19:06.645466" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/stats/tests/tags.yml b/modules/nf-core/samtools/stats/tests/tags.yml new file mode 100644 index 00000000..7c28e30f --- /dev/null +++ b/modules/nf-core/samtools/stats/tests/tags.yml @@ -0,0 +1,2 @@ +samtools/stats: + - modules/nf-core/samtools/stats/** diff --git a/modules/nf-core/samtools/view/environment.yml b/modules/nf-core/samtools/view/environment.yml new file mode 100644 index 00000000..da2df5e4 --- /dev/null +++ b/modules/nf-core/samtools/view/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::samtools=1.20 + - bioconda::htslib=1.20 diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf index cb91facf..dc611448 100644 --- a/modules/nf-core/samtools/view/main.nf +++ b/modules/nf-core/samtools/view/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_VIEW { tag "$meta.id" label 'process_low' - conda "bioconda::samtools=1.17" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.20--h50ea8bc_0' : + 'biocontainers/samtools:1.20--h50ea8bc_0' }" input: tuple val(meta), path(input), path(index) @@ -13,13 +13,15 @@ process SAMTOOLS_VIEW { path qname output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.sam"), emit: sam, optional: true - tuple val(meta), path("*.bai"), emit: bai, optional: true - tuple val(meta), path("*.csi"), emit: csi, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true + tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true + tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true + tuple val(meta), path("${prefix}.${file_type}.bai"), emit: bai, optional: true + tuple val(meta), path("${prefix}.${file_type}.csi"), emit: csi, optional: true + tuple val(meta), path("${prefix}.${file_type}.crai"), emit: crai, optional: true + tuple val(meta), path("${prefix}.unselected.${file_type}"), emit: unselected, optional: true + tuple val(meta), path("${prefix}.unselected.${file_type}.{bai,csi,crsi}"), emit: unselected_index, optional: true + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -27,13 +29,13 @@ process SAMTOOLS_VIEW { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--reference ${fasta}" : "" - def readnames = qname ? "--qname-file ${qname}": "" - def file_type = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt bam") ? "bam" : - args.contains("--output-fmt cram") ? "cram" : - input.getExtension() + file_type = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + input.getExtension() + readnames = qname ? "--qname-file ${qname} --output-unselected ${prefix}.unselected.${file_type}": "" if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ samtools \\ @@ -53,10 +55,19 @@ process SAMTOOLS_VIEW { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + file_type = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + input.getExtension() + if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + + def index = args.contains("--write-index") ? "touch ${prefix}.${file_type}.csi" : "" + """ - touch ${prefix}.bam - touch ${prefix}.cram + touch ${prefix}.${file_type} + ${index} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index 3b05450b..27be60d0 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/meta.yml @@ -73,6 +73,15 @@ output: type: file description: optional CRAM file index pattern: "*.{crai}" + # unselected and unselected_index are created when passing a qname + - unselected: + type: file + description: optional file with unselected alignments + pattern: "*.unselected.{bam,cram,sam}" + - unselected_index: + type: file + description: index for the "unselected" file + pattern: "*.unselected.{bai,csi,crai}" - versions: type: file description: File containing software versions @@ -82,3 +91,8 @@ authors: - "@joseespinosa" - "@FriederikeHanssen" - "@priyanka-surana" +maintainers: + - "@drpatelh" + - "@joseespinosa" + - "@FriederikeHanssen" + - "@priyanka-surana" diff --git a/modules/nf-core/samtools/view/tests/bam.config b/modules/nf-core/samtools/view/tests/bam.config new file mode 100644 index 00000000..c10d1081 --- /dev/null +++ b/modules/nf-core/samtools/view/tests/bam.config @@ -0,0 +1,3 @@ +process { + ext.args = "--output-fmt bam" +} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/bam_index.config b/modules/nf-core/samtools/view/tests/bam_index.config new file mode 100644 index 00000000..771ae033 --- /dev/null +++ b/modules/nf-core/samtools/view/tests/bam_index.config @@ -0,0 +1,3 @@ +process { + ext.args = "--output-fmt bam --write-index" +} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/main.nf.test b/modules/nf-core/samtools/view/tests/main.nf.test new file mode 100644 index 00000000..37b81a91 --- /dev/null +++ b/modules/nf-core/samtools/view/tests/main.nf.test @@ -0,0 +1,214 @@ +nextflow_process { + + name "Test Process SAMTOOLS_VIEW" + script "../main.nf" + process "SAMTOOLS_VIEW" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/view" + + test("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.bam', checkIfExists: true), + [] + ]) + input[1] = [[],[]] + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.bam[0][1]).name).match("bam_bam") }, + { assert snapshot(process.out.bai).match("bam_bai") }, + { assert snapshot(process.out.crai).match("bam_crai") }, + { assert snapshot(process.out.cram).match("bam_cram") }, + { assert snapshot(process.out.csi).match("bam_csi") }, + { assert snapshot(process.out.sam).match("bam_sam") }, + { assert snapshot(process.out.versions).match("bam_versions") } + ) + } + } + + test("cram") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.cram[0][1]).name).match("cram_cram") }, + { assert snapshot(process.out.bai).match("cram_bai") }, + { assert snapshot(process.out.bam).match("cram_bam") }, + { assert snapshot(process.out.crai).match("cram_crai") }, + { assert snapshot(process.out.csi).match("cram_csi") }, + { assert snapshot(process.out.sam).match("cram_sam") }, + { assert snapshot(process.out.versions).match("cram_versions") } + ) + } + } + + test("cram_to_bam") { + + config "./bam.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_bam") }, + { assert snapshot(process.out.bai).match("cram_to_bam_bai") }, + { assert snapshot(process.out.crai).match("cram_to_bam_crai") }, + { assert snapshot(process.out.cram).match("cram_to_bam_cram") }, + { assert snapshot(process.out.csi).match("cram_to_bam_csi") }, + { assert snapshot(process.out.sam).match("cram_to_bam_sam") }, + { assert snapshot(process.out.versions).match("cram_to_bam_versions") } + ) + } + } + + test("cram_to_bam_index") { + + config "./bam_index.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_bam") }, + { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_csi") }, + { assert snapshot(process.out.bai).match("cram_to_bam_index_bai") }, + { assert snapshot(process.out.crai).match("cram_to_bam_index_crai") }, + { assert snapshot(process.out.cram).match("cram_to_bam_index_cram") }, + { assert snapshot(process.out.sam).match("cram_to_bam_index_sam") }, + { assert snapshot(process.out.versions).match("cram_to_bam_index_versions") } + ) + } + } + + test("cram_to_bam_index_qname") { + + config "./bam_index.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + [] + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = Channel.of("testN:2817", "testN:2814").collectFile(name: "readnames.list", newLine: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_qname_bam") }, + { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_qname_csi") }, + { assert snapshot(process.out.bai).match("cram_to_bam_index_qname_bai") }, + { assert snapshot(process.out.crai).match("cram_to_bam_index_qname_crai") }, + { assert snapshot(process.out.cram).match("cram_to_bam_index_qname_cram") }, + { assert snapshot(process.out.sam).match("cram_to_bam_index_qname_sam") }, + { assert snapshot(file(process.out.unselected[0][1]).name).match("cram_to_bam_index_qname_unselected") }, + { assert snapshot(file(process.out.unselected_index[0][1]).name).match("cram_to_bam_index_qname_unselected_csi") }, + { assert snapshot(process.out.versions).match("cram_to_bam_index_qname_versions") } + ) + } + } + + test("bam_stub") { + + options "-stub" + config "./bam_index.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true), + [] + ]) + input[1] = [[],[]] + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.bam[0][1]).name).match("bam_stub_bam") }, + { assert snapshot(file(process.out.csi[0][1]).name).match("bam_stub_csi") }, + { assert snapshot(process.out.bai).match("bam_stub_bai") }, + { assert snapshot(process.out.crai).match("bam_stub_crai") }, + { assert snapshot(process.out.cram).match("bam_stub_cram") }, + { assert snapshot(process.out.sam).match("bam_stub_sam") }, + { assert snapshot(process.out.versions).match("bam_stub_versions") } + ) + } + } +} diff --git a/modules/nf-core/samtools/view/tests/main.nf.test.snap b/modules/nf-core/samtools/view/tests/main.nf.test.snap new file mode 100644 index 00000000..6bcce9fe --- /dev/null +++ b/modules/nf-core/samtools/view/tests/main.nf.test.snap @@ -0,0 +1,508 @@ +{ + "bam_bam": { + "content": [ + "test.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.256068" + }, + "cram_to_bam_index_csi": { + "content": [ + "test.bam.csi" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.958617" + }, + "bam_stub_bam": { + "content": [ + "test.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.065301" + }, + "bam_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.258578" + }, + "bam_stub_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.071284" + }, + "bam_stub_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:43:20.390692583" + }, + "cram_to_bam_index_cram": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.972288" + }, + "cram_to_bam_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.999247" + }, + "cram_to_bam_index_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.976457" + }, + "cram_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.497581" + }, + "cram_csi": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.50038" + }, + "cram_to_bam_cram": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.992239" + }, + "cram_to_bam_index_qname_csi": { + "content": [ + "test.bam.csi" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.325496" + }, + "bam_stub_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.079529" + }, + "cram_cram": { + "content": [ + "test.cram" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.490286" + }, + "bam_csi": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.262882" + }, + "cram_to_bam_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.989247" + }, + "cram_to_bam_index_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.967681" + }, + "cram_to_bam_index_qname_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:43:15.007493874" + }, + "cram_to_bam_bam": { + "content": [ + "test.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.982361" + }, + "cram_to_bam_index_bam": { + "content": [ + "test.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.95456" + }, + "cram_to_bam_index_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:43:09.472376824" + }, + "cram_to_bam_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.98601" + }, + "cram_to_bam_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:43:04.080050906" + }, + "cram_bam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.495512" + }, + "bam_stub_cram": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.076908" + }, + "cram_to_bam_index_qname_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.328458" + }, + "cram_to_bam_index_qname_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.330789" + }, + "cram_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.493129" + }, + "bam_stub_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.074313" + }, + "cram_to_bam_index_qname_bam": { + "content": [ + "test.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.322874" + }, + "cram_to_bam_index_qname_unselected": { + "content": [ + "test.unselected.bam" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.322874" + }, + "cram_to_bam_index_qname_unselected_csi": { + "content": [ + "test.unselected.bam.csi" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.328458" + }, + "bam_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:42:52.978954857" + }, + "cram_to_bam_index_qname_cram": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.333248" + }, + "bam_crai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.259774" + }, + "bam_cram": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.261287" + }, + "cram_to_bam_csi": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:04.995454" + }, + "cram_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:56.502625" + }, + "cram_versions": { + "content": [ + [ + "versions.yml:md5,6cd41a9a3b4a95271ec011ea990a2838" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-05-28T15:42:58.400776109" + }, + "bam_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:37:51.264651" + }, + "cram_to_bam_index_bai": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:12.962863" + }, + "cram_to_bam_index_qname_sam": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:23.337634" + }, + "bam_stub_csi": { + "content": [ + "test.bam.csi" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.04.3" + }, + "timestamp": "2024-02-12T19:38:32.068596" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/tests/tags.yml b/modules/nf-core/samtools/view/tests/tags.yml new file mode 100644 index 00000000..4fdf1dd1 --- /dev/null +++ b/modules/nf-core/samtools/view/tests/tags.yml @@ -0,0 +1,2 @@ +samtools/view: + - "modules/nf-core/samtools/view/**" diff --git a/modules/nf-core/taxpasta/merge/environment.yml b/modules/nf-core/taxpasta/merge/environment.yml index ca1a10b7..eb48f436 100644 --- a/modules/nf-core/taxpasta/merge/environment.yml +++ b/modules/nf-core/taxpasta/merge/environment.yml @@ -1,7 +1,5 @@ -name: taxpasta_merge channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::taxpasta=0.7.0 diff --git a/modules/nf-core/taxpasta/standardise/environment.yml b/modules/nf-core/taxpasta/standardise/environment.yml index a48f08e0..eb48f436 100644 --- a/modules/nf-core/taxpasta/standardise/environment.yml +++ b/modules/nf-core/taxpasta/standardise/environment.yml @@ -1,7 +1,5 @@ -name: taxpasta_standardise channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::taxpasta=0.7.0 diff --git a/modules/nf-core/untar/environment.yml b/modules/nf-core/untar/environment.yml new file mode 100644 index 00000000..c7794856 --- /dev/null +++ b/modules/nf-core/untar/environment.yml @@ -0,0 +1,7 @@ +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::grep=3.11 + - conda-forge::sed=4.8 + - conda-forge::tar=1.34 diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf index 61461c39..9bd8f554 100644 --- a/modules/nf-core/untar/main.nf +++ b/modules/nf-core/untar/main.nf @@ -2,10 +2,10 @@ process UNTAR { tag "$archive" label 'process_single' - conda "conda-forge::sed=4.7 conda-forge::grep=3.11 conda-forge::tar=1.34" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'nf-core/ubuntu:20.04' }" + 'https://depot.galaxyproject.org/singularity/ubuntu:22.04' : + 'nf-core/ubuntu:22.04' }" input: tuple val(meta), path(archive) @@ -52,8 +52,29 @@ process UNTAR { stub: prefix = task.ext.prefix ?: ( meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) """ - mkdir $prefix - touch ${prefix}/file.txt + 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 cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/untar/meta.yml b/modules/nf-core/untar/meta.yml index db241a6e..a9a2110f 100644 --- a/modules/nf-core/untar/meta.yml +++ b/modules/nf-core/untar/meta.yml @@ -39,3 +39,8 @@ authors: - "@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 00000000..c957517a --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test @@ -0,0 +1,85 @@ +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).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).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).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).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 00000000..ceb91b79 --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test.snap @@ -0,0 +1,158 @@ +{ + "test_untar_onlyfiles": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:28.231047" + }, + "test_untar_onlyfiles - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:45.773103" + }, + "test_untar - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:36.777441" + }, + "test_untar": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:19.377674" + } +} \ No newline at end of file diff --git a/modules/nf-core/untar/tests/tags.yml b/modules/nf-core/untar/tests/tags.yml new file mode 100644 index 00000000..feb6f15c --- /dev/null +++ b/modules/nf-core/untar/tests/tags.yml @@ -0,0 +1,2 @@ +untar: + - modules/nf-core/untar/** diff --git a/nextflow.config b/nextflow.config index dc42a08a..8c763bcf 100644 --- a/nextflow.config +++ b/nextflow.config @@ -79,14 +79,21 @@ params { shortread_qc_dedup = false perform_longread_qc = false + longread_adapterremoval_tool = 'porechop_abi' longread_qc_skipadaptertrim = false longread_qc_skipqualityfilter = false + longread_filter_tool = 'nanoq' longread_qc_qualityfilter_minlength = 1000 longread_qc_qualityfilter_keeppercent = 90 + longread_qc_qualityfilter_minquality = 7 longread_qc_qualityfilter_targetbases = 500000000 save_preprocessed_reads = false + // Redundancy estimation + perform_shortread_redundancyestimation = false + shortread_redundancyestimation_mode = 'kmer' + // Complexity filtering perform_shortread_complexityfilter = false shortread_complexityfilter_tool = 'bbduk' diff --git a/nextflow_schema.json b/nextflow_schema.json index deef481a..4fb4ba40 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -84,7 +84,7 @@ "type": "boolean", "fa_icon": "fas fa-save", "description": "Save reads from samples that went through the adapter clipping, pair-merging, and length filtering steps for both short and long reads", - "help_text": "This saves the FASTQ output from the following tools:\n\n- fastp\n- AdapterRemoval\n- Porechop\n- Filtlong\n\nThese reads will be a mixture of: adapter clipped, quality trimmed, pair-merged, and length filtered, depending on the parameters you set." + "help_text": "This saves the FASTQ output from the following tools:\n\n- fastp\n- AdapterRemoval\n- Porechop\n- Filtlong\n- Nanoq\n\nThese reads will be a mixture of: adapter clipped, quality trimmed, pair-merged, and length filtered, depending on the parameters you set." }, "save_analysis_ready_fastqs": { "type": "boolean", @@ -238,24 +238,40 @@ "description": "Turns on long read quality control steps (adapter clipping, length filtering etc.)", "help_text": "Turns on long read quality control steps (adapter clipping, length and/or quality filtering.)\n\nRemoving adapters (if present) is recommend to reduce false-postive hits that may occur from 'dirty' or 'contaminated' reference genomes in a profiling database that contain accidentially incorporated adapter sequences.\n\nLength filtering, and quality filtering can speed up alignment by reducing the number of unspecific reads that need to be aligned." }, + "longread_adapterremoval_tool": { + "type": "string", + "default": "porechop_abi", + "enum": ["porechop", "porechop_abi"], + "fa_icon": "fas fa-hammer", + "description": "Specify which tool to use for adapter trimming.", + "help_text": "The performance of Porechop and Porechop_ABI is same in terms of removing adapter reads. However Porechop is no longer updated, Porechop_ABI receives regular updates." + }, "longread_qc_skipadaptertrim": { "type": "boolean", "description": "Skip long-read trimming", "fa_icon": "fas fa-forward", "help_text": "Skip removal of adapters by Porechop. This can be useful in some cases to speed up run time - particularly when you are running data downloading from public databases such as the ENA/SRA that should already have adapters removed. We recommend that you check your FastQC results this is indeed the case." }, + "longread_filter_tool": { + "type": "string", + "default": "nanoq", + "enum": ["filtlong", "nanoq"], + "fa_icon": "fas fa-hammer", + "description": "Specify which tool to use for long reads filtering", + "help_text": "Nanoq is a filtering tool only for Nanopore reads. Nanoq is faster and more memory-efficient than Filtlong. Nanoq also provides a summary of input read statistics; see [benchmarking](https://github.com/esteinig/nanoq?tab=readme-ov-file#benchmarks). \n\nFiltlong is a good option if you want to keep a certain percentage of reads after filtering, and you can also use it for non-Nanopore long reads." + }, "longread_qc_skipqualityfilter": { "type": "boolean", "description": "Skip long-read length and quality filtering", "fa_icon": "fas fa-forward", - "help_text": "Skip removal of quality filtering with Filtlong. This will skip length, percent reads, and target bases filtering (see other `--longread_qc_qualityfilter_*` parameters)." + "help_text": "Skip removal of quality filtering with Filtlong or Nanoq. This will skip length, percent reads, and target bases filtering (see other `--longread_qc_qualityfilter_*` parameters)." }, "longread_qc_qualityfilter_minlength": { "type": "integer", "default": 1000, "description": "Specify the minimum length of reads to be retained", "fa_icon": "fas fa-ruler-horizontal", - "help_text": "Specify the minimum of length of reads to be kept for downstream analysis.\n\n> Modifies tool parameter(s):\n> - Filtlong: `--min_length`" + "help_text": "Specify the minimum of length of reads to be kept for downstream analysis.\n\n> Modifies tool parameter(s):\n> - Filtlong: `--min_length` or - Nanoq: `--min-len`" }, "longread_qc_qualityfilter_keeppercent": { "type": "integer", @@ -267,13 +283,43 @@ "longread_qc_qualityfilter_targetbases": { "type": "integer", "default": 500000000, - "description": "Specify the number of high-quality bases in the library to be retained", + "description": "Filtlong only: specify the number of high-quality bases in the library to be retained", "fa_icon": "fas fa-bullseye", "help_text": "Removes the worst reads until only the specified value of bases remain, useful for very large read sets. If the input read set is less than the specified value, this setting will have no effect. _Modified from [Filtlong documentation](https://github.com/rrwick/Filtlong)_\n\n> Modifies tool parameter(s):\n> - Filtlong: `--keep_percent`" + }, + "longread_qc_qualityfilter_minquality": { + "type": "integer", + "default": 7, + "description": "Nanoq only: specify the minimum average read quality filter (Q)", + "fa_icon": "fas fa-bullseye", + "help_text": "Remove the reads with quality score lower than 7. \n\n> Modifies tool parameter(s):\n> - Nanoq: `--min-qual`" } }, "fa_icon": "fas fa-expand-alt" }, + "redundancy_estimation": { + "title": "Redundancy Estimation", + "type": "object", + "description": "Estimate metagenome sequencing complexity coverage", + "default": "", + "properties": { + "perform_shortread_redundancyestimation": { + "type": "boolean", + "description": "Turn on short-read metagenome sequencing redundancy estimation with nonpareil. Warning: only use for shallow short-read sequencing datasets.", + "fa_icon": "fas fa-toggle-on", + "help_text": "Turns on [nonpareil](https://nonpareil.readthedocs.io/en/latest/), a tool for estimating metagenome 'coverage', i.e, whether all genomes within the metagenome have had at least one read sequenced.\n\nIt estimates this by checking the read redundancy between a subsample of reads versus other reads in the library.\n\nThe more redundancy that exists, the larger the assumption that all possible reads in the library have been sequenced and all 'redundant' reads are simply sequencing of PCR duplicates.\n\nThe lower the redundancy, the more sequencing should be done until the entire metagenome has been captured. The output can be used to guide the amount of further sequencing is required.\n\nNote this is not the same as _genomic_ coverage, which is the number of times a base-pair is covered by unique reads on a reference genome.\n\nBefore using this tool please note the following caveats:\n\n- It is not recommended to run this on deep sequencing data, or very large datasets\n - Nonpareil requires uncompressed FASTQ files, and nf-core/taxprofiler will uncompress these in your working directory, potentially with a extremely large hard-drive footprint.\n- Your shortest reads _after_ processing should not go below 24bp (see warning below)\n- It is not recommended to keep unmerged (`--shortread_qc_includeunmerged`) reads when using the calculation.\n:::warning\nOn default settings, with 'kmer mode', you must make sure that your shortest processed reads do not go below 24 bp (the default kmer size).\n\nIf you have errors regarding kmer size, you will need to specify in a custom config in a process block\n\n```\n withName: NONPAREIL {\n ext.args = { \"-k \" }\n }\n```\n\nWhere `` should be at least the shortest read in your library\n:::" + }, + "shortread_redundancyestimation_mode": { + "type": "string", + "default": "kmer", + "description": "Specify mode for identifying redundant reads", + "enum": ["kmer", "alignment"], + "fa_icon": "fas fa-align-left", + "help_text": "Specify which read-comparison mode to use to check for redundancy.\n\nk-mer is faster but less precise but is recommended for FASTQ files. Alignment is more precise but is slower, it is recommended for FASTA files.\n\n> Modifies tool parameter(s):\n> - Nonpareil: `-T`" + } + }, + "fa_icon": "fas fa-chart-line" + }, "preprocessing_host_removal_options": { "title": "Preprocessing host removal options", "type": "object", @@ -347,7 +393,7 @@ "type": "boolean", "fa_icon": "fas fa-save", "description": "Save reads from samples that went through the run-merging step", - "help_text": "Save the run- and library-concatenated reads of a given sample in FASTQ format.\n\n> ⚠️ Only samples that went through the run-merging step of the pipeline will be stored in the resulting directory. \n\nIf you wish to save the files that go to the classification/profiling steps for samples that _did not_ go through run merging, you must supply the appropriate upstream `--save_` flag.\n\n" + "help_text": "Save the run- and library-concatenated reads of a given sample in FASTQ format.\n\n> \u26a0\ufe0f Only samples that went through the run-merging step of the pipeline will be stored in the resulting directory. \n\nIf you wish to save the files that go to the classification/profiling steps for samples that _did not_ go through run merging, you must supply the appropriate upstream `--save_` flag.\n\n" } }, "fa_icon": "fas fa-clipboard-check" @@ -543,7 +589,7 @@ "type": "boolean", "description": "Turn on saving of ganon per-read taxonomic assignment file(s).", "fa_icon": "fas fa-save", - "help_text": "Saves `.lca`, `.all`, and `.unc` text files that contains a list of each read that had a taxonomic assignment, with information on specific taxonomic assignment that the read received.\n\n> Modifies tool parameter(s):\n- ganon classify: `--output-all --output-lca --output-unclassified`" + "help_text": "Saves `.one`, `.all`, and `.unc` text files that contains a list of each read that had a taxonomic assignment, with information on specific taxonomic assignment that the read received.\n\n> Modifies tool parameter(s):\n- ganon classify: `--output-all --output-unclassified`" }, "ganon_report_type": { "type": "string", @@ -557,7 +603,8 @@ "type": "string", "description": "Specify the taxonomic report the ganon report file should display.", "help_text": "Specify the taxonomic rank level to report each taxonomic hit as. `all` will specify all ranks, however you can customise this from `superkingdom` through to `species` to as specific as `assembly`. ganon has a default preset, however you can customise the specific ranks in a comma separated list, e.g. `--ganon_report_rank [phylum,genus,species]`.\n\nSee the [ganon documentation](https://pirovc.github.io/ganon/outputfiles/#ganon-report) for more information of each option.\n\n> Modifies tool parameter(s):\n- ganon report: `--ranks`", - "fa_icon": "fas fa-sort-amount-down-alt" + "fa_icon": "fas fa-sort-amount-down-alt", + "default": "default" }, "ganon_report_toppercentile": { "type": "integer", @@ -910,6 +957,9 @@ { "$ref": "#/definitions/preprocessing_long_read_qc_options" }, + { + "$ref": "#/definitions/redundancy_estimation" + }, { "$ref": "#/definitions/preprocessing_host_removal_options" }, diff --git a/subworkflows/local/longread_adapterremoval.nf b/subworkflows/local/longread_adapterremoval.nf new file mode 100644 index 00000000..f32bf8d1 --- /dev/null +++ b/subworkflows/local/longread_adapterremoval.nf @@ -0,0 +1,36 @@ +// +// Process long raw reads with porechop +// + +include { PORECHOP_PORECHOP } from '../../modules/nf-core/porechop/porechop/main' +include { PORECHOP_ABI } from '../../modules/nf-core/porechop/abi/main' + +workflow LONGREAD_ADAPTERREMOVAL { + take: + reads + + main: + ch_versions = Channel.empty() + ch_multiqc_files = Channel.empty() + + if (params.longread_adapterremoval_tool == 'porechop_abi') { + PORECHOP_ABI (reads) + ch_processed_reads = PORECHOP_ABI.out.reads + .map { meta, reads -> [meta + [ single_end: true ], reads ] } + ch_versions = ch_versions.mix( PORECHOP_ABI.out.versions.first() ) + ch_multiqc_files = ch_multiqc_files.mix( PORECHOP_ABI.out.log ) + } else if (params.longread_adapterremoval_tool == 'porechop') { + PORECHOP_PORECHOP ( reads ) + ch_processed_reads = PORECHOP_PORECHOP.out.reads + .map { meta, reads -> [ meta + [single_end: true], reads ] } + ch_versions = ch_versions.mix(PORECHOP_PORECHOP.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix( PORECHOP_PORECHOP.out.log ) + } else { + ch_processed_reads = reads + } + + emit: + reads = ch_processed_reads // channel: [ val(meta), [ reads ] ] + versions = ch_versions // channel: [ versions.yml ] + mqc = ch_multiqc_files +} diff --git a/subworkflows/local/longread_filtering.nf b/subworkflows/local/longread_filtering.nf new file mode 100644 index 00000000..67cd8f2b --- /dev/null +++ b/subworkflows/local/longread_filtering.nf @@ -0,0 +1,33 @@ +// +// Check input samplesheet and get read channels +// + +include { FILTLONG } from '../../modules/nf-core/filtlong/main' +include { NANOQ } from '../../modules/nf-core/nanoq/main' + +workflow LONGREAD_FILTERING { + take: + reads // [ [ meta ], [ reads ] ] + + main: + ch_versions = Channel.empty() + ch_multiqc_files = Channel.empty() + + // fastp complexity filtering is activated via modules.conf in shortread_preprocessing + if ( params.longread_filter_tool == 'filtlong' ) { + ch_filtered_reads = FILTLONG ( reads.map { meta, reads -> [ meta, [], reads ] } ).reads + ch_versions = ch_versions.mix( FILTLONG.out.versions.first() ) + ch_multiqc_files = ch_multiqc_files.mix( FILTLONG.out.log ) + } else if ( params.longread_filter_tool == 'nanoq' ) { + ch_filtered_reads = NANOQ ( reads , 'fastq.gz' ).reads + ch_versions = ch_versions.mix( NANOQ.out.versions.first() ) + ch_multiqc_files = ch_multiqc_files.mix( NANOQ.out.stats ) + } else { + ch_filtered_reads = reads + } + + emit: + reads = ch_filtered_reads // channel: [ val(meta), [ reads ] ] + versions = ch_versions // channel: [ versions.yml ] + mqc = ch_multiqc_files +} diff --git a/subworkflows/local/longread_hostremoval.nf b/subworkflows/local/longread_hostremoval.nf index bc146d6f..7f988366 100644 --- a/subworkflows/local/longread_hostremoval.nf +++ b/subworkflows/local/longread_hostremoval.nf @@ -20,13 +20,13 @@ workflow LONGREAD_HOSTREMOVAL { ch_multiqc_files = Channel.empty() if ( !params.longread_hostremoval_index ) { - ch_minimap2_index = MINIMAP2_INDEX ( [ [], reference ] ).index.map { it[1] } + ch_minimap2_index = MINIMAP2_INDEX ( [ [], reference ] ).index ch_versions = ch_versions.mix( MINIMAP2_INDEX.out.versions ) } else { ch_minimap2_index = index } - MINIMAP2_ALIGN ( reads, ch_minimap2_index, true, false, false ) + MINIMAP2_ALIGN ( reads, ch_minimap2_index, true, 'bai', false, false ) ch_versions = ch_versions.mix( MINIMAP2_ALIGN.out.versions.first() ) ch_minimap2_mapped = MINIMAP2_ALIGN.out.bam .map { diff --git a/subworkflows/local/longread_preprocessing.nf b/subworkflows/local/longread_preprocessing.nf index 72261013..3b25879d 100644 --- a/subworkflows/local/longread_preprocessing.nf +++ b/subworkflows/local/longread_preprocessing.nf @@ -1,12 +1,12 @@ // -// Process long raw reads with porechop +// Perform read trimming and filtering // -include { FASTQC as FASTQC_PROCESSED } from '../../modules/nf-core/fastqc/main' -include { FALCO as FALCO_PROCESSED } from '../../modules/nf-core/falco/main' +include { FASTQC as FASTQC_PROCESSED } from '../../modules/nf-core/fastqc/main' +include { FALCO as FALCO_PROCESSED } from '../../modules/nf-core/falco/main' -include { PORECHOP_PORECHOP } from '../../modules/nf-core/porechop/porechop/main' -include { FILTLONG } from '../../modules/nf-core/filtlong/main' +include { LONGREAD_ADAPTERREMOVAL } from './longread_adapterremoval.nf' +include { LONGREAD_FILTERING } from './longread_filtering.nf' workflow LONGREAD_PREPROCESSING { take: @@ -17,41 +17,32 @@ workflow LONGREAD_PREPROCESSING { ch_multiqc_files = Channel.empty() if ( !params.longread_qc_skipadaptertrim && params.longread_qc_skipqualityfilter) { - PORECHOP_PORECHOP ( reads ) - - ch_processed_reads = PORECHOP_PORECHOP.out.reads - .map { meta, reads -> [ meta + [single_end: true], reads ] } - - ch_versions = ch_versions.mix(PORECHOP_PORECHOP.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix( PORECHOP_PORECHOP.out.log ) - + ch_processed_reads = LONGREAD_ADAPTERREMOVAL ( reads ).reads + ch_versions = ch_versions.mix(LONGREAD_ADAPTERREMOVAL.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix( LONGREAD_ADAPTERREMOVAL.out.mqc ) } else if ( params.longread_qc_skipadaptertrim && !params.longread_qc_skipqualityfilter) { - - ch_processed_reads = FILTLONG ( reads.map { meta, reads -> [meta, [], reads ] } ) - ch_versions = ch_versions.mix(FILTLONG.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix( FILTLONG.out.log ) - + ch_processed_reads = LONGREAD_FILTERING ( reads ).reads + ch_versions = ch_versions.mix(LONGREAD_FILTERING.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix( LONGREAD_FILTERING.out.mqc ) } else { - PORECHOP_PORECHOP ( reads ) - ch_clipped_reads = PORECHOP_PORECHOP.out.reads + LONGREAD_ADAPTERREMOVAL ( reads ) + ch_clipped_reads = LONGREAD_ADAPTERREMOVAL.out.reads .map { meta, reads -> [ meta + [single_end: true], reads ] } - - ch_processed_reads = FILTLONG ( ch_clipped_reads.map { meta, reads -> [ meta, [], reads ] } ).reads - - ch_versions = ch_versions.mix(PORECHOP_PORECHOP.out.versions.first()) - ch_versions = ch_versions.mix(FILTLONG.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix( PORECHOP_PORECHOP.out.log ) - ch_multiqc_files = ch_multiqc_files.mix( FILTLONG.out.log ) + ch_processed_reads = LONGREAD_FILTERING ( ch_clipped_reads ).reads + ch_versions = ch_versions.mix(LONGREAD_ADAPTERREMOVAL.out.versions.first()) + ch_versions = ch_versions.mix(LONGREAD_FILTERING.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix( LONGREAD_ADAPTERREMOVAL.out.mqc ) + ch_multiqc_files = ch_multiqc_files.mix( LONGREAD_FILTERING.out.mqc ) } if (params.preprocessing_qc_tool == 'fastqc') { FASTQC_PROCESSED ( ch_processed_reads ) - ch_versions = ch_versions.mix( FASTQC_PROCESSED.out.versions ) + ch_versions = ch_versions.mix( FASTQC_PROCESSED.out.versions ) ch_multiqc_files = ch_multiqc_files.mix( FASTQC_PROCESSED.out.zip ) } else if (params.preprocessing_qc_tool == 'falco') { FALCO_PROCESSED ( ch_processed_reads ) - ch_versions = ch_versions.mix( FALCO_PROCESSED.out.versions ) + ch_versions = ch_versions.mix( FALCO_PROCESSED.out.versions ) ch_multiqc_files = ch_multiqc_files.mix( FALCO_PROCESSED.out.txt ) } @@ -60,4 +51,3 @@ workflow LONGREAD_PREPROCESSING { versions = ch_versions // channel: [ versions.yml ] mqc = ch_multiqc_files } - diff --git a/subworkflows/local/nonpareil.nf b/subworkflows/local/nonpareil.nf new file mode 100644 index 00000000..e7900aa5 --- /dev/null +++ b/subworkflows/local/nonpareil.nf @@ -0,0 +1,73 @@ +include { NONPAREIL_NONPAREIL } from '../../modules/nf-core/nonpareil/nonpareil/main' +include { NONPAREIL_CURVE } from '../../modules/nf-core/nonpareil/curve/main' +include { NONPAREIL_SET } from '../../modules/nf-core/nonpareil/set/main' +include { NONPAREIL_NONPAREILCURVESR } from '../../modules/nf-core/nonpareil/nonpareilcurvesr/main' + +// Custom Functions + +/* + +*/ +def extractNonpareilExtensionFromArrays(ch_input) { + +return ch_profile + .map { meta, profile -> [meta.db_name, meta, profile] } + .combine(ch_database, by: 0) + .multiMap { + key, meta, profile, db_meta, db -> + profile: [meta, profile] + db: db + } +} + +workflow NONPAREIL { + take: + reads // [ [ meta ], [ reads ] ] + + main: + ch_versions = Channel.empty() + ch_multiqc_files = Channel.empty() + + ch_reads_for_nonpareil = reads + .map { + meta, reads -> + def reads_new = meta.single_end ? reads : reads[0] + def format = reads_new[0].getBaseName().split('\\.').last() in ['fasta', 'fna', 'fa', 'fas'] ? 'fasta' : 'fastq' + + [meta, reads_new, format] + } + .multiMap { + meta, reads, format -> + reads: [meta, reads] + format: format + } + + // Calculation + NONPAREIL_NONPAREIL( ch_reads_for_nonpareil.reads, ch_reads_for_nonpareil.format, params.shortread_redundancyestimation_mode) + + ch_npos_for_nonparielset = NONPAREIL_NONPAREIL.out.npo + .map {meta, npo -> [[id: 'all'], npo] } + .groupTuple() + + // Plotting + NONPAREIL_CURVE ( NONPAREIL_NONPAREIL.out.npo ) // For static single-curve PNG + NONPAREIL_SET ( ch_npos_for_nonparielset ) // For static multi-curve PNG + NONPAREIL_NONPAREILCURVESR ( ch_npos_for_nonparielset ) // For dynamic multi-curve PNG in MultiQC and raw files + + ch_versions = ch_versions + .mix( + NONPAREIL_NONPAREIL.out.versions.first(), + NONPAREIL_CURVE.out.versions.first(), + NONPAREIL_SET.out.versions.first(), + NONPAREIL_NONPAREILCURVESR.out.versions.first() + ) + ch_multiqc_files = ch_multiqc_files.mix( NONPAREIL_NONPAREILCURVESR.out.json ) + + emit: + npo = NONPAREIL_NONPAREIL.out.npo + curve_pngs = NONPAREIL_CURVE.out.png + set_pngs = NONPAREIL_SET.out.png + nonpareilcurvesr = NONPAREIL_NONPAREILCURVESR.out.tsv + versions = ch_versions + mqc = ch_multiqc_files +} diff --git a/subworkflows/local/profiling.nf b/subworkflows/local/profiling.nf index 09b8ac19..5e4570ce 100644 --- a/subworkflows/local/profiling.nf +++ b/subworkflows/local/profiling.nf @@ -60,26 +60,47 @@ workflow PROFILING { COMBINE READS WITH POSSIBLE DATABASES */ - // e.g. output [DUMP: reads_plus_db] [['id':'2612', 'run_accession':'combined', 'instrument_platform':'ILLUMINA', 'single_end':true], /2612.merged.fastq.gz, ['tool':'malt', 'db_name':'mal95', 'db_params':'"-id 90"'], /malt90] + // Separate default 'short;long' (when necessary) databases when short/long specified in database sheet + ch_dbs = databases + .map{ + meta_db, db -> + [ [meta_db.db_type.split(";")].flatten(), meta_db, db] + } + .transpose(by: 0) + .map{ + type, meta_db, db -> + [[type: type], meta_db.subMap(meta_db.keySet() - 'db_type') + [type: type], db] + } + + // Join short and long reads with their corresponding short/long database + // Note that for not-specified `short;long`, it will match with the database. + // E.g. if there is no 'long' reads the above generted 'long' database channel element + // will have nothing to join to and will be discarded + // Final output: [DUMP: reads_plus_db] [['id':'2612', 'run_accession':'combined', 'instrument_platform':'ILLUMINA', 'single_end':1], /2612.merged.fastq.gz, ['tool':'malt', 'db_name':'mal95', 'db_params':'"-id 90"'], /malt90] + ch_input_for_profiling = reads - .map { - meta, reads -> - [meta + [id: "${meta.id}${meta.single_end ? '_se' : '_pe'}"], reads] - } - .combine(databases) - .branch { - centrifuge: it[2]['tool'] == 'centrifuge' - diamond: it[2]['tool'] == 'diamond' - kaiju: it[2]['tool'] == 'kaiju' - kraken2: it[2]['tool'] == 'kraken2' || it[2]['tool'] == 'bracken' // to reuse the kraken module to produce the input data for bracken - krakenuniq: it[2]['tool'] == 'krakenuniq' - malt: it[2]['tool'] == 'malt' - metaphlan: it[2]['tool'] == 'metaphlan' - motus: it[2]['tool'] == 'motus' - kmcp: it[2]['tool'] == 'kmcp' - ganon: it[2]['tool'] == 'ganon' - unknown: true - } + .map{ + meta, reads -> + [[type: meta.type], meta, reads] + } + .combine(ch_dbs, by: 0) + .map{ + db_type, meta, reads, db_meta, db -> + [ meta, reads, db_meta, db ] + } + .branch { meta, reads, db_meta, db -> + centrifuge: db_meta.tool == 'centrifuge' + diamond: db_meta.tool == 'diamond' + kaiju: db_meta.tool == 'kaiju' + kraken2: db_meta.tool == 'kraken2' || db_meta.tool == 'bracken' // to reuse the kraken module to produce the input data for bracken + krakenuniq: db_meta.tool == 'krakenuniq' + malt: db_meta.tool == 'malt' + metaphlan: db_meta.tool == 'metaphlan' + motus: db_meta.tool == 'motus' + kmcp: db_meta.tool == 'kmcp' + ganon: db_meta.tool == 'ganon' + unknown: true + } /* PREPARE PROFILER INPUT CHANNELS & RUN PROFILING @@ -322,12 +343,16 @@ workflow PROFILING { if ( params.run_diamond ) { ch_input_for_diamond = ch_input_for_profiling.diamond + .filter { + meta, reads, meta_db, db -> + if (!meta.single_end) log.warn "[nf-core/taxprofiler] DIAMOND does not accept paired-end files as input. To run DIAMOND on this sample, please merge reads (e.g. with --shortread_qc_mergepairs). Skipping DIAMOND for sample ${meta.id}." + meta.single_end + } .multiMap { it -> reads: [it[0] + it[2], it[1]] - db: it[3] + db: [ it[2], it[3] ] } - // diamond only accepts single output file specification, therefore // this will replace output file! ch_diamond_reads_format = params.diamond_save_reads ? 'sam' : params.diamond_output_format diff --git a/subworkflows/local/shortread_fastp.nf b/subworkflows/local/shortread_fastp.nf index ac421854..0da50f37 100644 --- a/subworkflows/local/shortread_fastp.nf +++ b/subworkflows/local/shortread_fastp.nf @@ -20,9 +20,9 @@ workflow SHORTREAD_FASTP { paired: it[0]['single_end'] == false } - FASTP_SINGLE ( ch_input_for_fastp.single, adapterlist, false, false ) + FASTP_SINGLE ( ch_input_for_fastp.single, adapterlist, false, false, false ) // Last parameter here turns on merging of PE data - FASTP_PAIRED ( ch_input_for_fastp.paired, adapterlist, false, params.shortread_qc_mergepairs ) + FASTP_PAIRED ( ch_input_for_fastp.paired, adapterlist, false, false, params.shortread_qc_mergepairs ) if ( params.shortread_qc_mergepairs ) { ch_fastp_reads_prepped_pe = FASTP_PAIRED.out.reads_merged diff --git a/subworkflows/local/shortread_hostremoval.nf b/subworkflows/local/shortread_hostremoval.nf index 32d64749..355b3c2e 100644 --- a/subworkflows/local/shortread_hostremoval.nf +++ b/subworkflows/local/shortread_hostremoval.nf @@ -25,15 +25,15 @@ workflow SHORTREAD_HOSTREMOVAL { } // Map, generate BAM with all reads and unmapped reads in FASTQ for downstream - BOWTIE2_ALIGN ( reads, ch_bowtie2_index, true, true) + BOWTIE2_ALIGN ( reads, ch_bowtie2_index, [ [], reference ], true, true) ch_versions = ch_versions.mix( BOWTIE2_ALIGN.out.versions.first() ) ch_multiqc_files = ch_multiqc_files.mix( BOWTIE2_ALIGN.out.log ) // Indexing whole BAM for host removal statistics - SAMTOOLS_INDEX ( BOWTIE2_ALIGN.out.aligned ) + SAMTOOLS_INDEX ( BOWTIE2_ALIGN.out.bam ) ch_versions = ch_versions.mix( SAMTOOLS_INDEX.out.versions.first() ) - bam_bai = BOWTIE2_ALIGN.out.aligned + bam_bai = BOWTIE2_ALIGN.out.bam .join(SAMTOOLS_INDEX.out.bai, remainder: true) SAMTOOLS_STATS ( bam_bai, [[],reference] ) diff --git a/subworkflows/local/utils_nfcore_taxprofiler_pipeline/main.nf b/subworkflows/local/utils_nfcore_taxprofiler_pipeline/main.nf index 96ef64f2..9a224154 100644 --- a/subworkflows/local/utils_nfcore_taxprofiler_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_taxprofiler_pipeline/main.nf @@ -85,16 +85,15 @@ workflow PIPELINE_INITIALISATION { .fromSamplesheet("input") .set { ch_samplesheet } - emit: - samplesheet = ch_samplesheet - versions = ch_versions - -// Create channel from databases file provided through params.databases + // + // Create channel from databases file provided through params.databases + // Channel .fromSamplesheet("databases") .set {ch_databases} emit: + samplesheet = ch_samplesheet databases = ch_databases versions = ch_versions } @@ -193,7 +192,7 @@ def genomeExistsError() { // def toolCitationText() { def text_seq_qc = [ - "Sequencing quality control was carried out with:", + "Sequencing quality control with", params.preprocessing_qc_tool == "falco" ? "Falco (de Sena Brandine and Smith 2021)." : "FastQC (Andrews 2010)." ].join(' ').trim() @@ -203,11 +202,17 @@ def toolCitationText() { params.shortread_qc_tool == "fastp" ? "fastp (Chen et al. 2018)." : "", ].join(' ').trim() + + def text_shortread_redundancy = [ + "Short-read reference-free metagenome coverage estimation was performed with Nonpareil (Rodriguez-R et al. 2018)." + ].join(' ').trim() + def text_longread_qc = [ "Long read preprocessing was performed with:", - !params.longread_qc_skipadaptertrim ? "Porechop (Wick et al. 2017)," : "", - !params.longread_qc_skipqualityfilter ? "Filtlong (Wick 2021)," : "", - "." + params.longread_adapterremoval_tool == "porechop_abi" ? "Porechop_ABI (Bonenfant et al. 2023)," : "", + params.longread_adapterremoval_tool == "porechop" ? "Porechop (Wick et al. 2017)," : "", + params.longread_filter_tool == "filtlong" ? "Filtlong (Wick 2021)," : "", + params.longread_filter_tool == "nanoq" ? "Nanoq (Steinig and Coin 2022)." : "", ].join(' ').trim() def text_shortreadcomplexity = [ @@ -253,14 +258,16 @@ def toolCitationText() { def citation_text = [ "Tools used in the workflow included:", text_seq_qc, - params.perform_shortread_qc ? text_shortread_qc : "", - params.perform_longread_qc ? text_longread_qc : "", - params.perform_shortread_complexityfilter ? text_shortreadcomplexity : "", - params.perform_shortread_hostremoval ? text_shortreadhostremoval : "", - params.perform_longread_hostremoval ? text_longreadhostremoval : "", - text_classification, - params.run_krona ? text_visualisation : "", - params.run_profile_standardisation ? text_postprocessing : "", + params.perform_shortread_qc ? text_shortread_qc : "", + params.perform_shortread_redundancyestimation ? text_shortread_redundancy : "", + params.perform_longread_qc ? text_longread_qc : "", + params.perform_shortread_complexityfilter ? text_shortreadcomplexity : "", + params.perform_shortread_hostremoval ? text_shortreadhostremoval : "", + params.perform_longread_hostremoval ? text_longreadhostremoval : "", + [params.run_bracken, params.run_kraken2, params.run_krakenuniq, params.run_metaphlan, params.run_malt, params.run_diamond, params.run_centrifuge, params.run_kaiju, params.run_motus, params.run_ganon, params.run_kmcp].any() ? + text_classification : "", + params.run_krona ? text_visualisation : "", + params.run_profile_standardisation ? text_postprocessing : "", "Pipeline results statistics were summarised with MultiQC (Ewels et al. 2016)." ].join(' ').trim().replaceAll("[,|.] +\\.", ".") @@ -278,9 +285,15 @@ def toolBibliographyText() { params.shortread_qc_tool == "adapterremoval" ? "
  • Schubert, M., Lindgreen, S., & Orlando, L. (2016). AdapterRemoval v2: rapid adapter trimming, identification, and read merging. BMC Research Notes, 9, 88. 10.1186/s13104-016-1900-2
  • " : "", ].join(' ').trim() + def text_shortread_redundancy = [ + "
  • Rodriguez-R, L. M., Gunturu, S., Tiedje, J. M., Cole, J. R., & Konstantinidis, K. T. (2018). Nonpareil 3: Fast Estimation of Metagenomic Coverage and Sequence Diversity. mSystems, 3(3). 10.1128/mSystems.00039-18
  • ", + ].join(' ').trim() + def text_longread_qc = [ - !params.longread_qc_skipadaptertrim ? "
  • Wick, R. R., Judd, L. M., Gorrie, C. L., & Holt, K. E. (2017). Completing bacterial genome assemblies with multiplex MinION sequencing. Microbial Genomics, 3(10), e000132. 10.1099/mgen.0.000132
  • " : "", - !params.longread_qc_skipqualityfilter ? "
  • Wick R. (2021) Filtlong, URL: https://github.com/rrwick/Filtlong
  • " : "" + params.longread_adapterremoval_tool == "porechop_abi" ? "
  • Bonenfant, Q., Noé, L., & Touzet, H. (2023). Porechop_ABI: discovering unknown adapters in Oxford Nanopore Technology sequencing reads for downstream trimming. Bioinformatics Advances, 3(1):vbac085. 10.1093/bioadv/vbac085
  • " : "", + params.longread_adapterremoval_tool == "porechop" ? "
  • Wick, R. R., Judd, L. M., Gorrie, C. L., & Holt, K. E. (2017). Completing bacterial genome assemblies with multiplex MinION sequencing. Microbial Genomics, 3(10), e000132. 10.1099/mgen.0.000132
  • " : "", + params.longread_filter_tool == "filtlong" ? "
  • Wick R. (2021) Filtlong, URL: https://github.com/rrwick/Filtlong
  • " : "", + params.longread_filter_tool == "nanoq" ? "
  • Steinig, E., & Coin, L. (2022). Nanoq: ultra-fast quality control for nanopore reads. Journal of Open Source Software, 7(69). 10.21105/joss.02991
  • " : "" ].join(' ').trim() def text_shortreadcomplexity = [ @@ -363,13 +376,11 @@ def methodsDescriptionText( mqc_methods_yaml ) { } 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.
  • " - 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 diff --git a/subworkflows/local/visualization_krona.nf b/subworkflows/local/visualization_krona.nf index 77e26a22..eb9b6cf6 100644 --- a/subworkflows/local/visualization_krona.nf +++ b/subworkflows/local/visualization_krona.nf @@ -99,6 +99,7 @@ workflow VISUALIZATION_KRONA { KRONA_KTIMPORTTAXONOMY ( ch_krona_taxonomy_for_input, file(params.krona_taxonomy_directory, checkExists: true) ) ch_krona_html.mix( KRONA_KTIMPORTTAXONOMY.out.html ) + ch_versions = ch_versions.mix ( GUNZIP.out.versions.first() ) ch_versions = ch_versions.mix( MEGAN_RMA2INFO_KRONA.out.versions.first() ) ch_versions = ch_versions.mix( KRONA_KTIMPORTTAXONOMY.out.versions.first() ) } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index ac31f28f..28e32b20 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -2,10 +2,6 @@ // Subworkflow with functionality that may be useful for any Nextflow pipeline // -import org.yaml.snakeyaml.Yaml -import groovy.json.JsonOutput -import nextflow.extension.FilesEx - /* ======================================================================================== SUBWORKFLOW DEFINITION @@ -58,7 +54,7 @@ workflow UTILS_NEXTFLOW_PIPELINE { // Generate version string // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -79,10 +75,10 @@ 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 = JsonOutput.toJson(params) - temp_pf.text = JsonOutput.prettyPrint(jsonStr) + def jsonStr = groovy.json.JsonOutput.toJson(params) + temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") temp_pf.delete() } @@ -90,7 +86,7 @@ def dumpParametersToJSON(outdir) { // When running with -profile conda, warn if channels have not been set-up appropriately // def checkCondaChannels() { - Yaml parser = new Yaml() + def parser = new org.yaml.snakeyaml.Yaml() def channels = [] try { def config = parser.load("conda config --show channels".execute().text) @@ -102,14 +98,16 @@ def checkCondaChannels() { // Check that all channels are present // This channel list is ordered by required channel priority. - def required_channels_in_order = ['conda-forge', 'bioconda', 'defaults'] + def required_channels_in_order = ['conda-forge', 'bioconda'] def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean // Check that they are in the right order def channel_priority_violation = false - def n = required_channels_in_order.size() - for (int i = 0; i < n - 1; i++) { - channel_priority_violation |= !(channels.indexOf(required_channels_in_order[i]) < channels.indexOf(required_channels_in_order[i+1])) + + required_channels_in_order.eachWithIndex { channel, index -> + if (index < required_channels_in_order.size() - 1) { + channel_priority_violation |= !(channels.indexOf(channel) < channels.indexOf(required_channels_in_order[index+1])) + } } if (channels_missing | channel_priority_violation) { diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config index d0a926bf..a09572e5 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config @@ -3,7 +3,7 @@ manifest { author = """nf-core""" homePage = 'https://127.0.0.1' description = """Dummy pipeline""" - nextflowVersion = '!>=23.04.0' + nextflowVersion = '!>=23.04.0' version = '9.9.9' doi = 'https://doi.org/10.5281/zenodo.5070524' } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 14558c39..cbd8495b 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -2,9 +2,6 @@ // Subworkflow with utility functions specific to the nf-core pipeline template // -import org.yaml.snakeyaml.Yaml -import nextflow.extension.FilesEx - /* ======================================================================================== SUBWORKFLOW DEFINITION @@ -34,7 +31,7 @@ workflow UTILS_NFCORE_PIPELINE { // Warn if a -profile or Nextflow config has not been provided to run the pipeline // def checkConfigProvided() { - valid_config = true + def valid_config = true as Boolean if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { log.warn "[$workflow.manifest.name] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + @@ -66,11 +63,13 @@ def checkProfileProvided(nextflow_cli_args) { // def workflowCitation() { def temp_doi_ref = "" - String[] manifest_doi = workflow.manifest.doi.tokenize(",") + def manifest_doi = workflow.manifest.doi.tokenize(",") // Using a loop to handle multiple DOIs // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers // Removing ` ` since the manifest.doi is a string and not a proper list - for (String doi_ref: manifest_doi) temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" + manifest_doi.each { doi_ref -> + temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" + } return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + "* The pipeline\n" + temp_doi_ref + "\n" + @@ -84,7 +83,7 @@ def workflowCitation() { // Generate workflow version string // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -102,8 +101,8 @@ def getWorkflowVersion() { // Get software versions for pipeline // def processVersionsFromYAML(yaml_file) { - Yaml yaml = new Yaml() - versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } + def yaml = new org.yaml.snakeyaml.Yaml() + def versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } return yaml.dumpAsMap(versions).trim() } @@ -124,7 +123,7 @@ def workflowVersionToYAML() { def softwareVersionsToYAML(ch_versions) { return ch_versions .unique() - .map { processVersionsFromYAML(it) } + .map { version -> processVersionsFromYAML(version) } .unique() .mix(Channel.of(workflowVersionToYAML())) } @@ -134,19 +133,19 @@ def softwareVersionsToYAML(ch_versions) { // def paramsSummaryMultiqc(summary_params) { def summary_section = '' - for (group in summary_params.keySet()) { + summary_params.keySet().each { group -> def group_params = summary_params.get(group) // This gets the parameters of that particular group if (group_params) { summary_section += "

    $group

    \n" summary_section += "
    \n" - for (param in group_params.keySet()) { + group_params.keySet().sort().each { param -> summary_section += "
    $param
    ${group_params.get(param) ?: 'N/A'}
    \n" } summary_section += "
    \n" } } - String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" + def yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" as String yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" @@ -161,7 +160,7 @@ def paramsSummaryMultiqc(summary_params) { // nf-core logo // def nfCoreLogo(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map String.format( """\n ${dashedLine(monochrome_logs)} @@ -180,7 +179,7 @@ def nfCoreLogo(monochrome_logs=true) { // Return dashed line // def dashedLine(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map return "-${colors.dim}----------------------------------------------------${colors.reset}-" } @@ -188,7 +187,7 @@ def dashedLine(monochrome_logs=true) { // ANSII colours used for terminal logging // def logColours(monochrome_logs=true) { - Map colorcodes = [:] + def colorcodes = [:] as Map // Reset / Meta colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" @@ -287,7 +286,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi } def summary = [:] - for (group in summary_params.keySet()) { + summary_params.keySet().sort().each { group -> summary << summary_params[group] } @@ -344,10 +343,10 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi def sendmail_html = sendmail_template.toString() // Send the HTML e-mail - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (email_address) { try { - if (plaintext_email) { throw GroovyException('Send plaintext e-mail, not HTML') } + if (plaintext_email) { throw new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') } // Try to send HTML e-mail using sendmail def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") sendmail_tf.withWriter { w -> w << sendmail_html } @@ -364,13 +363,13 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Write summary e-mail HTML to a file def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") output_hf.withWriter { w -> w << email_html } - FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); + nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); output_hf.delete() // Write summary e-mail TXT to a file def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") output_tf.withWriter { w -> w << email_txt } - FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); + nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); output_tf.delete() } @@ -378,7 +377,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Print pipeline summary on completion // def completionSummary(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (workflow.success) { if (workflow.stats.ignoredCount == 0) { log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" @@ -395,7 +394,7 @@ def completionSummary(monochrome_logs=true) { // def imNotification(summary_params, hook_url) { def summary = [:] - for (group in summary_params.keySet()) { + summary_params.keySet().sort().each { group -> summary << summary_params[group] } diff --git a/tower.yml b/tower.yml index 787aedfe..1101572e 100644 --- a/tower.yml +++ b/tower.yml @@ -1,5 +1,59 @@ reports: multiqc_report.html: display: "MultiQC HTML report" - samplesheet.csv: - display: "Auto-created samplesheet with collated metadata and FASTQ paths" + "**/fastqc/raw/*.html": + display: "A FastQC report containing quality metrics of raw reads in HTML format." + "**/fastqc/raw/*.txt": + display: "A FastQC report containing quality metrics of raw reads in TXT format." + "**/fastqc/preprocessed/*.html": + display: "A FastQC report containing quality metrics of processed reads in HTML format." + "**/fastqc/preprocessed/*.txt": + display: "A FastQC report containing quality metrics of processed reads in TXT format." + "**/falco/raw/*.html": + display: "A Falco report containing quality metrics of raw reads in HTML format." + "**/falco/raw/*.txt": + display: "A Falco report containing quality metrics of raw reads in TXT format." + "**/falco/preprocessed/*.html": + display: "A Falco report containing quality metrics of processed reads in HTML format." + "**/falco/preprocessed/*.txt": + display: "A Falco report containing quality metrics of processed reads in TXT format." + "**/fastp/*.html": + display: "A Log file in HTML format." + "**/bracken/*_combined_reports.txt": + display: "Combined bracken results as output from Bracken's combine_bracken_outputs.py script." + "**/bracken/*/*.tsv": + display: "A TSV file containing per-sample summary of Bracken results with abundance information." + "**/bracken/*/*report_bracken_species.txt": + display: "A Kraken2 style report with Bracken abundance information." + "**/kraken2/kraken2_*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by krakentools)." + "**/kraken2/*/*.kraken2.report.txt": + display: "A Kraken2 report that summarises the fraction abundance, taxonomic ID, number of Kmers, taxonomic path of all the hits in the Kraken2 run for a given sample. Will be 6 column rather than 8 if --save_minimizers specified." + "**/krakenuniq/*.krakenuniq.report.txt": + display: "A Kraken2-style report that summarises the fraction abundance, taxonomic ID, number of Kmers, taxonomic path of all the hits, with an additional column for k-mer coverage, that allows for more accurate distinguishing between false-positive/true-postitive hits." + "**/krakenuniq/*.krakenuniq.classified.txt": + display: "An optional list of read IDs and the hits each read had against each database for a given sample." + "**/centrifuge/*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by centrifuge-kreport)." + "**/centrifuge/*/*.centrifuge.report.txt": + display: "A classification report that summarises the taxonomic ID, the taxonomic rank, length of genome sequence, number of classified and uniquely classified reads." + "**/centrifuge/*/*.centrifuge.txt": + display: "A Kraken2-style report that summarises the fraction abundance, taxonomic ID, number of k-mers, taxonomic path of all the hits in the centrifuge run for a given sample." + "**/ganon/*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by ganon table)." + "**/kaiju/*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by kaiju2table)" + "**/kaiju/*/*.kaijutable.txt": + display: "Summarised Kaiju output with fraction abundance, taxonomic ID, number of reads, and taxonomic names (as generated by kaiju2table)" + "**/krona/*.html": + display: "Per-tool/per-database interactive HTML file containing hierarchical piecharts." + "**/metaphlan/*/*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by metaphlan_merge_tables)." + "**/metaphlan/*/*.bowtie2out.txt": + display: "Bowtie2 alignment information (can be re-used for skipping alignment when re-running MetaPhlAn with different parameters)." + "**/metaphlan/*/*_profile.txt": + display: "A MetaPhlAn taxonomic profile including abundance estimates." + "**/motus/*/*_combined_reports.txt": + display: "A combined profile of all samples aligned to a given database (as generated by motus_merge)." + "**/taxpasta/*tsv": + display: "Standardised taxon table containing multiple samples. The first column describes the taxonomy ID and the rest of the columns describe the read counts for each sample." diff --git a/workflows/taxprofiler.nf b/workflows/taxprofiler.nf index b3f93526..93eb55dd 100644 --- a/workflows/taxprofiler.nf +++ b/workflows/taxprofiler.nf @@ -64,6 +64,7 @@ if ( [params.taxpasta_add_name, params.taxpasta_add_rank, params.taxpasta_add_li // include { SHORTREAD_PREPROCESSING } from '../subworkflows/local/shortread_preprocessing' +include { NONPAREIL } from '../subworkflows/local/nonpareil' include { LONGREAD_PREPROCESSING } from '../subworkflows/local/longread_preprocessing' include { SHORTREAD_HOSTREMOVAL } from '../subworkflows/local/shortread_hostremoval' include { LONGREAD_HOSTREMOVAL } from '../subworkflows/local/longread_hostremoval' @@ -134,13 +135,16 @@ workflow TAXPROFILER { } .branch { meta, run_accession, instrument_platform, fastq_1, fastq_2, fasta -> fastq: meta.single_end || fastq_2 - return [ meta, fastq_2 ? [ fastq_1, fastq_2 ] : [ fastq_1 ] ] + return [ meta + [ type: "short" ], fastq_2 ? [ fastq_1, fastq_2 ] : [ fastq_1 ] ] nanopore: instrument_platform == 'OXFORD_NANOPORE' && !meta.is_fasta meta.single_end = true - return [ meta, [ fastq_1 ] ] - fasta: meta.is_fasta + return [ meta + [ type: "long" ], [ fastq_1 ] ] + fasta_short: meta.is_fasta && instrument_platform == 'ILLUMINA' meta.single_end = true - return [ meta, [ fasta ] ] + return [ meta + [ type: "short" ], [ fasta ] ] + fasta_long: meta.is_fasta && instrument_platform == 'OXFORD_NANOPORE' + meta.single_end = true + return [ meta + [ type: "long" ], [ fasta ] ] } // Merge ch_input.fastq and ch_input.nanopore into a single channel @@ -149,6 +153,9 @@ workflow TAXPROFILER { // Validate and decompress databases ch_dbs_for_untar = databases .branch { db_meta, db_path -> + if ( !db_meta.db_type ) { + db_meta = db_meta + [ db_type: "short;long" ] + } untar: db_path.name.endsWith( ".tar.gz" ) skip: true } @@ -218,6 +225,15 @@ workflow TAXPROFILER { ch_longreads_preprocessed = ch_input.nanopore } + /* + MODULE: REDUNDANCY ESTIMATION + */ + + if ( params.perform_shortread_redundancyestimation ) { + NONPAREIL ( ch_shortreads_preprocessed ) + ch_versions = ch_versions.mix( NONPAREIL.out.versions ) + } + /* SUBWORKFLOW: COMPLEXITY FILTERING */ @@ -276,13 +292,13 @@ workflow TAXPROFILER { meta, reads -> [ meta, [ reads ].flatten() ] } - .mix( ch_input.fasta ) + .mix( ch_input.fasta_short, ch_input.fasta_long) ch_versions = ch_versions.mix(MERGE_RUNS.out.versions) } else { ch_reads_runmerged = ch_shortreads_hostremoved - .mix( ch_longreads_hostremoved, ch_input.fasta ) + .mix( ch_longreads_hostremoved, ch_input.fasta_short, ch_input.fasta_long ) } /* @@ -376,6 +392,10 @@ workflow TAXPROFILER { ch_multiqc_files = ch_multiqc_files.mix( LONGREAD_PREPROCESSING.out.mqc.collect{it[1]}.ifEmpty([]) ) } + if ( params.perform_shortread_redundancyestimation ) { + ch_multiqc_files = ch_multiqc_files.mix( NONPAREIL.out.mqc.collect{it[1]}.ifEmpty([]) ) + } + if (params.perform_shortread_complexityfilter && params.shortread_complexityfilter_tool != 'fastp'){ ch_multiqc_files = ch_multiqc_files.mix( SHORTREAD_COMPLEXITYFILTERING.out.mqc.collect{it[1]}.ifEmpty([]) ) } @@ -398,7 +418,9 @@ workflow TAXPROFILER { ch_multiqc_files.collect(), ch_multiqc_config.toList(), ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList() + ch_multiqc_logo.toList(), + [], + [] ) emit: