diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ee1a97beb..2de8ceddeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Add `actions/upload-artifact` step to the awstest workflows, to expose the debug log file - Bioconda incompatible conda channel setups now result in more informative error messages ([#1812](https://github.com/nf-core/tools/pull/1812)) +- Update MultiQC module, update supplying MultiQC default and custom config files to module +- Add a 'recommend' methods description text to MultiQC to help pipeline users report pipeline usage in publications ([#1749](https://github.com/nf-core/tools/pull/1749)) ### Linting diff --git a/docs/images/nf-core-bump-version.svg b/docs/images/nf-core-bump-version.svg index a956d2c922..b1ba414fde 100644 --- a/docs/images/nf-core-bump-version.svg +++ b/docs/images/nf-core-bump-version.svg @@ -93,6 +93,9 @@ + + + @@ -101,9 +104,9 @@ - + - + $ nf-core bump-version 1.1 diff --git a/docs/images/nf-core-create.svg b/docs/images/nf-core-create.svg index 96278a10cd..72f19730f0 100644 --- a/docs/images/nf-core-create.svg +++ b/docs/images/nf-core-create.svg @@ -123,6 +123,9 @@ + + + @@ -131,7 +134,7 @@ - + diff --git a/docs/images/nf-core-download.svg b/docs/images/nf-core-download.svg index 9fd4ecc75a..f3b79f8dd6 100644 --- a/docs/images/nf-core-download.svg +++ b/docs/images/nf-core-download.svg @@ -92,6 +92,9 @@ + + + @@ -100,9 +103,9 @@ - + - + $ nf-core download rnaseq -r 3.8 --outdir nf-core-rnaseq -x none -c none diff --git a/docs/images/nf-core-launch-rnaseq.svg b/docs/images/nf-core-launch-rnaseq.svg index 0815e2d7fe..a29248b02e 100644 --- a/docs/images/nf-core-launch-rnaseq.svg +++ b/docs/images/nf-core-launch-rnaseq.svg @@ -88,6 +88,9 @@ + + + @@ -96,9 +99,9 @@ - + - + $ nf-core launch rnaseq -r 3.8.1 diff --git a/docs/images/nf-core-licences.svg b/docs/images/nf-core-licences.svg index df8efdc33f..6d998ba454 100644 --- a/docs/images/nf-core-licences.svg +++ b/docs/images/nf-core-licences.svg @@ -124,6 +124,9 @@ + + + @@ -132,9 +135,9 @@ - + - + $ nf-core licences deepvariant diff --git a/docs/images/nf-core-list-rna.svg b/docs/images/nf-core-list-rna.svg index def102c509..e6b508831b 100644 --- a/docs/images/nf-core-list-rna.svg +++ b/docs/images/nf-core-list-rna.svg @@ -114,6 +114,9 @@ + + + @@ -122,9 +125,9 @@ - + - + $ nf-core list rna rna-seq diff --git a/docs/images/nf-core-list-stars.svg b/docs/images/nf-core-list-stars.svg index 6b8aa5659b..bc8d85fbf5 100644 --- a/docs/images/nf-core-list-stars.svg +++ b/docs/images/nf-core-list-stars.svg @@ -111,9 +111,9 @@ - + - + $ nf-core list -s stars diff --git a/docs/images/nf-core-list.svg b/docs/images/nf-core-list.svg index 943cf41219..6ee5a7aa0e 100644 --- a/docs/images/nf-core-list.svg +++ b/docs/images/nf-core-list.svg @@ -114,9 +114,9 @@ - + - + $ nf-core list diff --git a/docs/images/nf-core-modules-bump-version.svg b/docs/images/nf-core-modules-bump-version.svg index 946da37712..80ab0abbcc 100644 --- a/docs/images/nf-core-modules-bump-version.svg +++ b/docs/images/nf-core-modules-bump-version.svg @@ -105,6 +105,9 @@ + + + @@ -113,9 +116,9 @@ - + - + $ nf-core modules bump-versions fastqc diff --git a/docs/images/nf-core-modules-create.svg b/docs/images/nf-core-modules-create.svg index 741c98771e..d5e55b2745 100644 --- a/docs/images/nf-core-modules-create.svg +++ b/docs/images/nf-core-modules-create.svg @@ -119,6 +119,9 @@ + + + @@ -127,9 +130,9 @@ - + - + $ nf-core modules create fastqc --author @nf-core-bot  --label process_low --meta --force diff --git a/docs/images/nf-core-modules-info.svg b/docs/images/nf-core-modules-info.svg index ba471c1863..6c4f9a30d0 100644 --- a/docs/images/nf-core-modules-info.svg +++ b/docs/images/nf-core-modules-info.svg @@ -178,6 +178,9 @@ + + + @@ -186,7 +189,7 @@ - + diff --git a/docs/images/nf-core-modules-install.svg b/docs/images/nf-core-modules-install.svg index d3527d270a..6ad1026cab 100644 --- a/docs/images/nf-core-modules-install.svg +++ b/docs/images/nf-core-modules-install.svg @@ -87,6 +87,9 @@ + + + @@ -95,9 +98,9 @@ - + - + $ nf-core modules install abacas diff --git a/docs/images/nf-core-modules-lint.svg b/docs/images/nf-core-modules-lint.svg index e16d844a01..eb945ee68f 100644 --- a/docs/images/nf-core-modules-lint.svg +++ b/docs/images/nf-core-modules-lint.svg @@ -174,7 +174,7 @@ - + diff --git a/docs/images/nf-core-modules-list-local.svg b/docs/images/nf-core-modules-list-local.svg index 0344143c2b..d60232b7c5 100644 --- a/docs/images/nf-core-modules-list-local.svg +++ b/docs/images/nf-core-modules-list-local.svg @@ -132,9 +132,9 @@ - + - + $ nf-core modules list local diff --git a/docs/images/nf-core-modules-list-remote.svg b/docs/images/nf-core-modules-list-remote.svg index dfbe22e11a..4a753e8d4f 100644 --- a/docs/images/nf-core-modules-list-remote.svg +++ b/docs/images/nf-core-modules-list-remote.svg @@ -132,9 +132,9 @@ - + - + $ nf-core modules list remote diff --git a/docs/images/nf-core-modules-mulled.svg b/docs/images/nf-core-modules-mulled.svg index 163f41a53d..deb84df66b 100644 --- a/docs/images/nf-core-modules-mulled.svg +++ b/docs/images/nf-core-modules-mulled.svg @@ -85,6 +85,9 @@ + + + @@ -93,9 +96,9 @@ - + - + $ nf-core modules mulled pysam==0.16.0.1 biopython==1.78 diff --git a/docs/images/nf-core-modules-patch.svg b/docs/images/nf-core-modules-patch.svg index 0c7a4dd9f8..ffb4a69c87 100644 --- a/docs/images/nf-core-modules-patch.svg +++ b/docs/images/nf-core-modules-patch.svg @@ -134,6 +134,9 @@ + + + @@ -142,9 +145,9 @@ - + - + $ nf-core modules patch fastqc diff --git a/docs/images/nf-core-modules-remove.svg b/docs/images/nf-core-modules-remove.svg index bc67a96483..12712e23a0 100644 --- a/docs/images/nf-core-modules-remove.svg +++ b/docs/images/nf-core-modules-remove.svg @@ -80,6 +80,9 @@ + + + @@ -88,9 +91,9 @@ - + - + $ nf-core modules remove abacas diff --git a/docs/images/nf-core-modules-test.svg b/docs/images/nf-core-modules-test.svg index b65ae7a6ad..d6ef0d7355 100644 --- a/docs/images/nf-core-modules-test.svg +++ b/docs/images/nf-core-modules-test.svg @@ -83,6 +83,9 @@ + + + @@ -91,9 +94,9 @@ - + - + $ nf-core modules test samtools/view --no-prompts diff --git a/docs/images/nf-core-modules-update.svg b/docs/images/nf-core-modules-update.svg index 080277cff0..c330cf219a 100644 --- a/docs/images/nf-core-modules-update.svg +++ b/docs/images/nf-core-modules-update.svg @@ -92,6 +92,9 @@ + + + @@ -100,9 +103,9 @@ - + - + $ nf-core modules update --all --no-preview diff --git a/docs/images/nf-core-schema-build.svg b/docs/images/nf-core-schema-build.svg index 87f27862ac..fabdefa4bc 100644 --- a/docs/images/nf-core-schema-build.svg +++ b/docs/images/nf-core-schema-build.svg @@ -87,6 +87,9 @@ + + + @@ -95,9 +98,9 @@ - + - + $ nf-core schema build --no-prompts diff --git a/docs/images/nf-core-schema-lint.svg b/docs/images/nf-core-schema-lint.svg index 0083a44941..68ca3f9707 100644 --- a/docs/images/nf-core-schema-lint.svg +++ b/docs/images/nf-core-schema-lint.svg @@ -83,6 +83,9 @@ + + + @@ -91,9 +94,9 @@ - + - + $ nf-core schema lint nextflow_schema.json diff --git a/docs/images/nf-core-schema-validate.svg b/docs/images/nf-core-schema-validate.svg index 2e089460a0..b3ab5d3dc5 100644 --- a/docs/images/nf-core-schema-validate.svg +++ b/docs/images/nf-core-schema-validate.svg @@ -86,6 +86,9 @@ + + + @@ -94,9 +97,9 @@ - + - + $ nf-core schema validate nf-core-rnaseq/workflow nf-params.json diff --git a/docs/images/nf-core-sync.svg b/docs/images/nf-core-sync.svg index ec1ac051e8..32f4bd448c 100644 --- a/docs/images/nf-core-sync.svg +++ b/docs/images/nf-core-sync.svg @@ -88,6 +88,9 @@ + + + @@ -96,9 +99,9 @@ - + - + $ nf-core sync 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)