<https://docs.seqera.io/multiqc/reports/customisat...
# multiqc
n
https://docs.seqera.io/multiqc/reports/customisation#software-versions-yaml-file states:
If you prefer to provide versions in a separate YAML file, MultiQC will also look for filenames ending in
*_mqc_versions.(yml|yaml)
in your search path, for example
rnaseq_mqc_versions.yml
or
mapping_mqc_versions.yaml
. The content of these YAML files should be a YAML dictionary, similar to the previous examples but without the top level
software_versions
.
...but it appears that at least most nf-core pipelines/modules use
versions.yml
, and not
*_mqc_versions.(yml|yaml)
. At least for nf-core/rnaseq, the following is used:
Copy code
softwareVersionsToYAML(ch_versions)
        .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_rnaseq_software_mqc_versions.yml', sort: true, newLine: true)
        .set { ch_collated_versions }
Is there a way to just use
versions.yml
instead of requiring this somewhat complex step extra step of using
softwareVersionsToYAML
?
Why must the software be included in the file name, given that it is in the yaml file already? For example:
Copy code
cat <<-END_VERSIONS > versions.yml
    "${task.process}":
        salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g")
    END_VERSIONS
Lastly, calling the executable to get the version for every single job is inefficient, especially for 10's or 100's of 1000's of jobs. Maybe using a version introspection system divorced from processes would be helpful, in which the user provides a command that is run once per container/env (similar to Snakemake). For example:
Copy code
process {
  versions {
    container = 'quay.io/biocontainers/salmon:1.10.3--hecfa306_0'
    command = 'salmon: $(echo \$(salmon --version) | sed -e "s/salmon //g")'
  }
}
m
so we add the software because you could have multiple software in a single container: https://github.com/nf-core/modules/blob/master/modules/nf-core/bwa/mem/main.nf#L48-L52
n
so we add the software
You mean adding the software to the file name? Really, versions should be named by container or conda env, right?
m
so each modules produce a
versions.yml
file
All of them gets collected and produce a single
*_mqc_versions.yml
sorry, edited, because pasted the wrong lines
n
All of them gets collected and produce a single
softwareVersionsToYAML
is not built into nextflow, and there seems to be no standard docs on collecting versions into one yaml file
m
you are right,
Currently this all sit in a subworkflow hosted in modules
n
Any plans on making this process more integrated into nextflow (docs and/or build into the nextflow codebase)?
m
So our plans at the moment would be to migrate that into a plugin. But yeah, definitively some extra-documentation would be good
👍 1
n
Any thoughts on:
Lastly, calling the executable to get the version for every single job is inefficient, especially for 10's or 100's of 1000's of jobs.
Maybe using a version introspection system divorced from processes would be helpful, in which the user provides a command that is run once per container/env (similar to Snakemake).
m
I would agree with you on that bit. I'd say this way of getting the versions is not the most optimal one
The Nextflow devs have been thinking of smarter ways to deal with this particular thing
Currently what we're doing is crude, but the easiest due to the way Nextflow work
n
Yeah, it's something I miss about Snakemake: obtaining software versions was much more efficient and streamlined
m
I mean you could always "trust" the conda declarations on use that directly
but the way I see it, since you can always overwrite all of that with your configurations, it's safer to get these infos on run time and be sure
But I do agree with you than we should be able to run this command only once per process
Basically this was developed downstream (ie at the pipeline level) when we implemented the modules repo
The Nextflow devs have thought of helping us out with these ideas: https://github.com/nextflow-io/nextflow/pull/4493
n
So
cmd
would just be run once per process?
m
so I'd say this ties in with
topic
n
It would be helpful if https://www.nextflow.io/docs/latest/process.html#eval-output-eval included examples of where
eval
is useful
m
but the uniqueness of running the cmd is a good question
I will investigate that
👍 1
yeah, I think we don't have much examples yet, because we haven't made much yet
n
Is the general thought that
eval
would be used to obtain software versions?
m
It is my thoughts
n
So how would that work for creating the yaml for multiqc?
m
I don't think it's general yet
So there's an old POC for that
Let me dig that up for you
🙏 1
n
https://nextflow.io/docs/latest/reference/channel.html#topic is definitely helpful for aspects like
versions
. My current code for a simple pipeline:
Copy code
ch_version_files = ch_version_files.mix(STAR_map.out.versions)
        .mix(SALMON_quant.out.versions)
        .mix(TXimport.out.versions)
        .mix(ALIGNMENTS_distances.out.versions)
        .mix(BAM_MARKDUPLICATES_PICARD.out.versions)
        .mix(STRANDEDNESS_fromSpliceMotifs.out.versions)
        .mix(BAM_RSEQC.out.versions)
At least to me, https://github.com/nf-core/rnaseq/pull/1115 is unclear on how
eval
would actually be used for obtaining all software versions and adding them to the final multiqc report
m
The whole idea behind
topic
is to avoid having such multiple lines
ch_version_files = ch_version_files.mix(STAR_map.out.versions)
It really is why it was designed for
We should call it
maxim
operator
One of the best compliment I ever got from Paolo
👏 1
😆 1
p
Note that all of this ☝🏻 is not specific to MultiQC. There are several things going on here: • MultiQC natively pulls software versions from logs where it can • MultiQC can take a file of version numbers if you supply it • nf-core likes to have process name <> software name association for version numbers, and jumps through a bunch of hoops to do it
nf-core was doing this before the MultiQC features, and before the Nextflow syntax. So there's a bit of catch up needed at some point to simplify the custom nf-core implementation and use the new native functionality in the tools
👍 1
(partly done already I think)