Skip to content

Importing from Nextflow

nf-metro can convert Nextflow’s built-in DAG output into a metro map.

Nextflow can export its pipeline DAG in mermaid format:

Terminal window
nextflow run my_pipeline.nf -preview -with-dag dag.mmd

The -preview flag skips execution and generates only the DAG. The resulting file uses Nextflow’s flowchart TB mermaid syntax, which nf-metro cannot render directly but can convert.

The quickest way to get a metro map is to convert and render in one step with the --from-nextflow flag. The examples below show the unedited output.

A simple five-process pipeline with no subworkflows:

workflow {
reads_ch = Channel.of(["sample1", [file("reads/s1_1.fq.gz"), file("reads/s1_2.fq.gz")]])
reference_ch = Channel.of(file("genome.fa"))
FASTQC(reads_ch)
TRIM_READS(reads_ch)
ALIGN(TRIM_READS.out, reference_ch.collect())
SORT_BAM(ALIGN.out)
MULTIQC(FASTQC.out.zip.mix(SORT_BAM.out.map { it[1] }).collect())
}
Terminal window
nextflow run flat_pipeline.nf -preview -with-dag dag.mmd
nf-metro render dag.mmd -o pipeline.svg --from-nextflow
Rendered map
Pipeline 1 Fastqc Trim Reads Align Sort Bam Multiqc Main created with nf-metro v2.0.0+dev

With no subworkflows, everything lands in a single section and the converter assigns one “main” line following the longest path. Output rarely comes out tidier than this.

A pipeline with three subworkflows (Preprocess, Alignment, Quantification) plus a standalone MultiQC process:

workflow PREPROCESS {
take: reads
main:
FASTQC(reads)
TRIMGALORE(reads)
emit:
reads = TRIMGALORE.out.reads
fastqc_zip = FASTQC.out.zip
trim_log = TRIMGALORE.out.log
}
workflow ALIGNMENT {
take: reads; genome; gtf
main:
STAR_GENOMEGENERATE(genome, gtf)
STAR_ALIGN(reads, STAR_GENOMEGENERATE.out.index.collect())
SAMTOOLS_SORT(STAR_ALIGN.out.bam)
SAMTOOLS_INDEX(SAMTOOLS_SORT.out.bam)
emit:
bam = SAMTOOLS_SORT.out.bam
star_log = STAR_ALIGN.out.log
}
workflow QUANTIFICATION {
take: bam; gtf
main:
SALMON_QUANT(bam, gtf)
emit:
results = SALMON_QUANT.out.results
}
workflow {
PREPROCESS(reads_ch)
ALIGNMENT(PREPROCESS.out.reads, genome_ch, gtf_ch)
QUANTIFICATION(ALIGNMENT.out.bam, gtf_ch)
MULTIQC(/* all logs */)
}
Terminal window
nextflow run with_subworkflows.nf -preview -with-dag dag.mmd
nf-metro render dag.mmd -o pipeline.svg --from-nextflow
Rendered map
Preprocess / Alignment / Quantification Pipeline 1 2 3 4 Star Genomegener Fastqc Salmon Quant Multiqc Trimgalore Star Align Samtools Sort Samtools Index Main Alignment - Reporting Preprocess - Reporting Spur created with nf-metro v2.0.0+dev

The converter maps each subworkflow to a section and creates a “Reporting” section for the standalone MultiQC. It detects bypass lines, meaning edges that skip sections such as QC metrics going from Preprocess straight to Reporting, and spur lines for dead-end processes such as Samtools Index.

Variant calling pipeline (diamond pattern)

Section titled “Variant calling pipeline (diamond pattern)”

A pipeline where two variant callers (GATK and DeepVariant) both receive input from the same alignment step and reconverge at BCFtools Stats:

workflow VARIANT_CALLING {
take: bam; bai; genome
main:
bam_bai = bam.join(bai)
GATK_HAPLOTYPECALLER(bam_bai, genome.collect())
DEEPVARIANT(bam_bai, genome.collect())
BCFTOOLS_STATS(GATK_HAPLOTYPECALLER.out.vcf.mix(DEEPVARIANT.out.vcf))
emit:
stats = BCFTOOLS_STATS.out.stats
}
workflow {
PREPROCESS(reads_ch)
ALIGNMENT(PREPROCESS.out.reads, genome_ch)
VARIANT_CALLING(ALIGNMENT.out.bam, ALIGNMENT.out.bai, genome_ch)
MULTIQC(/* all logs */)
}
Terminal window
nextflow run variant_calling.nf -preview -with-dag dag.mmd
nf-metro render dag.mmd -o pipeline.svg --from-nextflow
Rendered map
Preprocess / Alignment / Variant Calling Pipeline 1 2 3 4 Bwa Index Gatk Haplotypeca Deepvariant Fastqc Multiqc Fastp Bwa Mem Bcftools Stats Samtools Sort Samtools Index Main Preprocess - Reporting created with nf-metro v2.0.0+dev

The Variant Calling section fans out to the two callers and back in again without further editing.

For anything beyond a toy pipeline, the two-step workflow gives better results. Convert, edit the .mmd, then render:

Terminal window
nf-metro convert dag.mmd -o pipeline.mmd --title "My Pipeline"
# edit pipeline.mmd
nf-metro render pipeline.mmd -o pipeline.svg

The converter produces this for the variant calling pipeline:

%%metro title: Preprocess / Alignment / Variant Calling Pipeline
%%metro style: nfcore
%%metro line: main | Main | #2db572
%%metro line: preprocess_reporting | Preprocess - Reporting | #0570b0
graph LR
subgraph preprocess [Preprocess]
fastqc([Fastqc])
fastp([Fastp])
end
subgraph alignment [Alignment]
bwa_index([Bwa Index])
bwa_mem([Bwa Mem])
samtools_sort([Samtools Sort])
samtools_index([Samtools Index])
bwa_index -->|main| bwa_mem
bwa_mem -->|main| samtools_sort
samtools_sort -->|main| samtools_index
end
subgraph variant_calling [Variant Calling]
gatk_haplotypecaller([Gatk Haplotypeca])
deepvariant([Deepvariant])
bcftools_stats([Bcftools Stats])
gatk_haplotypecaller -->|main| bcftools_stats
deepvariant -->|main| bcftools_stats
end
subgraph reporting [Reporting]
multiqc([Multiqc])
end
%% Inter-section edges
bcftools_stats -->|main| multiqc
fastp -->|main| bwa_mem
samtools_sort -->|main| gatk_haplotypecaller
samtools_sort -->|main| deepvariant
samtools_index -->|main| gatk_haplotypecaller
samtools_index -->|main| deepvariant
fastqc -->|preprocess_reporting| multiqc
fastp -->|preprocess_reporting| multiqc

Cleaning up the labels, renaming the bypass line and adding a proper title gives this:

Mermaid source
examples/variant_calling.mmd
%%metro title: Variant Calling Pipeline
%%metro style: nfcore
%%metro line: main | Main | #2db572
%%metro line: qc | QC Reporting | #0570b0
graph LR
subgraph preprocess [Pre-processing]
fastqc[FastQC]
fastp[FastP]
end
subgraph alignment [Alignment]
bwa_index[BWA Index]
bwa_mem[BWA-MEM]
samtools_sort[SAMtools Sort]
samtools_index[SAMtools Index]
bwa_index -->|main| bwa_mem
bwa_mem -->|main| samtools_sort
samtools_sort -->|main| samtools_index
end
subgraph variant_calling [Variant Calling]
gatk[GATK HaplotypeCaller]
deepvariant[DeepVariant]
bcftools[BCFtools Stats]
gatk -->|main| bcftools
deepvariant -->|main| bcftools
end
subgraph reporting [Reporting]
multiqc[MultiQC]
end
%% Inter-section edges
fastp -->|main| bwa_mem
samtools_sort -->|main| gatk
samtools_sort -->|main| deepvariant
samtools_index -->|main| gatk
samtools_index -->|main| deepvariant
bcftools -->|main| multiqc
fastqc -->|qc| multiqc
fastp -->|qc| multiqc
Rendered map
Variant Calling Pipeline 1 2 3 4 BWA Index GATK HaplotypeCaller DeepVariant FastQC MultiQC FastP BWA-MEM BCFtools Stats SAMtools Sort SAMtools Index Main QC Reporting created with nf-metro v2.0.0+dev

The changes are small, but the diagram reads better for them: proper casing on labels (BWA-MEM, SAMtools, GATK HaplotypeCaller), a meaningful line name (“QC Reporting” rather than “Preprocess - Reporting”), and a clearer title. See the Guide for the full .mmd format reference.

Marking input and output files with document icons is one of the most useful things you can do to a Nextflow pipeline diagram. The %%metro file: directive pairs a station ID with a label, and when that station has a blank label ([ ]) it renders as a document icon instead of a pill-shaped station marker.

Starting from the hand-tuned variant calling example above, three things change:

  1. Add %%metro file: directives at the top of the file, one per file terminus:

    %%metro file: fastq_in | FASTQ
    %%metro file: ref_in | FASTA
    %%metro file: vcf_out | VCF
    %%metro file: report_out | HTML
  2. Add blank terminus stations ([ ]) at the input and output points of your pipeline. The station ID must match the %%metro file: directive:

    fastq_in[ ]
  3. Connect them to the pipeline with normal edges:

    fastq_in -->|main,qc| fastp

The full .mmd with file icons added:

Mermaid source
examples/variant_calling_tuned.mmd
%%metro title: Variant Calling Pipeline
%%metro style: nfcore
%%metro file: fastq_in | FASTQ
%%metro file: ref_in | FASTA
%%metro file: vcf_out | VCF
%%metro file: report_out | HTML
%%metro line: main | Main | #2db572
%%metro line: qc | QC Reporting | #0570b0
graph LR
subgraph preprocess [Pre-processing]
fastq_in[ ]
fastqc[FastQC]
fastp[FastP]
fastq_in -->|main,qc| fastp
fastq_in -->|qc| fastqc
end
subgraph alignment [Alignment]
ref_in[ ]
bwa_index[BWA Index]
bwa_mem[BWA-MEM]
samtools_sort[SAMtools Sort]
samtools_index[SAMtools Index]
ref_in -->|main| bwa_index
bwa_index -->|main| bwa_mem
bwa_mem -->|main| samtools_sort
samtools_sort -->|main| samtools_index
end
subgraph variant_calling [Variant Calling]
gatk[GATK HaplotypeCaller]
deepvariant[DeepVariant]
bcftools[BCFtools Stats]
vcf_out[ ]
gatk -->|main| bcftools
deepvariant -->|main| bcftools
bcftools -->|main| vcf_out
end
subgraph reporting [Reporting]
multiqc[MultiQC]
report_out[ ]
multiqc -->|qc| report_out
end
%% Inter-section edges
fastp -->|main| bwa_mem
samtools_sort -->|main| gatk
samtools_sort -->|main| deepvariant
samtools_index -->|main| gatk
samtools_index -->|main| deepvariant
bcftools -->|qc| multiqc
fastqc -->|qc| multiqc
fastp -->|qc| multiqc
Rendered map
Variant Calling Pipeline 1 2 3 4 FASTQ FASTA VCF HTML GATK HaplotypeCaller DeepVariant MultiQC BWA Index FastP BCFtools Stats FastQC BWA-MEM SAMtools Sort SAMtools Index Main QC Reporting created with nf-metro v2.0.0+dev

The FASTQ icon at the start of Pre-processing and the FASTA icon at the start of Alignment show where data enters the pipeline. The VCF icon at the end of Variant Calling and the HTML icon in Reporting show where results are written. A reader who has never seen the pipeline can now tell at a glance what goes in and what comes out.

For a more complex example with multiple file icons, see the nf-core/rnaseq diagram at examples/rnaseq_sections.mmd, which uses FASTQ input icons and HTML report output icons across several sections.

Two more icon variants cover common Nextflow patterns:

  • %%metro files: renders a stacked-documents icon for paired-end reads or multi-file inputs, as in %%metro files: reads_in | FASTQ.
  • %%metro dir: renders a folder icon for directory outputs such as publishDir results, as in %%metro dir: results_out | Results.

Add banner as a fourth field to a file: or files: directive to draw the format label on a dark strip across the icon, for when the format should stand out: %%metro files: aln_out | BAM | Alignments | banner.

Nextflow’s -with-dag output contains three types of node: processes (the pipeline steps), channels and values (data plumbing), and operators (Nextflow internals such as mix and collect). The raw DAG for the flat pipeline example looks like this:

flowchart TB
subgraph " "
v0["Channel.of"]
v1["Channel.of"]
end
v2(["FASTQC"])
v4(["TRIM_READS"])
v6(["ALIGN"])
v7(["SORT_BAM"])
v11(["MULTIQC"])
v5(( ))
v8(( ))
v0 --> v2
v0 --> v4
v1 --> v5
v4 --> v6
v5 --> v6
v6 --> v7
v7 --> v8
v2 --> v8
v8 --> v11

The converter:

  1. Drops non-process nodes. Channel nodes (v0["Channel.of"]), value nodes (v1["Channel.of"]) and operator nodes (v5(( )), v8(( ))) are removed. Only stadium-shaped process nodes such as v2(["FASTQC"]) are kept.

  2. Reconnects edges. Edges that ran through a dropped node are stitched back together, so SORT_BAM --> v8 --> MULTIQC becomes SORT_BAM --> MULTIQC and FASTQC --> v8 --> MULTIQC becomes FASTQC --> MULTIQC.

  3. Breaks cycles. nf-metro’s layout engine requires a DAG, so a process graph that loops cannot be drawn edge for edge. The converter removes a deterministic set of back edges, including any process that reaches itself. It reports every removed connection on stderr and lists them in a %% comment block at the end of the output, so a loop can be redrawn by hand rather than vanishing.

    %% Feedback removed: the process graph loops back here, and nf-metro's
    %% layout requires a DAG, so these connections were left out of the map.
    %% Each one may run through channel or operator nodes rather than being
    %% a single declared edge.
    %% polish (Polish) -> assemble (Assemble)
  4. Maps subworkflows to sections. Nextflow subworkflows become nf-metro subgraph sections. Processes that belong to no subworkflow are grouped into generated sections.

  5. Assigns metro lines. The longest path gets the “main” line. Edges that skip sections get their own bypass lines, and dead-end processes get spur lines.

  6. Cleans up labels. SCREAMING_SNAKE_CASE becomes Title Case, and long names are abbreviated.

For this example, the result is:

%%metro title: Pipeline
%%metro style: nfcore
%%metro line: main | Main | #2db572
graph LR
subgraph pipeline [Pipeline]
fastqc([Fastqc])
trim_reads([Trim Reads])
align([Align])
sort_bam([Sort Bam])
multiqc([Multiqc])
fastqc -->|main| multiqc
trim_reads -->|main| align
align -->|main| sort_bam
sort_bam -->|main| multiqc
end