From d548c23fe8880f691199941aada738d70876775f Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Tue, 23 Apr 2024 12:55:45 +0200 Subject: [PATCH 1/4] Add metrics to multiqc report --- workflows/wisecondorx.nf | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/workflows/wisecondorx.nf b/workflows/wisecondorx.nf index 02b06f0..449bd4d 100644 --- a/workflows/wisecondorx.nf +++ b/workflows/wisecondorx.nf @@ -1,3 +1,5 @@ +import groovy.yaml.YamlBuilder + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS @@ -119,6 +121,10 @@ workflow WISECONDORX { counts } .map { genders -> create_metrics(genders)} + .collectFile(name: "metrics_mqc.tsv") + .set { ch_metrics } + + ch_multiqc_files = ch_multiqc_files.mix(ch_metrics) } @@ -202,20 +208,17 @@ def get_gender(tsv) { } def create_metrics(genders) { - male = genders["male"] - female = genders["female"] - male_count = male.size() - female_count = female.size() - total_count = male_count + female_count - ratio_male_to_female = male_count / female_count - - output = file("${params.outdir}/metrics.txt") - output.write("Ratio male to female: ${ratio_male_to_female}\n") - output.append("Male count: ${male_count}\n") - output.append("Female count: ${female_count}\n") - output.append("Total count: ${total_count}\n") - output.append("Males: ${male.join(',')}\n") - output.append("Females: ${female.join(',')}\n") + def List male = genders["male"] + def List female = genders["female"] + def Integer male_count = male.size() + def Integer female_count = female.size() + def Float male_to_female_ratio = male_count / female_count + def Integer total_count = male_count + female_count + + return """# plot_type: 'table' +Male to female ratio\tMale count\tFemale count\tTotal count\tMales\tFemales +${male_to_female_ratio}\t${male_count}\t${female_count}\t${total_count}\t${male.join(",")}\t${female.join(",")} +""" } /* From 6bfba16248dfae9c33190cc261718f30ac5c4f24 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Tue, 23 Apr 2024 12:57:34 +0200 Subject: [PATCH 2/4] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2fc384..10d04ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v1.2.0dev +### New features + +1. The metrics are now in the multiqc report instead of in a separate file + ### Changes 1. Updated the pipeline template to nf-core v2.13.1 From 7a022e7bd7e3f38419e3c0cc3db29d1bbdcd9dc3 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Tue, 23 Apr 2024 13:51:28 +0200 Subject: [PATCH 3/4] fix nf-tests --- tests/main.nf.test | 2 +- tests/main.nf.test.snap | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/main.nf.test b/tests/main.nf.test index 4f920c6..f76cb77 100644 --- a/tests/main.nf.test +++ b/tests/main.nf.test @@ -13,7 +13,7 @@ nextflow_pipeline { input = "${projectDir}/tests/inputs/samplesheet.csv" outdir = "${outputDir}" prefix = "test_reference" - bin_sizes = "10000,5" + bin_sizes = "10,5" max_cpus = 2 max_memory = '6.GB' max_time = '6.h' diff --git a/tests/main.nf.test.snap b/tests/main.nf.test.snap index 135c352..523cad8 100644 --- a/tests/main.nf.test.snap +++ b/tests/main.nf.test.snap @@ -5,7 +5,6 @@ ], [ - "metrics.txt:md5,bdb678960431c256e283e21d6e1db1ed", [ [ @@ -14,7 +13,7 @@ "multiqc_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" ], "test_reference_10kbp.npz:md5,d41d8cd98f00b204e9800998ecf8427e", - "test_reference_5bp.npz:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_reference_5kbp.npz:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "meta": { From da897b261da63238eec439f508386508e52564f2 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Tue, 23 Apr 2024 15:13:46 +0200 Subject: [PATCH 4/4] make the pipeline pluggable + add extra check --- main.nf | 29 ++++++++++++++++++++++++++++- workflows/wisecondorx.nf | 37 ++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/main.nf b/main.nf index 5165c1a..25cd927 100644 --- a/main.nf +++ b/main.nf @@ -20,6 +20,24 @@ include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_wise params.fasta = getGenomeAttribute('fasta') params.fai = getGenomeAttribute('fai') +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ADDITIONAL INPUT VALIDATION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +def List val_bin_sizes = params.bin_sizes.split(",").collect { it as Integer } +def Integer lowestBinSize = val_bin_sizes.min() +val_bin_sizes.each { bin_size -> + if(bin_size % lowestBinSize != 0) { + error(""" +All bin sizes should be divisible by the lowest bin size! +${bin_size} is not divisible by ${lowestBinSize}... +""") + } +} + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS @@ -53,7 +71,16 @@ workflow NFCMGG_WISECONDORX { // WORKFLOW: Run pipeline // WISECONDORX ( - samplesheet + samplesheet, + params.fasta, + params.fai, + val_bin_sizes, + params.no_metrics, + params.prefix, + params.outdir, + params.multiqc_config, + params.multiqc_logo, + params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) ) emit: diff --git a/workflows/wisecondorx.nf b/workflows/wisecondorx.nf index 449bd4d..1bc5f7f 100644 --- a/workflows/wisecondorx.nf +++ b/workflows/wisecondorx.nf @@ -1,5 +1,3 @@ -import groovy.yaml.YamlBuilder - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS @@ -26,7 +24,16 @@ include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore workflow WISECONDORX { take: - ch_samplesheet // channel: samplesheet read in from --input + ch_samplesheet // queue channel: samplesheet read in from --input + fasta // string: the reference fasta file + fai // string: the index of the reference fasta file + val_bin_sizes // list: a list of bin sizes to use + no_metrics // boolean: deactivate the generation of metrics + prefix // string: the prefix to be used by the output file + outdir // string: the path of the output directory + multiqc_config // string: the path to the multiqc config + multiqc_logo // string: the path to the multiqc logo + multiqc_methods_description // file: the file containing the multiqc custom method descriptions main: @@ -37,11 +44,11 @@ workflow WISECONDORX { // Create optional input files // - ch_fasta = Channel.fromPath(params.fasta, checkIfExists:true) - .map { [[id:params.genome ?: "fasta"], it] } + ch_fasta = Channel.fromPath(fasta, checkIfExists:true) + .map { [[id:"fasta"], it] } .collect() - if(!params.fai) { + if(!fai) { SAMTOOLS_FAIDX( ch_fasta, [[],[]] @@ -51,8 +58,8 @@ workflow WISECONDORX { SAMTOOLS_FAIDX.out.fai .set { ch_fai } } else { - ch_fai = Channel.fromPath(params.fai, checkIfExists:true) - .map { [[id:params.genome ?: "fasta"], it] } + ch_fai = Channel.fromPath(fai, checkIfExists:true) + .map { [[id:"fasta"], it] } .collect() } @@ -78,7 +85,7 @@ workflow WISECONDORX { .mix(ch_input.indexed) .set { ch_indexed } - if(!params.no_metrics){ + if(!no_metrics){ // // Define the gender if it's not given @@ -149,11 +156,11 @@ workflow WISECONDORX { WISECONDORX_CONVERT.out.npz .map { meta, npz -> - new_meta = [id:params.prefix ?: dateFormat] + new_meta = [id:prefix ?: dateFormat] [ new_meta, npz ] } .groupTuple() // All files should be present here, so no size is needed - .combine(params.bin_sizes.split(",")) + .combine(val_bin_sizes) .map { meta, npz, bin_size -> new_meta = meta + [bin_size:bin_size] [ new_meta, npz ] @@ -167,18 +174,18 @@ workflow WISECONDORX { // Collate and save software versions // softwareVersionsToYAML(ch_versions) - .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_pipeline_software_mqc_versions.yml', sort: true, newLine: true) + .collectFile(storeDir: "${outdir}/pipeline_info", name: 'nf_core_pipeline_software_mqc_versions.yml', sort: true, newLine: true) .set { ch_collated_versions } // // MODULE: MultiQC // ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) - ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty() - ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty() + ch_multiqc_custom_config = multiqc_config ? Channel.fromPath(multiqc_config, checkIfExists: true) : Channel.empty() + ch_multiqc_logo = multiqc_logo ? Channel.fromPath(multiqc_logo, checkIfExists: true) : Channel.empty() summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) - ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) + ch_multiqc_custom_methods_description = multiqc_methods_description ch_methods_description = Channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions)