From 3be641de99d29e10ea49b9566673d05e8010d527 Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Thu, 28 Aug 2025 06:38:49 -0300 Subject: [PATCH 1/3] Add hostile --- modules.json | 15 +++ modules/nf-core/bowtie2/build/environment.yml | 13 ++ modules/nf-core/bowtie2/build/main.nf | 42 ++++++ modules/nf-core/bowtie2/build/meta.yml | 53 ++++++++ .../nf-core/bowtie2/build/tests/main.nf.test | 31 +++++ .../bowtie2/build/tests/main.nf.test.snap | 49 +++++++ modules/nf-core/hostile/clean/environment.yml | 8 ++ modules/nf-core/hostile/clean/main.nf | 78 +++++++++++ modules/nf-core/hostile/clean/meta.yml | 86 +++++++++++++ .../nf-core/hostile/clean/tests/main.nf.test | 121 ++++++++++++++++++ .../hostile/clean/tests/main.nf.test.snap | 98 ++++++++++++++ .../hostile/clean/tests/nextflow.config | 5 + modules/nf-core/hostile/fetch/environment.yml | 8 ++ modules/nf-core/hostile/fetch/main.nf | 55 ++++++++ modules/nf-core/hostile/fetch/meta.yml | 48 +++++++ .../nf-core/hostile/fetch/tests/main.nf.test | 59 +++++++++ .../hostile/fetch/tests/main.nf.test.snap | 90 +++++++++++++ .../hostile/fetch/tests/nextflow.config | 5 + .../local/preprocessing_shortread/main.nf | 84 ++++++------ 19 files changed, 912 insertions(+), 36 deletions(-) create mode 100644 modules/nf-core/bowtie2/build/environment.yml create mode 100644 modules/nf-core/bowtie2/build/main.nf create mode 100644 modules/nf-core/bowtie2/build/meta.yml create mode 100644 modules/nf-core/bowtie2/build/tests/main.nf.test create mode 100644 modules/nf-core/bowtie2/build/tests/main.nf.test.snap create mode 100644 modules/nf-core/hostile/clean/environment.yml create mode 100644 modules/nf-core/hostile/clean/main.nf create mode 100644 modules/nf-core/hostile/clean/meta.yml create mode 100644 modules/nf-core/hostile/clean/tests/main.nf.test create mode 100644 modules/nf-core/hostile/clean/tests/main.nf.test.snap create mode 100644 modules/nf-core/hostile/clean/tests/nextflow.config create mode 100644 modules/nf-core/hostile/fetch/environment.yml create mode 100644 modules/nf-core/hostile/fetch/main.nf create mode 100644 modules/nf-core/hostile/fetch/meta.yml create mode 100644 modules/nf-core/hostile/fetch/tests/main.nf.test create mode 100644 modules/nf-core/hostile/fetch/tests/main.nf.test.snap create mode 100644 modules/nf-core/hostile/fetch/tests/nextflow.config diff --git a/modules.json b/modules.json index 22b7b3fdb..881d9d143 100644 --- a/modules.json +++ b/modules.json @@ -31,6 +31,11 @@ "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", "installed_by": ["modules"] }, + "bowtie2/build": { + "branch": "master", + "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", + "installed_by": ["modules"] + }, "busco/busco": { "branch": "master", "git_sha": "36c6c8445284e021d95ce30cdf743baef66b21aa", @@ -196,6 +201,16 @@ "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", "installed_by": ["modules"] }, + "hostile/clean": { + "branch": "master", + "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", + "installed_by": ["modules"] + }, + "hostile/fetch": { + "branch": "master", + "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", + "installed_by": ["modules"] + }, "maxbin2": { "branch": "master", "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", diff --git a/modules/nf-core/bowtie2/build/environment.yml b/modules/nf-core/bowtie2/build/environment.yml new file mode 100644 index 000000000..066ff52e0 --- /dev/null +++ b/modules/nf-core/bowtie2/build/environment.yml @@ -0,0 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/bowtie2 + - bioconda::bowtie2=2.5.4 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.21 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.21 + - conda-forge::pigz=2.8 diff --git a/modules/nf-core/bowtie2/build/main.nf b/modules/nf-core/bowtie2/build/main.nf new file mode 100644 index 000000000..fb7effec4 --- /dev/null +++ b/modules/nf-core/bowtie2/build/main.nf @@ -0,0 +1,42 @@ +process BOWTIE2_BUILD { + tag "$fasta" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b4/b41b403e81883126c3227fc45840015538e8e2212f13abc9ae84e4b98891d51c/data' : + 'community.wave.seqera.io/library/bowtie2_htslib_samtools_pigz:edeb13799090a2a6' }" + + input: + tuple val(meta), path(fasta) + + output: + tuple val(meta), path('bowtie2') , emit: index + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + mkdir bowtie2 + bowtie2-build $args --threads $task.cpus $fasta bowtie2/${fasta.baseName} + cat <<-END_VERSIONS > versions.yml + "${task.process}": + bowtie2: \$(echo \$(bowtie2 --version 2>&1) | sed 's/^.*bowtie2-align-s version //; s/ .*\$//') + END_VERSIONS + """ + + stub: + """ + mkdir bowtie2 + touch bowtie2/${fasta.baseName}.{1..4}.bt2 + touch bowtie2/${fasta.baseName}.rev.{1,2}.bt2 + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + bowtie2: \$(echo \$(bowtie2 --version 2>&1) | sed 's/^.*bowtie2-align-s version //; s/ .*\$//') + END_VERSIONS + """ +} diff --git a/modules/nf-core/bowtie2/build/meta.yml b/modules/nf-core/bowtie2/build/meta.yml new file mode 100644 index 000000000..3e83ecb42 --- /dev/null +++ b/modules/nf-core/bowtie2/build/meta.yml @@ -0,0 +1,53 @@ +name: bowtie2_build +description: Builds bowtie index for reference genome +keywords: + - build + - index + - fasta + - genome + - reference +tools: + - bowtie2: + description: | + Bowtie 2 is an ultrafast and memory-efficient tool for aligning + sequencing reads to long reference sequences. + homepage: http://bowtie-bio.sourceforge.net/bowtie2/index.shtml + documentation: http://bowtie-bio.sourceforge.net/bowtie2/manual.shtml + doi: 10.1038/nmeth.1923 + licence: ["GPL-3.0-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Input genome fasta file + ontologies: [] +output: + index: + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test', single_end:false ] + - bowtie2: + type: file + description: Bowtie2 genome index files + pattern: "*.bt2" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@joseespinosa" + - "@drpatelh" +maintainers: + - "@joseespinosa" + - "@drpatelh" diff --git a/modules/nf-core/bowtie2/build/tests/main.nf.test b/modules/nf-core/bowtie2/build/tests/main.nf.test new file mode 100644 index 000000000..ee94c19c9 --- /dev/null +++ b/modules/nf-core/bowtie2/build/tests/main.nf.test @@ -0,0 +1,31 @@ +nextflow_process { + + name "Test Process BOWTIE2_BUILD" + script "../main.nf" + process "BOWTIE2_BUILD" + tag "modules" + tag "modules_nfcore" + tag "bowtie2" + tag "bowtie2/build" + + test("Should run without failures") { + + 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() + } + + } + +} diff --git a/modules/nf-core/bowtie2/build/tests/main.nf.test.snap b/modules/nf-core/bowtie2/build/tests/main.nf.test.snap new file mode 100644 index 000000000..ea5711e42 --- /dev/null +++ b/modules/nf-core/bowtie2/build/tests/main.nf.test.snap @@ -0,0 +1,49 @@ +{ + "Should run without failures": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + [ + "genome.1.bt2:md5,cbe3d0bbea55bc57c99b4bfa25b5fbdf", + "genome.2.bt2:md5,47b153cd1319abc88dda532462651fcf", + "genome.3.bt2:md5,4ed93abba181d8dfab2e303e33114777", + "genome.4.bt2:md5,c25be5f8b0378abf7a58c8a880b87626", + "genome.rev.1.bt2:md5,52be6950579598a990570fbcf5372184", + "genome.rev.2.bt2:md5,e3b4ef343dea4dd571642010a7d09597" + ] + ] + ], + "1": [ + "versions.yml:md5,d136fb9c16f0a9fb2ae804b2a5fbc09c" + ], + "index": [ + [ + { + "id": "test" + }, + [ + "genome.1.bt2:md5,cbe3d0bbea55bc57c99b4bfa25b5fbdf", + "genome.2.bt2:md5,47b153cd1319abc88dda532462651fcf", + "genome.3.bt2:md5,4ed93abba181d8dfab2e303e33114777", + "genome.4.bt2:md5,c25be5f8b0378abf7a58c8a880b87626", + "genome.rev.1.bt2:md5,52be6950579598a990570fbcf5372184", + "genome.rev.2.bt2:md5,e3b4ef343dea4dd571642010a7d09597" + ] + ] + ], + "versions": [ + "versions.yml:md5,d136fb9c16f0a9fb2ae804b2a5fbc09c" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.02.1" + }, + "timestamp": "2023-11-23T11:51:01.107681997" + } +} \ No newline at end of file diff --git a/modules/nf-core/hostile/clean/environment.yml b/modules/nf-core/hostile/clean/environment.yml new file mode 100644 index 000000000..8c8ee7d12 --- /dev/null +++ b/modules/nf-core/hostile/clean/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::hostile=2.0.1 diff --git a/modules/nf-core/hostile/clean/main.nf b/modules/nf-core/hostile/clean/main.nf new file mode 100644 index 000000000..fce103eef --- /dev/null +++ b/modules/nf-core/hostile/clean/main.nf @@ -0,0 +1,78 @@ +process HOSTILE_CLEAN { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4f1e4558685117662053d37800dcf7a0d64d1f857e22c84900c379a16a04103c/data' + : 'community.wave.seqera.io/library/hostile:2.0.1--9fa0d3c35ac8f37e'}" + + input: + tuple val(meta), path(reads) + tuple val(reference_name), path(reference_dir) + + + output: + tuple val(meta), path('cleaned_reads/*.fastq.gz'), emit: fastq + tuple val(meta), path('*.json') , emit: json + 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 reads_cmd = meta.single_end ? "--fastq1 ${reads.sort()[0]}" : "--fastq1 ${reads.sort()[0]} --fastq2 ${reads.sort()[1]}" + """ + export HOSTILE_CACHE_DIR=${reference_dir} + mkdir cleaned_reads/ + + ## Reorder the reads for reproducibility + ## Set offline as we never want this process to auto-download reference files as required input channel + hostile \\ + clean \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads_cmd} \\ + --index ${reference_dir}/${reference_name} \\ + --output cleaned_reads/ \\ + --reorder \\ + --airplane \\ + | tee > ${prefix}.json + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + hostile: \$(hostile --version) + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def reads_cmd = meta.single_end ? "echo '' | gzip -c > cleaned_reads/${prefix}.clean_2.fastq.gz" : "" + + """ + echo "hostile \\ + clean \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads_cmd} \\ + --index ${reference_dir}/${reference_name} \\ + --output cleaned_reads/ \\ + --reorder \\ + --airplane \\ + | tee > ${prefix}.json" + + export HOSTILE_CACHE_DIR=${reference_dir} + mkdir cleaned_reads/ + echo "" | gzip -c > cleaned_reads/${prefix}.clean_1.fastq.gz + ${reads_cmd} + touch ${prefix}.json + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + hostile: \$(hostile --version) + END_VERSIONS + """ +} diff --git a/modules/nf-core/hostile/clean/meta.yml b/modules/nf-core/hostile/clean/meta.yml new file mode 100644 index 000000000..2277cd1ec --- /dev/null +++ b/modules/nf-core/hostile/clean/meta.yml @@ -0,0 +1,86 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "hostile_clean" +description: write your description here +keywords: + - hostile + - decontamination + - human removal + - download + - host removal + - clean +tools: + - "hostile": + description: "Hostile: accurate host decontamination" + homepage: "https://github.com/bede/hostile" + documentation: "https://github.com/bede/hostile" + tool_dev_url: "https://github.com/bede/hostile" + doi: "10.1093/bioinformatics/btad728" + licence: ["MIT"] + identifier: biotools:hostile + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - reads: + type: file + description: Paired or single end FASTQ files + pattern: "*.{fastq,fq,fastq.gz,fq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" + - - reference_name: + type: string + description: | + Name of the reference to align against and thus remove mapped reads to. + Typically corresponds + - reference_dir: + type: directory + description: | + Directory containing index file(s) corresponding to the preferred aligner (bowtie2 short reads or minimap for long reads). + Note that single end data is assumed to be long reads. If you have single-end short read you must supply both the BowTie2 + indices AND explicitly specify `--aligner bowtie2` + ontologies: + - edam: "http://edamontology.org/data_1049" + +output: + fastq: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - cleaned_reads/*.fastq.gz: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + pattern: "*.{fastq,fq,fastq.gz,fq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" + json: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.json": + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + pattern: "*.json" + ontologies: + - edam: "http://edamontology.org/format_3464" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/hostile/clean/tests/main.nf.test b/modules/nf-core/hostile/clean/tests/main.nf.test new file mode 100644 index 000000000..16265605e --- /dev/null +++ b/modules/nf-core/hostile/clean/tests/main.nf.test @@ -0,0 +1,121 @@ +nextflow_process { + + name "Test Process HOSTILE_CLEAN" + script "../main.nf" + process "HOSTILE_CLEAN" + config './nextflow.config' + + tag "modules" + tag "modules_nfcore" + tag "hostile" + tag "hostile/clean" + tag "bowtie2/build" + + setup { + run("BOWTIE2_BUILD") { + script "../../../bowtie2/build/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + test("fastq - single-end") { + when { + params { + module_args = "--aligner bowtie2" + } + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + ], + ] + input[1] = BOWTIE2_BUILD.out.index.map { ['genome', it[1]] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.fastq, + process.out.versions, + path(process.out.json[0][1]).readLines().any{ it.contains('\"reads_removed\": 0')} + ).match() } + ) + } + + } + + + test("fastq - paired-end") { + when { + params { + module_args = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + ], + ] + input[1] = BOWTIE2_BUILD.out.index.map { ['genome', it[1]] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.fastq[0][1][0]).linesGzip.size(), + path(process.out.fastq[0][1][1]).linesGzip.size(), + process.out.versions, + path(process.out.json[0][1]).readLines().any{ it.contains('\"reads_removed\": 0')} + ).match() } + ) + } + + } + + test("fastq - single-end - stub") { + + options "-stub" + + when { + params { + module_args = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + [file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_1.fastq.gz', checkIfExists: true)], + ] + input[1] = BOWTIE2_BUILD.out.index.map { ['genome', it[1]] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/hostile/clean/tests/main.nf.test.snap b/modules/nf-core/hostile/clean/tests/main.nf.test.snap new file mode 100644 index 000000000..93addfa45 --- /dev/null +++ b/modules/nf-core/hostile/clean/tests/main.nf.test.snap @@ -0,0 +1,98 @@ +{ + "fastq - single-end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.clean_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.clean_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,03b18aa9c4fb860c3291406e0ddd0604" + ], + "fastq": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.clean_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.clean_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,03b18aa9c4fb860c3291406e0ddd0604" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-06-22T16:42:13.096606105" + }, + "fastq - paired-end": { + "content": [ + 1066944, + 1066944, + [ + "versions.yml:md5,03b18aa9c4fb860c3291406e0ddd0604" + ], + true + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-06-22T16:41:54.142468338" + }, + "fastq - single-end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test_1.clean.fastq.gz:md5,9224ada21765cb3ad5fc05f40df78f17" + ] + ], + [ + "versions.yml:md5,03b18aa9c4fb860c3291406e0ddd0604" + ], + true + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-06-22T16:41:24.589567811" + } +} \ No newline at end of file diff --git a/modules/nf-core/hostile/clean/tests/nextflow.config b/modules/nf-core/hostile/clean/tests/nextflow.config new file mode 100644 index 000000000..864528aad --- /dev/null +++ b/modules/nf-core/hostile/clean/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'HOSTILE_CLEAN' { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/hostile/fetch/environment.yml b/modules/nf-core/hostile/fetch/environment.yml new file mode 100644 index 000000000..8c8ee7d12 --- /dev/null +++ b/modules/nf-core/hostile/fetch/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::hostile=2.0.1 diff --git a/modules/nf-core/hostile/fetch/main.nf b/modules/nf-core/hostile/fetch/main.nf new file mode 100644 index 000000000..e88f2db99 --- /dev/null +++ b/modules/nf-core/hostile/fetch/main.nf @@ -0,0 +1,55 @@ +process HOSTILE_FETCH { + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4f1e4558685117662053d37800dcf7a0d64d1f857e22c84900c379a16a04103c/data' + : 'community.wave.seqera.io/library/hostile:2.0.1--9fa0d3c35ac8f37e'}" + + input: + val index_name + + output: + tuple val(index_name), path('reference/'), emit: reference + path 'versions.yml' , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + mkdir reference/ + export HOSTILE_CACHE_DIR=./reference + + hostile \\ + index \\ + fetch \\ + --name ${index_name} \\ + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + hostile: \$(hostile --version) + END_VERSIONS + """ + + stub: + """ + mkdir reference/ + export HOSTILE_CACHE_DIR=./reference + + touch reference/human-t2t-hla.1.bt2 + touch reference/human-t2t-hla.2.bt2 + touch reference/human-t2t-hla.3.bt2 + touch reference/human-t2t-hla.4.bt2 + touch reference/human-t2t-hla.rev.1.bt2 + touch reference/human-t2t-hla.rev.2.bt2 + touch reference/human-t2t-hla.mmi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + hostile: \$(hostile --version) + END_VERSIONS + """ +} diff --git a/modules/nf-core/hostile/fetch/meta.yml b/modules/nf-core/hostile/fetch/meta.yml new file mode 100644 index 000000000..bfd27f930 --- /dev/null +++ b/modules/nf-core/hostile/fetch/meta.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "hostile_fetch" +description: Downloads required reference genomes for Hostile +keywords: + - hostile + - decontamination + - human removal + - download +tools: + - "hostile": + description: "Hostile: accurate host decontamination" + homepage: "https://github.com/bede/hostile" + documentation: "https://github.com/bede/hostile" + tool_dev_url: "https://github.com/bede/hostile" + doi: "10.1093/bioinformatics/btad728" + licence: ["MIT"] + identifier: biotools:hostile + +input: + - index_name: + type: string + description: Name of the reference genome index to download + +output: + reference: + - - index_name: + type: directory + description: Name of the reference genome index downloaded + - reference/: + type: directory + description: Directory containing required reference genome files for hostile + clean + pattern: "reference/" + ontologies: + - edam: "http://edamontology.org/data_1049" + + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/hostile/fetch/tests/main.nf.test b/modules/nf-core/hostile/fetch/tests/main.nf.test new file mode 100644 index 000000000..0c8526779 --- /dev/null +++ b/modules/nf-core/hostile/fetch/tests/main.nf.test @@ -0,0 +1,59 @@ +nextflow_process { + + name "Test Process HOSTILE_FETCH" + script "../main.nf" + process "HOSTILE_FETCH" + config './nextflow.config' + + tag "modules" + tag "modules_nfcore" + tag "hostile" + tag "hostile/fetch" + + test("human-t2t-hla - bowtie2") { + + when { + params { + module_args = "--bowtie2" + } + process { + """ + input[0] = 'human-t2t-hla' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("human-t2t-hla - stub") { + + options "-stub" + + when { + params { + module_args = "" + } + process { + """ + input[0] = 'human-t2t-hla' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/hostile/fetch/tests/main.nf.test.snap b/modules/nf-core/hostile/fetch/tests/main.nf.test.snap new file mode 100644 index 000000000..a5f1e08a9 --- /dev/null +++ b/modules/nf-core/hostile/fetch/tests/main.nf.test.snap @@ -0,0 +1,90 @@ +{ + "human-t2t-hla - bowtie2": { + "content": [ + { + "0": [ + [ + "human-t2t-hla", + [ + "human-t2t-hla.1.bt2:md5,b481b623a14908f29c5dce42077f8763", + "human-t2t-hla.2.bt2:md5,8df357276c7c3a4e768ecd70ca951b53", + "human-t2t-hla.3.bt2:md5,78289afb436f8d0a9526ecfa95e3fa24", + "human-t2t-hla.4.bt2:md5,198badf146cd0b3886b674424250d419", + "human-t2t-hla.rev.1.bt2:md5,34c65db94aba9cc49cb31e14d2698c1c", + "human-t2t-hla.rev.2.bt2:md5,53c9901609915475a2e1b009046d8371" + ] + ] + ], + "1": [ + "versions.yml:md5,8cff1f213b27df6d30e85fbc41e8d802" + ], + "reference": [ + [ + "human-t2t-hla", + [ + "human-t2t-hla.1.bt2:md5,b481b623a14908f29c5dce42077f8763", + "human-t2t-hla.2.bt2:md5,8df357276c7c3a4e768ecd70ca951b53", + "human-t2t-hla.3.bt2:md5,78289afb436f8d0a9526ecfa95e3fa24", + "human-t2t-hla.4.bt2:md5,198badf146cd0b3886b674424250d419", + "human-t2t-hla.rev.1.bt2:md5,34c65db94aba9cc49cb31e14d2698c1c", + "human-t2t-hla.rev.2.bt2:md5,53c9901609915475a2e1b009046d8371" + ] + ] + ], + "versions": [ + "versions.yml:md5,8cff1f213b27df6d30e85fbc41e8d802" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.3" + }, + "timestamp": "2025-06-22T17:41:12.85641403" + }, + "human-t2t-hla - stub": { + "content": [ + { + "0": [ + [ + "human-t2t-hla", + [ + "human-t2t-hla.1.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.2.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.3.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.4.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.mmi:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.rev.1.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.rev.2.bt2:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,8cff1f213b27df6d30e85fbc41e8d802" + ], + "reference": [ + [ + "human-t2t-hla", + [ + "human-t2t-hla.1.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.2.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.3.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.4.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.mmi:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.rev.1.bt2:md5,d41d8cd98f00b204e9800998ecf8427e", + "human-t2t-hla.rev.2.bt2:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,8cff1f213b27df6d30e85fbc41e8d802" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.3" + }, + "timestamp": "2025-06-22T17:22:15.545415161" + } +} diff --git a/modules/nf-core/hostile/fetch/tests/nextflow.config b/modules/nf-core/hostile/fetch/tests/nextflow.config new file mode 100644 index 000000000..8bbf46927 --- /dev/null +++ b/modules/nf-core/hostile/fetch/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'HOSTILE_FETCH' { + ext.args = params.module_args + } +} diff --git a/subworkflows/local/preprocessing_shortread/main.nf b/subworkflows/local/preprocessing_shortread/main.nf index bb29b73a4..1d87036ba 100644 --- a/subworkflows/local/preprocessing_shortread/main.nf +++ b/subworkflows/local/preprocessing_shortread/main.nf @@ -11,6 +11,10 @@ include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../m include { CAT_FASTQ } from '../../../modules/nf-core/cat/fastq/main' include { SEQTK_MERGEPE } from '../../../modules/nf-core/seqtk/mergepe/main' include { BBMAP_BBNORM } from '../../../modules/nf-core/bbmap/bbnorm/main' +include { HOSTILE_CLEAN as HOSTILE_CLEAN_HOST_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' +include { HOSTILE_CLEAN as HOSTILE_CLEAN_PHIX_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' +include { BOWTIE2_BUILD as BOWTIE2_HOST_BUILD } from '../../../modules/nf-core/bowtie2/build/main' +include { BOWTIE2_BUILD as BOWTIE2_PHIX_BUILD } from '../../../modules/nf-core/bowtie2/build/main' include { BOWTIE2_REMOVAL_BUILD as BOWTIE2_HOST_REMOVAL_BUILD } from '../../../modules/local/bowtie2_removal_build/main' include { BOWTIE2_REMOVAL_ALIGN as BOWTIE2_HOST_REMOVAL_ALIGN } from '../../../modules/local/bowtie2_removal_align/main' @@ -19,11 +23,11 @@ include { BOWTIE2_REMOVAL_ALIGN as BOWTIE2_PHIX_REMOVAL_ALIGN } from '../../../m workflow SHORTREAD_PREPROCESSING { take: - ch_raw_short_reads // [ [meta] , fastq1, fastq2] (mandatory) - ch_host_fasta // [fasta] (optional) - ch_host_genome_index // fasta (optional) - ch_phix_db_file // [fasta] (optional) - val_skip_qc // [boolean] + ch_raw_short_reads // [[meta] , fastq1, fastq2] (mandatory) + val_host_fasta // [fasta] (optional) + val_host_genome_index // fasta (optional) + val_phix_db_file // [fasta] (optional) + val_skip_qc // [boolean] main: ch_versions = Channel.empty() @@ -84,62 +88,70 @@ workflow SHORTREAD_PREPROCESSING { if (params.host_fasta || params.host_genome) { if (params.host_fasta_bowtie2index) { - ch_host_bowtie2index = file(params.host_fasta_bowtie2index, checkIfExists: true) + ch_host_bowtie2index = val_host_genome_index } else { - ch_host_fasta_for_build = ch_host_fasta + ch_host_fasta_for_build = val_host_fasta .combine(ch_short_reads_prepped) - .map { host_fasta, _meta, _reads -> - host_fasta + .map { host_fasta, meta, _reads -> + [meta, host_fasta] } .first() + // makes sure to only use the host fasta if the short read channel is not empty - BOWTIE2_HOST_REMOVAL_BUILD( - ch_host_fasta_for_build - ) - ch_versions = ch_versions.mix(BOWTIE2_HOST_REMOVAL_BUILD.out.versions) + BOWTIE2_HOST_BUILD(ch_host_fasta_for_build) + ch_versions = ch_versions.mix(BOWTIE2_HOST_BUILD.out.versions) - ch_host_bowtie2index = BOWTIE2_HOST_REMOVAL_BUILD.out.index + ch_host_bowtie2index = BOWTIE2_HOST_BUILD.out.index.map { _meta, index -> index } } - } - else if (params.host_genome) { - ch_host_bowtie2index = ch_host_genome_index - } - if (params.host_fasta || params.host_genome) { - BOWTIE2_HOST_REMOVAL_ALIGN( + // add reference basename for hostile + ch_host_hostile_reference = ch_host_bowtie2index.map { index_dir -> + def index_file = file(index_dir).listFiles().find { it.name.endsWith('.bt2') } + def index_name = index_file.name - ~/.(rev.)?(\d+).bt2/ + + [index_name, index_dir] + } + + HOSTILE_CLEAN_HOST_SHORTREAD( ch_short_reads_prepped, - ch_host_bowtie2index, + ch_host_hostile_reference, ) - ch_versions = ch_versions.mix(BOWTIE2_HOST_REMOVAL_ALIGN.out.versions) + ch_versions = ch_versions.mix(HOSTILE_CLEAN_HOST_SHORTREAD.out.versions) - ch_short_reads_hostremoved = BOWTIE2_HOST_REMOVAL_ALIGN.out.reads - ch_multiqc_files = ch_multiqc_files.mix(BOWTIE2_HOST_REMOVAL_ALIGN.out.log) + ch_short_reads_hostremoved = HOSTILE_CLEAN_HOST_SHORTREAD.out.fastq + ch_multiqc_files = ch_multiqc_files.mix(HOSTILE_CLEAN_HOST_SHORTREAD.out.json) } else { ch_short_reads_hostremoved = ch_short_reads_prepped } if (!params.keep_phix && !val_skip_qc) { - ch_phix_fasta_for_build = ch_phix_db_file + ch_phix_fasta_for_build = val_phix_db_file .combine(ch_short_reads_prepped) - .map { host_fasta, _meta, _reads -> - host_fasta + .map { host_fasta, meta, _reads -> + [meta, host_fasta] } .first() - BOWTIE2_PHIX_REMOVAL_BUILD( - ch_phix_fasta_for_build - ) - ch_versions = ch_versions.mix(BOWTIE2_PHIX_REMOVAL_BUILD.out.versions) - BOWTIE2_PHIX_REMOVAL_ALIGN( + BOWTIE2_PHIX_BUILD(ch_phix_fasta_for_build) + ch_versions = ch_versions.mix(BOWTIE2_PHIX_BUILD.out.versions) + + ch_phix_hostile_reference = BOWTIE2_PHIX_BUILD.out.index.map { _meta, index_dir -> + def index_file = file(index_dir).listFiles().find { it.name.endsWith('.bt2') } + def index_name = index_file.name - ~/.(rev.)?(\d+).bt2/ + + [index_name, index_dir] + } + + HOSTILE_CLEAN_PHIX_SHORTREAD( ch_short_reads_hostremoved, - BOWTIE2_PHIX_REMOVAL_BUILD.out.index, + ch_phix_hostile_reference, ) - ch_versions = ch_versions.mix(BOWTIE2_PHIX_REMOVAL_ALIGN.out.versions) + ch_versions = ch_versions.mix(HOSTILE_CLEAN_PHIX_SHORTREAD.out.versions) - ch_short_reads_phixremoved = BOWTIE2_PHIX_REMOVAL_ALIGN.out.reads - ch_multiqc_files = ch_multiqc_files.mix(BOWTIE2_PHIX_REMOVAL_ALIGN.out.log) + ch_short_reads_phixremoved = HOSTILE_CLEAN_PHIX_SHORTREAD.out.fastq + ch_multiqc_files = ch_multiqc_files.mix(HOSTILE_CLEAN_PHIX_SHORTREAD.out.json) } else { ch_short_reads_phixremoved = ch_short_reads_hostremoved From d6e60578b91426231067d263ebc69943b993411f Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Thu, 28 Aug 2025 07:11:41 -0300 Subject: [PATCH 2/3] Add module configs --- conf/modules.config | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/conf/modules.config b/conf/modules.config index c74160073..1c75c5c5e 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -145,6 +145,21 @@ process { tag = { "${meta.id}_run${meta.run}" } } + withName: HOSTILE_CLEAN_HOST_SHORTREAD { + ext.prefix = { "${meta.id}_run${meta.run}_host_removed" } + ext.args = [ + "--aligner bowtie2", + params.host_removal_verysensitive + ? "--aligner-args \\\"--very-sensitive\\\"" + : "--aligner-args \\\"--sensitive\\\"", + ].join(' ') + } + + withName: HOSTILE_CLEAN_PHIX_SHORTREAD { + ext.prefix = { "${meta.id}_run${meta.run}_phix_removed" } + ext.args = "--aligner bowtie2" + } + withName: FASTQC_TRIMMED { ext.args = '--quiet' ext.prefix = { "${meta.id}_run${meta.run}_trimmed" } From 95c22d6e66ecd3c8ec28195356b8f0a20de75e39 Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Fri, 12 Sep 2025 08:56:12 -0300 Subject: [PATCH 3/3] Longread (WIP) --- conf/modules.config | 5 +++ .../local/preprocessing_longread/main.nf | 36 +++++++++++-------- .../local/preprocessing_shortread/main.nf | 32 ++++++++--------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 64d02eeb0..ced18efa0 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -160,6 +160,11 @@ process { ext.args = "--aligner bowtie2" } + withName: HOSTILE_CLEAN_HOST_LONGREAD { + ext.prefix = { "${meta.id}_run${meta.run}_host_removed" } + ext.args = "--aligner minimap2" + } + withName: FASTQC_TRIMMED { ext.args = '--quiet' ext.prefix = { "${meta.id}_run${meta.run}_trimmed" } diff --git a/subworkflows/local/preprocessing_longread/main.nf b/subworkflows/local/preprocessing_longread/main.nf index d794ae9c3..1ccb08e6b 100644 --- a/subworkflows/local/preprocessing_longread/main.nf +++ b/subworkflows/local/preprocessing_longread/main.nf @@ -2,18 +2,20 @@ * LONGREAD_PREPROCESSING: Preprocessing and QC for long reads */ -include { NANOPLOT as NANOPLOT_RAW } from '../../../modules/nf-core/nanoplot/main' -include { NANOPLOT as NANOPLOT_FILTERED } from '../../../modules/nf-core/nanoplot/main' -include { NANOLYSE } from '../../../modules/nf-core/nanolyse/main' -include { PORECHOP_PORECHOP } from '../../../modules/nf-core/porechop/porechop/main' -include { PORECHOP_ABI } from '../../../modules/nf-core/porechop/abi/main' -include { FILTLONG } from '../../../modules/nf-core/filtlong' -include { CHOPPER } from '../../../modules/nf-core/chopper' -include { NANOQ } from '../../../modules/nf-core/nanoq' -include { CAT_FASTQ as CAT_FASTQ_LONGREADS } from '../../../modules/nf-core/cat/fastq/main' +include { NANOPLOT as NANOPLOT_RAW } from '../../../modules/nf-core/nanoplot/main' +include { NANOPLOT as NANOPLOT_FILTERED } from '../../../modules/nf-core/nanoplot/main' +include { NANOLYSE } from '../../../modules/nf-core/nanolyse/main' +include { PORECHOP_PORECHOP } from '../../../modules/nf-core/porechop/porechop/main' +include { PORECHOP_ABI } from '../../../modules/nf-core/porechop/abi/main' +include { FILTLONG } from '../../../modules/nf-core/filtlong' +include { CHOPPER } from '../../../modules/nf-core/chopper' +include { NANOQ } from '../../../modules/nf-core/nanoq' +include { CAT_FASTQ as CAT_FASTQ_LONGREADS } from '../../../modules/nf-core/cat/fastq/main' +include { MINIMAP2_INDEX } from '../../../modules/nf-core/minimap2/index/main' +include { HOSTILE_CLEAN as HOSTILE_CLEAN_HOST_LONGREAD } from '../../../modules/nf-core/hostile/clean/main' // include other subworkflows here -include { LONGREAD_HOSTREMOVAL } from '../hostremoval_longread/main' +include { LONGREAD_HOSTREMOVAL } from '../hostremoval_longread/main' workflow LONGREAD_PREPROCESSING { take: @@ -104,13 +106,17 @@ workflow LONGREAD_PREPROCESSING { // host removal long reads if (params.host_fasta || params.host_genome) { - LONGREAD_HOSTREMOVAL( + MINIMAP2_INDEX([[:], ch_host_fasta]) + ch_versions = ch_versions.mix(MINIMAP2_INDEX.out.versions) + + HOSTILE_CLEAN_HOST_LONGREAD( ch_long_reads, - ch_host_fasta, + MINIMAP2_INDEX.out.index.map { _meta, index -> ['.', index] }, ) - ch_versions = ch_versions.mix(LONGREAD_HOSTREMOVAL.out.versions) - ch_multiqc_files = ch_multiqc_files.mix(LONGREAD_HOSTREMOVAL.out.multiqc_files) - ch_long_reads = LONGREAD_HOSTREMOVAL.out.reads + + ch_versions = ch_versions.mix(HOSTILE_CLEAN_HOST_LONGREAD.out.versions) + ch_multiqc_files = ch_multiqc_files.mix(HOSTILE_CLEAN_HOST_LONGREAD.out.json) + ch_long_reads = HOSTILE_CLEAN_HOST_LONGREAD.out.fastq } /** diff --git a/subworkflows/local/preprocessing_shortread/main.nf b/subworkflows/local/preprocessing_shortread/main.nf index ded0f887b..b0da71446 100644 --- a/subworkflows/local/preprocessing_shortread/main.nf +++ b/subworkflows/local/preprocessing_shortread/main.nf @@ -2,24 +2,20 @@ * SHORTREAD_PREPROCESSING: Preprocessing and QC for short reads */ -include { FASTQC as FASTQC_RAW } from '../../../modules/nf-core/fastqc/main' -include { FASTQC as FASTQC_TRIMMED } from '../../../modules/nf-core/fastqc/main' -include { FASTP } from '../../../modules/nf-core/fastp/main' -include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' -include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/adapterremoval/main' -include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' -include { CAT_FASTQ } from '../../../modules/nf-core/cat/fastq/main' -include { SEQTK_MERGEPE } from '../../../modules/nf-core/seqtk/mergepe/main' -include { BBMAP_BBNORM } from '../../../modules/nf-core/bbmap/bbnorm/main' -include { HOSTILE_CLEAN as HOSTILE_CLEAN_HOST_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' -include { HOSTILE_CLEAN as HOSTILE_CLEAN_PHIX_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' -include { BOWTIE2_BUILD as BOWTIE2_HOST_BUILD } from '../../../modules/nf-core/bowtie2/build/main' -include { BOWTIE2_BUILD as BOWTIE2_PHIX_BUILD } from '../../../modules/nf-core/bowtie2/build/main' - -include { BOWTIE2_REMOVAL_BUILD as BOWTIE2_HOST_REMOVAL_BUILD } from '../../../modules/local/bowtie2_removal_build/main' -include { BOWTIE2_REMOVAL_ALIGN as BOWTIE2_HOST_REMOVAL_ALIGN } from '../../../modules/local/bowtie2_removal_align/main' -include { BOWTIE2_REMOVAL_BUILD as BOWTIE2_PHIX_REMOVAL_BUILD } from '../../../modules/local/bowtie2_removal_build/main' -include { BOWTIE2_REMOVAL_ALIGN as BOWTIE2_PHIX_REMOVAL_ALIGN } from '../../../modules/local/bowtie2_removal_align/main' +include { FASTQC as FASTQC_RAW } from '../../../modules/nf-core/fastqc/main' +include { FASTQC as FASTQC_TRIMMED } from '../../../modules/nf-core/fastqc/main' +include { FASTP } from '../../../modules/nf-core/fastp/main' +include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' +include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/adapterremoval/main' +include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' +include { CAT_FASTQ } from '../../../modules/nf-core/cat/fastq/main' +include { SEQTK_MERGEPE } from '../../../modules/nf-core/seqtk/mergepe/main' +include { BBMAP_BBNORM } from '../../../modules/nf-core/bbmap/bbnorm/main' +include { HOSTILE_CLEAN as HOSTILE_CLEAN_HOST_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' +include { HOSTILE_CLEAN as HOSTILE_CLEAN_PHIX_SHORTREAD } from '../../../modules/nf-core/hostile/clean/main' +include { BOWTIE2_BUILD as BOWTIE2_HOST_BUILD } from '../../../modules/nf-core/bowtie2/build/main' +include { BOWTIE2_BUILD as BOWTIE2_PHIX_BUILD } from '../../../modules/nf-core/bowtie2/build/main' + workflow SHORTREAD_PREPROCESSING { take: