diff --git a/nf_core/pipeline-template/assets/methods_description_template.yml b/nf_core/pipeline-template/assets/methods_description_template.yml
new file mode 100644
index 0000000000..b2dc0a99c1
--- /dev/null
+++ b/nf_core/pipeline-template/assets/methods_description_template.yml
@@ -0,0 +1,25 @@
+id: "{{ name_noslash }}-methods-description"
+description: "Suggested text and references to use when describing pipeline usage within the methods section of a publication."
+section_name: "{{ name }} Methods Description"
+section_href: "https://github.com/{{ name }}"
+plot_type: "html"
+## TODO nf-core: Update the HTML below to your prefered methods description, e.g. add publication citation for this pipeline
+## You inject any metadata in the Nextflow '${workflow}' object
+data: |
+ Methods
+ Data was processed using {{ name }} v${workflow.manifest.version} ${doi_text} of the nf-core collection of workflows (Ewels et al., 2020).
+ The pipeline was executed with Nextflow v${workflow.nextflow.version} (Di Tommaso et al., 2017) with the following command:
+ ${workflow.commandLine}
+ References
+
+ - Di Tommaso, P., Chatzou, M., Floden, E. W., Barja, P. P., Palumbo, E., & Notredame, C. (2017). Nextflow enables reproducible computational workflows. Nature Biotechnology, 35(4), 316-319. https://doi.org/10.1038/nbt.3820
+ - Ewels, P. A., Peltzer, A., Fillinger, S., Patel, H., Alneberg, J., Wilm, A., Garcia, M. U., Di Tommaso, P., & Nahnsen, S. (2020). The nf-core framework for community-curated bioinformatics pipelines. Nature Biotechnology, 38(3), 276-278. https://doi.org/10.1038/s41587-020-0439-x
+
+
+
Notes:
+
+ ${nodoi_text}
+ - The command above does not include parameters contained in any configs or profiles that may have been used. Ensure the config file is also uploaded with your publication!
+ - You should also cite all software used within this run. Check the "Software Versions" of this report to get version information.
+
+
diff --git a/nf_core/pipeline-template/assets/multiqc_config.yml b/nf_core/pipeline-template/assets/multiqc_config.yml
index a9cc6cdb35..440b0b9a3a 100644
--- a/nf_core/pipeline-template/assets/multiqc_config.yml
+++ b/nf_core/pipeline-template/assets/multiqc_config.yml
@@ -3,9 +3,11 @@ report_comment: >
analysis pipeline.{% if branded %} For information about how to interpret these results, please see the
documentation.{% endif %}
report_section_order:
- software_versions:
+ "{{ name_noslash }}-methods-description":
order: -1000
- "{{ name.lower().replace('/', '-') }}-summary":
+ software_versions:
order: -1001
+ "{{ name_noslash }}-summary":
+ order: -1002
export_plots: true
diff --git a/nf_core/pipeline-template/lib/WorkflowPipeline.groovy b/nf_core/pipeline-template/lib/WorkflowPipeline.groovy
index ba9199e6fc..252f127d80 100755
--- a/nf_core/pipeline-template/lib/WorkflowPipeline.groovy
+++ b/nf_core/pipeline-template/lib/WorkflowPipeline.groovy
@@ -2,6 +2,8 @@
// This file holds several functions specific to the workflow/{{ short_name }}.nf in the {{ name }} pipeline
//
+import groovy.text.SimpleTemplateEngine
+
class Workflow{{ short_name[0]|upper }}{{ short_name[1:] }} {
//
@@ -45,6 +47,23 @@ class Workflow{{ short_name[0]|upper }}{{ short_name[1:] }} {
return yaml_file_text
}
+ public static String methodsDescriptionText(run_workflow, mqc_methods_yaml) {
+ // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file
+ def meta = [:]
+ meta.workflow = run_workflow.toMap()
+ meta["manifest_map"] = run_workflow.manifest.toMap()
+
+ meta["doi_text"] = meta.manifest_map.doi ? "(doi: ${meta.manifest_map.doi})" : ""
+ 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. "
+
+ def methods_text = mqc_methods_yaml.text
+
+ def engine = new SimpleTemplateEngine()
+ def description_html = engine.createTemplate(methods_text).make(meta)
+
+ return description_html
+ }
+
{%- if igenomes -%}
//
// Exit pipeline if incorrect --genome key provided
diff --git a/nf_core/pipeline-template/modules.json b/nf_core/pipeline-template/modules.json
index 9c8d724aef..2a804dc1d0 100644
--- a/nf_core/pipeline-template/modules.json
+++ b/nf_core/pipeline-template/modules.json
@@ -6,16 +6,16 @@
"git_url": "https://github.com/nf-core/modules.git",
"modules": {
"custom/dumpsoftwareversions": {
- "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d",
- "branch": "master"
+ "branch": "master",
+ "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d"
},
"fastqc": {
- "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d",
- "branch": "master"
+ "branch": "master",
+ "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d"
},
"multiqc": {
- "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d",
- "branch": "master"
+ "branch": "master",
+ "git_sha": "16eee433b87b303bda650131ac5a0b1ad725e166"
}
}
}
diff --git a/nf_core/pipeline-template/modules/nf-core/modules/multiqc/main.nf b/nf_core/pipeline-template/modules/nf-core/modules/multiqc/main.nf
index 1264aac1eb..c8e6acee30 100644
--- a/nf_core/pipeline-template/modules/nf-core/modules/multiqc/main.nf
+++ b/nf_core/pipeline-template/modules/nf-core/modules/multiqc/main.nf
@@ -1,13 +1,15 @@
process MULTIQC {
label 'process_medium'
- conda (params.enable_conda ? 'bioconda::multiqc=1.12' : null)
+ conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null)
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
- 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' :
- 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }"
+ 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' :
+ 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }"
input:
- path multiqc_files
+ path multiqc_files, stageAs: "?/*"
+ path(multiqc_config)
+ path(multiqc_logo)
output:
path "*multiqc_report.html", emit: report
@@ -20,8 +22,25 @@ process MULTIQC {
script:
def args = task.ext.args ?: ''
+ def config = multiqc_config ? "--config $multiqc_config" : ''
"""
- multiqc -f $args .
+ multiqc \\
+ --force \\
+ $config \\
+ $args \\
+ .
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
+ END_VERSIONS
+ """
+
+ stub:
+ """
+ touch multiqc_data
+ touch multiqc_plots
+ touch multiqc_report.html
cat <<-END_VERSIONS > versions.yml
"${task.process}":
diff --git a/nf_core/pipeline-template/modules/nf-core/modules/multiqc/meta.yml b/nf_core/pipeline-template/modules/nf-core/modules/multiqc/meta.yml
index 6fa891efc2..a1029f3366 100644
--- a/nf_core/pipeline-template/modules/nf-core/modules/multiqc/meta.yml
+++ b/nf_core/pipeline-template/modules/nf-core/modules/multiqc/meta.yml
@@ -12,11 +12,21 @@ tools:
homepage: https://multiqc.info/
documentation: https://multiqc.info/docs/
licence: ["GPL-3.0-or-later"]
+
input:
- multiqc_files:
type: file
description: |
List of reports / files recognised by MultiQC, for example the html and zip output of FastQC
+ - multiqc_config:
+ type: file
+ description: Optional config yml for MultiQC
+ pattern: "*.{yml,yaml}"
+ - multiqc_logo:
+ type: file
+ description: Optional logo file for MultiQC
+ pattern: "*.{png}"
+
output:
- report:
type: file
@@ -38,3 +48,4 @@ authors:
- "@abhi18av"
- "@bunop"
- "@drpatelh"
+ - "@jfy133"
diff --git a/nf_core/pipeline-template/nextflow.config b/nf_core/pipeline-template/nextflow.config
index ba808b1d50..bc222cb6e4 100644
--- a/nf_core/pipeline-template/nextflow.config
+++ b/nf_core/pipeline-template/nextflow.config
@@ -23,7 +23,9 @@ params {
// MultiQC options
multiqc_config = null
multiqc_title = null
+ multiqc_logo = null
max_multiqc_email_size = '25.MB'
+ multiqc_methods_description = null
// Boilerplate options
outdir = null
@@ -192,6 +194,7 @@ manifest {
mainScript = 'main.nf'
nextflowVersion = '!>=21.10.3'
version = '{{ version }}'
+ doi = ''
}
// Load modules.config for DSL2 module specific options
diff --git a/nf_core/pipeline-template/nextflow_schema.json b/nf_core/pipeline-template/nextflow_schema.json
index 2be134ba08..d6c455d707 100644
--- a/nf_core/pipeline-template/nextflow_schema.json
+++ b/nf_core/pipeline-template/nextflow_schema.json
@@ -226,6 +226,17 @@
"fa_icon": "fas fa-cog",
"hidden": true
},
+ "multiqc_logo": {
+ "type": "string",
+ "description": "Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file",
+ "fa_icon": "fas fa-image",
+ "hidden": true
+ },
+ "multiqc_methods_description": {
+ "type": "string",
+ "description": "Custom MultiQC yaml file containing HTML including a methods description.",
+ "fa_icon": "fas fa-cog"
+ },
"tracedir": {
"type": "string",
"description": "Directory to keep pipeline Nextflow logs and reports.",
diff --git a/nf_core/pipeline-template/workflows/pipeline.nf b/nf_core/pipeline-template/workflows/pipeline.nf
index 24f78e7746..b978ab81bc 100644
--- a/nf_core/pipeline-template/workflows/pipeline.nf
+++ b/nf_core/pipeline-template/workflows/pipeline.nf
@@ -23,8 +23,9 @@ if (params.input) { ch_input = file(params.input) } else { exit 1, 'Input sample
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-ch_multiqc_config = file("$projectDir/assets/multiqc_config.yml", checkIfExists: true)
-ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config) : Channel.empty()
+ch_multiqc_config = params.multiqc_config ? file( params.multiqc_config, checkIfExists: true ) : file("$projectDir/assets/multiqc_config.yml", checkIfExists: true)
+ch_multiqc_logo = params.multiqc_logo ? file( params.multiqc_logo, checkIfExists: true ) : []
+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)
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -89,15 +90,19 @@ workflow {{ short_name|upper }} {
workflow_summary = Workflow{{ short_name[0]|upper }}{{ short_name[1:] }}.paramsSummaryMultiqc(workflow, summary_params)
ch_workflow_summary = Channel.value(workflow_summary)
+ methods_description = WorkflowTestpipeline.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description)
+ ch_methods_description = Channel.value(methods_description)
+
ch_multiqc_files = Channel.empty()
- ch_multiqc_files = ch_multiqc_files.mix(Channel.from(ch_multiqc_config))
- ch_multiqc_files = ch_multiqc_files.mix(ch_multiqc_custom_config.collect().ifEmpty([]))
ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml'))
+ ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml'))
ch_multiqc_files = ch_multiqc_files.mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect())
ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}.ifEmpty([]))
MULTIQC (
- ch_multiqc_files.collect()
+ ch_multiqc_files.collect(),
+ ch_multiqc_config,
+ ch_multiqc_logo
)
multiqc_report = MULTIQC.out.report.toList()
ch_versions = ch_versions.mix(MULTIQC.out.versions)