Chapter 3 Additional features
Automatic reports
Snakemake can automatically create HTML reports with
Such a report contains runtime statistics, a visualization of the workflow topology, used software and data provenance information.
In addition, you can mark any output file generated in your workflow for inclusion into the report.
It will be encoded directly into the report, such that it can be, e.g., emailed as a self-contained document.
The reader (e.g., a collaborator of yours) can at any time download the enclosed results from the report for further use, e.g., in a manuscript you write together.
In this example, please mark the output file "results/plots/quals.png" for inclusion by replacing it with report("results/plots/quals.png", caption="report/calling.rst", category="Variants") and adding a file report/calling.rst, containing some description of the output file.
This description will be presented as caption in the resulting report.
Benchmarking
With the benchmark directive, Snakemake can be instructed to measure the wall clock time of a job.
We activate benchmarking for the rule bwa_mem:
rule bwa_mem:
input:
"data/genome.fa",
get_bwa_mem_input_fastqs
output:
temp("results/mapped_reads/{sample}.sam")
log:
"results/logs/bwa_mem_{sample}.log"
benchmark:
"results/benchmarks/bwa_mem_{sample}.benchmark.txt"
params:
rg=r"@RG\tID:{sample}\tSM:{sample}"
threads: 3
singularity:
"oras://registry.forgemia.inra.fr/gafl/singularity/bwa/bwa:latest"
shell:
"bwa mem -R '{params.rg}' -t {threads} {input} > {output} 2> {log}"The benchmark directive takes a string that points to the file where benchmarking results shall be stored.
Similar to output files, the path can contain wildcards (it must be the same wildcards as in the output files).
When a job derived from the rule is executed, Snakemake will measure the wall clock time and memory usage (in MiB) and store it in the file in tab-delimited format.
It is possible to repeat a benchmark multiple times in order to get a sense for the variability of the measurements.
This can be done by annotating the benchmark file, e.g., with repeat("benchmarks/{sample}.bwa.benchmark.txt", 3) Snakemake can be told to run the job three times.
The repeated measurements occur as subsequent lines in the tab-delimited benchmark file.
Modularization
In order to re-use building blocks or simply to structure large workflows, it is sometimes reasonable to split a workflow into modules.
For this, Snakemake provides the include directive to include another Snakefile into the current one, e.g.:
Alternatively, Snakemake allows to define sub-workflows. A sub-workflow refers to a working directory with a complete Snakemake workflow. Output files of that sub-workflow can be used in the current Snakefile. When executing, Snakemake ensures that the output files of the sub-workflow are up-to-date before executing the current workflow. This mechanism is particularly useful when you want to extend a previous analysis without modifying it. For details about sub-workflows, see the documentation.
Exercise
Put the read mapping related rules into a separate Snakefile and use the include directive to make them available in our example workflow again.
Automatic deployment of software dependencies
In order to get a fully reproducible data analysis, it is not sufficient to be able to execute each step and document all used parameters. The used software tools and libraries have to be documented as well. Conda can be used to specify an isolated software environment for a whole workflow. With Snakemake, you can go one step further and specify Conda environments per rule. This way, you can even make use of conflicting software versions (e.g. combine Python 2 with Python 3).
In our example, instead of using an external environment we can specify environments per rule, e.g.:
rule samtools_index:
input:
"results/sorted_reads/{sample}.bam"
output:
"results/sorted_reads/{sample}.bam.bai"
conda:
"envs/samtools.yaml"
shell:
"samtools index {input}"with envs/samtools.yaml defined as
NOTE: The conda directive does not work in combination with
runblocks, because they have to share their Python environment with the surrounding snakefile.
When Snakemake is executed with
It will automatically create required environments and activate them before a job is executed. It is best practice to specify at least the major and minor version of any packages in the environment definition. Specifying environments per rule in this way has two advantages. First, the workflow definition also documents all used software versions. Second, a workflow can be re-executed (without admin rights) on a vanilla system, without installing any prerequisites apart from Snakemake and Miniconda.
Tool wrappers
In order to simplify the utilization of popular tools, Snakemake provides a repository of so-called wrappers (the Snakemake wrapper repository).
A wrapper is a short script that wraps (typically) a command line application and makes it directly addressable from within Snakemake.
For this, Snakemake provides the wrapper directive that can be used instead of shell, script, or run.
For example, the rule bwa_mem could alternatively look like this:
rule bwa_mem:
input:
ref="data/genome.fa",
sample=get_bwa_mem_input_fastqs
output:
temp("results/mapped_reads/{sample}.sam")
log:
"results/logs/bwa_mem_{sample}.log"
benchmark:
"results/benchmarks/bwa_mem_{sample}.benchmark.txt"
params:
rg=r"@RG\tID:{sample}\tSM:{sample}"
threads: 3
wrapper:
"0.15.3/bio/bwa/mem"NOTE: Updates to the Snakemake wrapper repository are automatically tested via continuous integration.
The wrapper directive expects a (partial) URL that points to a wrapper in the repository.
These can be looked up in the corresponding database.
The first part of the URL is a Git version tag.
Upon invocation, Snakemake will automatically download the requested version of the wrapper.
Furthermore, in combination with --use-conda, the required software will be automatically deployed before execution.
Cluster execution
By default, Snakemake executes jobs on the local machine it is invoked on. Alternatively, it can execute jobs in distributed environments, e.g., compute clusters or batch systems. If the nodes share a common file system, / supports three alternative execution modes.
In cluster environments, compute jobs are usually submitted as shell scripts via commands like sbatch.
Snakemake provides a generic mode to execute on such clusters.
By invoking Snakemake with
Each job will be compiled into a shell script that is submitted with the given command (here sbatch).
The --jobs flag limits the number of concurrently submitted jobs to 100.
This basic mode assumes that the submission command returns immediately after submitting the job.
Some clusters allow to run the submission command in synchronous mode, such that it waits until the job has been executed.
In such cases, we can invoke e.g.
The specified submission command can also be decorated with additional parameters taken from the submitted job. For example, the number of used threads can be accessed in braces similarly to the formatting of shell commands, e.g.
To support additional cluster specific parametrization, a Snakefile can be complemented by a Cluster Configuration file, see for instance config/ressources.genologin.yaml that you may declare in the config/config.yaml file as:
Finally, the submission fo the workflow can be defined in a separate bash file, see for instance job.sh that you can submit as:
Constraining wildcards
Snakemake uses regular expressions to match output files to input files and determine dependencies between the jobs.
Sometimes it is useful to constrain the values a wildcard can have.
This can be achieved by adding a regular expression that describes the set of allowed wildcard values.
For example, the wildcard sample in the output file "results/sorted_reads/{sample}.bam" can be constrained to only allow alphanumeric sample names as "results/sorted_reads/{sample,[A-Za-z0-9]+}.bam".
Constraints may be defined per rule or globally using the wildcard_constraints keyword.
This mechanism helps to solve two kinds of ambiguity.
It can help to avoid ambiguous rules, i.e. two or more rules that can be applied to generate the same output file. Other ways of handling ambiguous rules are described in the Section Handling Ambiguous Rules.
It can help to guide the regular expression based matching so that wildcards are assigned to the right parts of a file name.
Consider the output file {sample}.{group}.txt and assume that the target file is A.1.normal.txt.
It is not clear whether dataset="A.1" and group="normal" or dataset="A" and group="1.normal" is the right assignment.
Here, constraining the dataset wildcard by {sample,[A-Z]+}.{group} solves the problem.
When dealing with ambiguous rules, it is best practice to first try to solve the ambiguity by using a proper file structure, for example, by separating the output files of different steps in different directories.