diff --git a/CHANGELOG.md b/CHANGELOG.md index 374b145c..92d76abf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#365](https://github.com/nf-core/funcscan/pull/365) Fixed AMRFinderPlus module and usage docs for manual database download. (by @jasmezz) - [#371](https://github.com/nf-core/funcscan/pull/371) Fixed AMRFinderPlus parameter `arg_amrfinderplus_name`. (by @m3hdad) - [#376](https://github.com/nf-core/funcscan/pull/376) Fixed an occasional RGI process failure when certain files not produced. (❤️ to @amizeranschi for reporting, fix by @amizeranschi & @jfy133) +- [#386](https://github.com/nf-core/funcscan/pull/386) Updated DeepBGC module to fix output file names, separate annotation step for all BGC tools, add warning if no BGCs found, fix MultiQC reporting of annotation workflow. (by @jfy133, @jasmezz) ### `Dependencies` diff --git a/modules.json b/modules.json index e6724c43..b9327d86 100644 --- a/modules.json +++ b/modules.json @@ -87,7 +87,7 @@ }, "deepbgc/pipeline": { "branch": "master", - "git_sha": "f315f85d9ac6c321f6e3596493fd61019340df2a", + "git_sha": "0ea330bfd93fbbe5b5cae9afab565c73cc508583", "installed_by": ["modules"] }, "fargene": { diff --git a/modules/nf-core/deepbgc/pipeline/main.nf b/modules/nf-core/deepbgc/pipeline/main.nf index 9cc22708..fc72d238 100644 --- a/modules/nf-core/deepbgc/pipeline/main.nf +++ b/modules/nf-core/deepbgc/pipeline/main.nf @@ -12,17 +12,17 @@ process DEEPBGC_PIPELINE { path(db) output: - tuple val(meta), path("${prefix}/README.txt") , optional: true, emit: readme - tuple val(meta), path("${prefix}/LOG.txt") , emit: log - tuple val(meta), path("${prefix}/${genome.baseName}.antismash.json") , optional: true, emit: json - tuple val(meta), path("${prefix}/${genome.baseName}.bgc.gbk") , optional: true, emit: bgc_gbk - tuple val(meta), path("${prefix}/${genome.baseName}.bgc.tsv") , optional: true, emit: bgc_tsv - tuple val(meta), path("${prefix}/${genome.baseName}.full.gbk") , optional: true, emit: full_gbk - tuple val(meta), path("${prefix}/${genome.baseName}.pfam.tsv") , optional: true, emit: pfam_tsv - tuple val(meta), path("${prefix}/evaluation/${genome.baseName}.bgc.png") , optional: true, emit: bgc_png - tuple val(meta), path("${prefix}/evaluation/${genome.baseName}.pr.png") , optional: true, emit: pr_png - tuple val(meta), path("${prefix}/evaluation/${genome.baseName}.roc.png") , optional: true, emit: roc_png - tuple val(meta), path("${prefix}/evaluation/${genome.baseName}.score.png") , optional: true, emit: score_png + tuple val(meta), path("${prefix}/README.txt") , optional: true, emit: readme + tuple val(meta), path("${prefix}/LOG.txt") , emit: log + tuple val(meta), path("${prefix}/${prefix}.antismash.json") , optional: true, emit: json + tuple val(meta), path("${prefix}/${prefix}.bgc.gbk") , optional: true, emit: bgc_gbk + tuple val(meta), path("${prefix}/${prefix}.bgc.tsv") , optional: true, emit: bgc_tsv + tuple val(meta), path("${prefix}/${prefix}.full.gbk") , optional: true, emit: full_gbk + tuple val(meta), path("${prefix}/${prefix}.pfam.tsv") , optional: true, emit: pfam_tsv + tuple val(meta), path("${prefix}/evaluation/${prefix}.bgc.png") , optional: true, emit: bgc_png + tuple val(meta), path("${prefix}/evaluation/${prefix}.pr.png") , optional: true, emit: pr_png + tuple val(meta), path("${prefix}/evaluation/${prefix}.roc.png") , optional: true, emit: roc_png + tuple val(meta), path("${prefix}/evaluation/${prefix}.score.png"), optional: true, emit: score_png path "versions.yml" , emit: versions when: @@ -43,6 +43,34 @@ process DEEPBGC_PIPELINE { mv "${genome.baseName}/" "${prefix}/" fi + for i in \$(find -name '${genome.baseName}*' -type f); do + mv \$i \${i/${genome.baseName}/${prefix}}; + done + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepbgc: \$(echo \$(deepbgc info 2>&1 /dev/null/ | grep 'version' | cut -d " " -f3) ) + prodigal: \$(prodigal -v 2>&1 | sed -n 's/Prodigal V\\(.*\\):.*/\\1/p') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir -p ${prefix}/evaluation + touch ${prefix}/README.txt + touch ${prefix}/LOG.txt + touch ${prefix}/${prefix}.antismash.json + touch ${prefix}/${prefix}.bgc.gbk + touch ${prefix}/${prefix}.bgc.tsv + touch ${prefix}/${prefix}.full.gbk + touch ${prefix}/${prefix}.pfam.tsv + touch ${prefix}/evaluation/${prefix}.bgc.png + touch ${prefix}/evaluation/${prefix}.pr.png + touch ${prefix}/evaluation/${prefix}.roc.png + touch ${prefix}/evaluation/${prefix}.score.png + cat <<-END_VERSIONS > versions.yml "${task.process}": deepbgc: \$(echo \$(deepbgc info 2>&1 /dev/null/ | grep 'version' | cut -d " " -f3) ) diff --git a/modules/nf-core/deepbgc/pipeline/tests/main.nf.test b/modules/nf-core/deepbgc/pipeline/tests/main.nf.test new file mode 100644 index 00000000..190b7e8f --- /dev/null +++ b/modules/nf-core/deepbgc/pipeline/tests/main.nf.test @@ -0,0 +1,116 @@ +nextflow_process { + + name "Test Process DEEPBGC_PIPELINE" + script "../main.nf" + process "DEEPBGC_PIPELINE" + + tag "modules" + tag "modules_nfcore" + tag "deepbgc" + tag "deepbgc/pipeline" + tag "deepbgc/download" + tag "gunzip" + tag "prodigal" + + setup { + run("DEEPBGC_DOWNLOAD") { + script "../..//download/main.nf" + process { + """ + """ + } + } + run("GUNZIP") { + script "../../../gunzip/main.nf" + process { + """ + input[0] = Channel.fromList([ + tuple([ id:'test_gbk', single_end:false ], // meta map + file(params.test_data['bacteroides_fragilis']['illumina']['test1_contigs_fa_gz'], checkIfExists: true)) + ]) + """ + } + } + run("PRODIGAL") { + script "../../../prodigal/main.nf" + process { + """ + input[0] = GUNZIP.out.gunzip + input[1] = 'gbk' + """ + } + } + } + + test("deepbgc pipeline gbk - bacteroides fragilis - test1_contigs.fa.gz") { + + when { + process { + """ + input [0] = PRODIGAL.out.gene_annotations + input [1] = DEEPBGC_DOWNLOAD.out.db + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("gbk_versions") }, + { assert snapshot(process.out.json).match("gbk_json") }, + { assert path(process.out.log.get(0).get(1)).exists() }, + { assert path(process.out.bgc_gbk.get(0).get(1)).exists() }, + { assert path(process.out.full_gbk.get(0).get(1)).exists() } + ) + } + + } + + test("deepbgc pipeline fa - bacteroides fragilis - test1_contigs.fa.gz") { + + when { + process { + """ + input [0] = GUNZIP.out.gunzip + input [1] = DEEPBGC_DOWNLOAD.out.db + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match("fa_versions") }, + { assert snapshot(process.out.bgc_gbk).match("fa_bgc_gbk") }, + { assert snapshot(process.out.bgc_png).match("fa_bgc_png") }, + { assert snapshot(process.out.score_png).match("fa_score_png") }, + { assert snapshot(process.out.pfam_tsv).match("fa_pfam_tsv") }, + { assert path(process.out.json.get(0).get(1)).exists() }, + { assert path(process.out.log.get(0).get(1)).exists() }, + { assert path(process.out.bgc_tsv.get(0).get(1)).exists() }, + { assert path(process.out.full_gbk.get(0).get(1)).exists() } + ) + } + } + + test("deepbgc pipeline fa - bacteroides fragilis - test1_contigs.fa.gz - stub") { + options "-stub" + when { + process { + """ + input [0] = GUNZIP.out.gunzip + input [1] = DEEPBGC_DOWNLOAD.out.db + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} + diff --git a/modules/nf-core/deepbgc/pipeline/tests/main.nf.test.snap b/modules/nf-core/deepbgc/pipeline/tests/main.nf.test.snap new file mode 100644 index 00000000..ef64db97 --- /dev/null +++ b/modules/nf-core/deepbgc/pipeline/tests/main.nf.test.snap @@ -0,0 +1,331 @@ +{ + "gbk_versions": { + "content": [ + [ + "versions.yml:md5,988a1db70bd9e95ad22c25b4d6d40e6e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.1" + }, + "timestamp": "2023-12-01T18:29:41.728695197" + }, + "fa_bgc_png": { + "content": [ + [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.png:md5,f4a0fc6cd260e2d7ad16f7a1fa103f96" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:29:32.389704368" + }, + "deepbgc pipeline fa - bacteroides fragilis - test1_contigs.fa.gz - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "README.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "LOG.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.score.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + "versions.yml:md5,988a1db70bd9e95ad22c25b4d6d40e6e" + ], + "2": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.antismash.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.gbk:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.full.gbk:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.pfam.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.pr.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.roc.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bgc_gbk": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.gbk:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bgc_png": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bgc_tsv": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "full_gbk": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.full.gbk:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.antismash.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "LOG.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pfam_tsv": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.pfam.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pr_png": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.pr.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readme": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "README.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "roc_png": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.roc.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "score_png": [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.score.png:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,988a1db70bd9e95ad22c25b4d6d40e6e" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:32:11.354631831" + }, + "fa_score_png": { + "content": [ + [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.score.png:md5,572e8882031f667580d8c8e13c2cbb91" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:29:32.401051746" + }, + "fa_pfam_tsv": { + "content": [ + [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.pfam.tsv:md5,1179eb4e6df0c83aaeec18d7d34e7524" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:29:32.411632144" + }, + "gbk_json": { + "content": [ + [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.antismash.json:md5,889ac1efb6a9a7d7b8c65e4cd2233bba" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:25:25.861672633" + }, + "fa_versions": { + "content": [ + [ + "versions.yml:md5,988a1db70bd9e95ad22c25b4d6d40e6e" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.1" + }, + "timestamp": "2023-12-01T18:44:16.352023677" + }, + "fa_bgc_gbk": { + "content": [ + [ + [ + { + "id": "test_gbk", + "single_end": false + }, + "test_gbk.bgc.gbk:md5,7fc70dd034903622dae273bf71b402f2" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T16:29:32.383560585" + } +} \ No newline at end of file diff --git a/modules/nf-core/deepbgc/pipeline/tests/tags.yml b/modules/nf-core/deepbgc/pipeline/tests/tags.yml new file mode 100644 index 00000000..c6c4e11d --- /dev/null +++ b/modules/nf-core/deepbgc/pipeline/tests/tags.yml @@ -0,0 +1,2 @@ +deepbgc/pipeline: + - "modules/nf-core/deepbgc/pipeline/**" diff --git a/nextflow.config b/nextflow.config index 8c368156..c676b9e5 100644 --- a/nextflow.config +++ b/nextflow.config @@ -31,6 +31,9 @@ params { version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' + // To stop the random warning coming from nf-validation, remove on upgrade to nf-schema + monochromeLogs = null + // Taxonomy classification options run_taxa_classification = false taxa_classification_tool = 'mmseqs2' @@ -244,7 +247,7 @@ params { // Schema validation default options validationFailUnrecognisedParams = false validationLenientMode = false - validationSchemaIgnoreParams = 'genomes,igenomes_base,fasta' + validationSchemaIgnoreParams = 'genomes,igenomes_base,fasta,monochromeLogs' validationShowHiddenParams = false validate_params = true diff --git a/subworkflows/local/annotation.nf b/subworkflows/local/annotation.nf index a431885b..db3b34f6 100644 --- a/subworkflows/local/annotation.nf +++ b/subworkflows/local/annotation.nf @@ -22,10 +22,10 @@ workflow ANNOTATION { ch_versions = Channel.empty() ch_multiqc_files = Channel.empty() - if ( params.annotation_tool == "pyrodigal" || ( params.annotation_tool == "prodigal" && params.run_bgc_screening == true && !params.bgc_skip_antismash ) || ( params.annotation_tool == "prodigal" && params.run_amp_screening == true ) ) { // Need to use pyrodigal for antiSMASH / AMP workflow because prodigal GBK annotation format is incompatible with antiSMASH/AMPcombi. + if ( params.annotation_tool == "pyrodigal" || ( params.annotation_tool == "prodigal" && params.run_bgc_screening == true && ( !params.bgc_skip_antismash || !params.bgc_skip_deepbgc || !params.bgc_skip_gecco ) ) || ( params.annotation_tool == "prodigal" && params.run_amp_screening == true ) ) { // Need to use Pyrodigal for most BGC tools and AMPcombi because Prodigal GBK annotation format is incompatible with them. - if ( params.annotation_tool == "prodigal" && params.run_bgc_screening == true && !params.bgc_skip_antismash ) { - log.warn("[nf-core/funcscan] Switching annotation tool to: Pyrodigal. This is because Prodigal annotations (in GBK format) are incompatible with antiSMASH. If you specifically wish to run Prodigal instead, please skip antiSMASH or provide a pre-annotated GBK file in the samplesheet.") + if ( params.annotation_tool == "prodigal" && params.run_bgc_screening == true && ( !params.bgc_skip_antismash || !params.bgc_skip_deepbgc || !params.bgc_skip_gecco ) ) { + log.warn("[nf-core/funcscan] Switching annotation tool to: Pyrodigal. This is because Prodigal annotations (in GBK format) are incompatible with antiSMASH, DeepBGC, and GECCO. If you specifically wish to run Prodigal instead, please skip antiSMASH, DeepBGC, and GECCO or provide a pre-annotated GBK file in the samplesheet.") } else if ( params.annotation_tool == "prodigal" && params.run_amp_screening == true ) { log.warn("[nf-core/funcscan] Switching annotation tool to: Pyrodigal. This is because Prodigal annotations (in GBK format) are incompatible with AMPcombi. If you specifically wish to run Prodigal instead, please skip AMP workflow or provide a pre-annotated GBK file in the samplesheet.") } diff --git a/subworkflows/local/bgc.nf b/subworkflows/local/bgc.nf index 455e7719..99d371e0 100644 --- a/subworkflows/local/bgc.nf +++ b/subworkflows/local/bgc.nf @@ -73,14 +73,23 @@ workflow BGC { ANTISMASH_ANTISMASHLITE ( gbks, ch_antismash_databases, ch_antismash_directory, [] ) ch_versions = ch_versions.mix( ANTISMASH_ANTISMASHLITE.out.versions ) - ch_antismashresults_for_combgc = ANTISMASH_ANTISMASHLITE.out.knownclusterblast_dir + ch_antismashresults = ANTISMASH_ANTISMASHLITE.out.knownclusterblast_dir .mix( ANTISMASH_ANTISMASHLITE.out.gbk_input ) .groupTuple() .map{ meta, files -> - [meta, files.flatten()] + [ meta, files.flatten() ] } + // Filter out samples with no BGC hits + ch_antismashresults_for_combgc = ch_antismashresults + .join(fastas, remainder: false) + .join(ANTISMASH_ANTISMASHLITE.out.gbk_results, remainder: false) + .map { + meta, gbk_input, fasta, gbk_results -> + [ meta, gbk_input ] + } + ch_bgcresults_for_combgc = ch_bgcresults_for_combgc.mix( ch_antismashresults_for_combgc ) } @@ -97,14 +106,14 @@ workflow BGC { ch_versions = ch_versions.mix( DEEPBGC_DOWNLOAD.out.versions ) } - DEEPBGC_PIPELINE ( fastas, ch_deepbgc_database) + DEEPBGC_PIPELINE ( gbks, ch_deepbgc_database) ch_versions = ch_versions.mix( DEEPBGC_PIPELINE.out.versions ) ch_bgcresults_for_combgc = ch_bgcresults_for_combgc.mix( DEEPBGC_PIPELINE.out.bgc_tsv ) } // GECCO if ( !params.bgc_skip_gecco ) { - ch_gecco_input = fastas.groupTuple() + ch_gecco_input = gbks.groupTuple() .multiMap { fastas: [ it[0], it[1], [] ] } @@ -148,6 +157,15 @@ workflow BGC { } // COMBGC + + ch_bgcresults_for_combgc + .join(fastas, remainder: true) + .filter { + meta, bgcfile, fasta -> + if ( !bgcfile ) { log.warn("[nf-core/funcscan] BGC workflow: No hits found by BGC tools; comBGC summary tool will not be run for sample: ${meta.id}") } + return [meta, bgcfile, fasta] + } + COMBGC ( ch_bgcresults_for_combgc ) ch_versions = ch_versions.mix( COMBGC.out.versions ) diff --git a/workflows/funcscan.nf b/workflows/funcscan.nf index f2d8c8c9..dd5028f8 100644 --- a/workflows/funcscan.nf +++ b/workflows/funcscan.nf @@ -122,10 +122,9 @@ workflow FUNCSCAN { */ // Some tools require annotated FASTAs - if ( ( params.run_arg_screening && !params.arg_skip_deeparg ) || ( params.run_amp_screening && ( !params.amp_skip_hmmsearch || !params.amp_skip_amplify || !params.amp_skip_ampir ) ) || ( params.run_bgc_screening && ( !params.bgc_skip_hmmsearch || !params.bgc_skip_antismash ) ) ) { + if ( ( params.run_arg_screening && !params.arg_skip_deeparg ) || ( params.run_amp_screening && ( !params.amp_skip_hmmsearch || !params.amp_skip_amplify || !params.amp_skip_ampir ) ) || ( params.run_bgc_screening ) ) { ANNOTATION( ch_input_for_annotation ) ch_versions = ch_versions.mix( ANNOTATION.out.versions ) - ch_multiqc_files = ch_multiqc_files.mix( ANNOTATION.out.multiqc_files ) ch_new_annotation = ch_input_for_annotation .join( ANNOTATION.out.faa ) @@ -364,7 +363,9 @@ workflow FUNCSCAN { ) ) - ch_multiqc_files = ch_multiqc_files.mix( ANNOTATION.out.multiqc_files.collect{it[1]}.ifEmpty([]) ) + if ( ( params.run_arg_screening && !params.arg_skip_deeparg ) || ( params.run_amp_screening && ( !params.amp_skip_hmmsearch || !params.amp_skip_amplify || !params.amp_skip_ampir ) ) || ( params.run_bgc_screening ) ) { + ch_multiqc_files = ch_multiqc_files.mix( ANNOTATION.out.multiqc_files.collect{it[1]} ) + } MULTIQC ( ch_multiqc_files.collect(),