Running MetaFlux¶
MetaFlux is launched with snakemake. Everything that varies between runs lives
in the config file, so the command line stays short and looks the same for both
modes.
Run from the repository root¶
The Snakefile resolves configfile: "config/config.yaml" against the directory the
command was launched from, not against its own location. Two more lookups behave
the same way: references.refdb_root defaults to the relative path refdb, and
user-supplied marker packs are read from config/markers/. Launching from
somewhere else silently changes where all three point.
Paths inside the config (input.fastq_dir, output.out_dir, references.kraken_db,
the primer FASTAs) are best given as absolute paths, which makes them immune to this.
The two commands¶
# Always preview the plan first
snakemake --sdm conda --cores 16 --configfile config/config.yaml --dry-run
# Execute
snakemake --sdm conda --cores 16 --configfile config/config.yaml
A dry run (--dry-run, or -n) builds the job list and prints it without running
anything or writing any file. It is worth the ten seconds every time, because
MetaFlux does most of its validation while the workflow is being read — before any
job starts. A dry run therefore catches, among others:
modeset to something other thanampliconorshotgun;- an
amplicon.typethat matches no marker pack; - primer FASTAs that do not exist (amplicon), or a
kraken_dbthat does not exist (shotgun); - a config still using the retired
include_pattern/exclude_patternfilter keys; - ITS combined with
length_filter.mode: autobut a manualexpected_length, which would otherwise crash after the full DADA2 run.
The same parse step prints a banner line to stderr:
Checking that the sample count is the expected one costs nothing and catches a
mistyped fastq_dir or a mate-naming mismatch before a long run starts.
--configfile is optional
The Snakefile already loads config/config.yaml. Passing --configfile makes
the choice explicit, and is how a different config — one per marker, or one per
project — is selected.
--sdm conda and --conda-prefix¶
--sdm conda is short for --software-deployment-method conda. It tells Snakemake
to build each rule's own conda environment from the YAML files in
workflow/envs/ and to run that rule inside it. Only Snakemake itself has to be
installed by hand; DADA2, Cutadapt, Kraken2, Bracken and the rest are installed by
the workflow on first use. Leaving the flag out makes every rule run against
whatever happens to be on PATH, which is exactly what the per-rule environments
exist to avoid.
The environments are built once and then reused. By default they go into
.snakemake/conda/ inside the working directory, which is why running from the
repository root keeps reusing the same ones. --conda-prefix moves them somewhere
else:
That is useful when several checkouts, several users, or several working directories should share one set of environments instead of each building its own — they are a few gigabytes in total, and building them takes minutes.
Pre-build the environments
--conda-create-envs-only builds every environment and stops. Handy before a
cluster run, so the compute nodes are not each waiting on conda, and on
machines where the network is only reachable from the login node.
Useful patterns¶
# Override the mode without editing the config
snakemake --sdm conda --cores 16 --config mode=shotgun
# Cap concurrent memory (e.g. memory-bound steps)
snakemake --sdm conda --cores 16 --resources mem_mb=32000
# Resume after an interruption
snakemake --sdm conda --cores 16 --rerun-incomplete
# Cluster execution: supply a profile (e.g. SLURM) — per-rule threads/mem_mb are honoured
snakemake --sdm conda --profile <slurm-profile>
Overriding the mode. --config mode=shotgun replaces the top-level mode key
for that invocation only; the file on disk is untouched and every other setting
still comes from it. The shotgun section of the config has to be filled in for this
to work — references.kraken_db in particular, which is checked while the workflow
is read. Nested settings (amplicon.type, for instance) can't be reached with a dotted
key — --config only accepts plain top-level identifiers, so overriding one
means replacing its whole parent block with inline YAML
(--config 'amplicon={type: ITS}') rather than a single key=value pair.
Keeping one config file per marker and selecting it with --configfile is
clearer.
Give each mode its own out_dir
Both modes write stats/read_tracking.txt and multiqc/multiqc_report.html.
Running the second mode into the first mode's output directory overwrites them.
The same applies to running two markers into one directory: the ASV files in
5.dada2/ are not named after the marker.
Limiting concurrency. --cores is the total CPU budget on the machine; a rule
asking for more threads than that is scaled down to fit. Lowering --cores is
therefore the way to run fewer heavy jobs side by side. Memory is capped
separately: every heavy rule declares a mem_mb — from resources.mem_mb.* in the
config, except Kraken2, whose figure is computed while the workflow is read — so
--resources mem_mb=32000 lets Snakemake start jobs only while their declared memory
still fits in 32 GB. This matters most for Kraken2 with
shotgun.kraken.memory_mapping: false, where every concurrent process loads its own
full copy of the database, and for the DADA2 steps, which hold all samples in
memory at once.
--jobs is not a second lever here. On a local run Snakemake treats it as an alias
for --cores, and passing both switches the core budget off rather than adding a
job cap on top of it — --jobs 4 --cores 16 would run four jobs at once whatever
their thread counts add up to. It belongs on cluster runs only, see below.
Resuming. An interrupted run leaves two kinds of debris. Files that a job was
part-way through writing are marked incomplete, and --rerun-incomplete rebuilds
them instead of trusting them. A run killed outright (Ctrl-C twice, a node
failure, an OOM kill) can also leave the working directory locked, which Snakemake
reports on the next launch; snakemake --unlock clears it. Everything that
finished cleanly is kept and not recomputed.
Cluster execution. A profile holds the submission settings for the scheduler
(partition, account, how threads and mem_mb map to sbatch arguments), so the
MetaFlux command line does not change. The per-rule values come from
resources.threads.<rule> and resources.mem_mb.<rule> in the config, falling back
to threads_default (4) and mem_mb_default (2000) for any rule not listed.
Kraken2 is the exception: its memory request is computed while the workflow is read,
from shotgun.kraken.memory_mapping and the actual size of the database's
hash.k2d — 20000 MB with memory mapping on (the database itself is shared through
the operating system's file cache), otherwise the hash size plus 10 % headroom. With
a profile, --jobs becomes the cap on jobs queued with the scheduler at once —
the one setting where it does something --cores does not.
What happens on a re-run¶
Snakemake only rebuilds what is missing or out of date. Re-running a completed workflow with no changes does nothing at all and says so. Three practical consequences:
- A deleted or edited output is rebuilt, and only what is needed to rebuild it
runs. Deleting
6.taxonomy/asv_table.txtre-runsassign_taxonomy; the DADA2 steps upstream are already satisfied and are skipped. - Changing the config can be enough to mark a step out of date. Current
Snakemake versions consider more than file timestamps: a changed rule parameter, a
changed script, or a changed conda environment also count. Because the contaminant
keep/discard lists reach
assign_taxonomyas rule parameters, editing them re-runs the taxonomy step alone and leaves the denoising untouched. Adding--rerun-triggers mtimerestricts the comparison to timestamps only. - A dry run answers the question directly.
-nprints exactly which jobs a re-run would execute, which is faster than reasoning about it.
Two caches deliberately sit outside this machinery and survive across runs:
reference databases under refdb/, and the amplicon-length probe result under
refdb/cache/ inside the MetaFlux checkout — that second path is fixed and does
not follow references.refdb_root. The probe's filename encodes the marker, its
reference, and a hash of both primer sequences, so it is reused whenever those
are unchanged and recomputed when a primer changes. See
output files for what a run writes where.
Two mode-specific notes¶
Shotgun, BioProject mode
Setting input.bioproject to an NCBI accession makes MetaFlux resolve the
project's PAIRED runs through NCBI e-utils and download them into fastq_dir
before anything else. Single-end runs are skipped — they do not fit the rest of
the pipeline. The run list is cached as {accession}_runinfo.csv in fastq_dir,
so later invocations do not need the network for that step, and
input.accession_list narrows the set to named runs.
Shotgun, first Kraken2 call
The first Kraken2 job reads the whole database off disk. That is slow while the cache is cold and fast once the operating system has the database in memory, so a first sample that seems to hang is usually just loading.
See also¶
- Configuration — every key referred to here.
- Output files — what the run produces and which file feeds which step.
- Troubleshooting — YAML errors, empty tables, and the
truncLentrap.