Skip to content

Commit 946da0a

Browse files
pinin4fjordsclaude
andauthored
docs: nf-core Pipelines gallery page (#239)
* docs: add nf-core Pipelines page with renders for all adopted pipelines New dedicated docs page showcasing real-world nf-core/sanger-tol pipelines using nf-metro: rnaseq, epitopeprediction, hlatyping, variantprioritization, variantbenchmarking, genomeassembly, and funcprofiler. Removes pipeline-specific entries (genomeassembly, variantprioritization) from the layout gallery, keeping it focused on layout patterns. Adds funcprofiler.mmd from nf-core/funcprofiler dev branch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use explicit .md paths in cross-page links to silence mkdocs warnings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: sync rnaseq and hlatyping examples with upstream repos Update rnaseq_auto.mmd from nf-core/rnaseq master (adds bowtie2_salmon line, ribodetector, tximport/SummarizedExperiment, file icons, explicit port directives, and section directions). Update hlatyping.mmd from nf-core/hlatyping dev (different hidden station routing with merge junction pattern, updated logo path). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add funcprofiler upstream and simplified variants, debug renders Add funcprofiler_upstream.mmd (original 11-line topology from nf-core) and simplified funcprofiler.mmd (3-line version). Both rendered on the pipelines page. Pipeline renders use debug mode for ongoing review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Split out funcprofiler + rnaseq_auto fixture changes These need engine-side follow-up work: - funcprofiler.mmd: profiling->reporting trunk-Y kink, qc-crosses-merge - funcprofiler_upstream.mmd: humann3 junction nearly horizontal - rnaseq_auto.mmd (expanded): hisat2/bowtie2 stacking under y_spacing threshold, ascend-vs-descend z-order mismatch around bbsplit/sortmerna/ribodetector fan Moved to PR #337. Restored examples/rnaseq_auto.mmd to main's version so this PR (docs gallery + hlatyping logo path + gallery script infrastructure) lands without an engine block. * Regenerate docs/pipelines/index.md from build_gallery.py The PR initially committed a hand-edited version of the file; CI's render-diff job runs the gallery script, which rewrites the file from its PIPELINE_ENTRIES list, and the resulting diff blocked the base branch checkout step. Committing the script's output verbatim so the file matches what CI regenerates and the workflow's base-branch checkout can proceed. * chore: stop committing build_gallery.py-generated docs/pipelines/index.md The file is regenerated from PIPELINE_ENTRIES by scripts/build_gallery.py on every invocation, including the docs build in CI. Committing it kept us tied to a stale snapshot that diverged from the script's output and broke the render-diff workflow's base-branch checkout step. Add to .gitignore alongside docs/gallery/index.md (which has always been generated and never committed). CI and the mkdocs site builder will regenerate the file from the script on demand. * Remove funcprofiler fixtures (resurrected by accident; they live in #337) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1713dd5 commit 946da0a

4 files changed

Lines changed: 127 additions & 37 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ build/
1010
site/
1111
docs/gallery/
1212
docs/assets/renders/
13+
14+
# Generated by scripts/build_gallery.py
15+
docs/pipelines/index.md
16+
docs/gallery/index.md

examples/hlatyping.mmd

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
%%metro title: nf-core/hlatyping
22
%%metro style: dark
3-
%%metro logo: examples/nf-core-hlatyping_logo_dark.png
3+
%%metro logo: docs/images/nf-core-hlatyping_logo_dark.png
44
%%metro file: fastq_in | FASTQ
55
%%metro file: bam_in | BAM
66
%%metro file: report_tsv | TSV
77
%%metro file: report_html | HTML
88
%%metro line: fastq | FASTQ | #2db572
99
%%metro line: bam | BAM | #e6842a
1010
%%metro legend: bl
11-
%%metro legend_min_height: 72
1211

1312
graph LR
1413
subgraph preprocessing [Pre-processing]
1514
%%metro exit: right | fastq, bam
1615
fastq_in[ ]
1716
bam_in[ ]
1817
cat_fastq[cat FASTQ]
18+
_fastq_delay[ ]
1919
check_paired[Check Paired]
2020
collatefastq[BAM to FASTQ]
2121
fastqc[FastQC]
2222

2323
fastq_in -->|fastq| cat_fastq
24-
cat_fastq -->|fastq| fastqc
24+
cat_fastq -->|fastq| _fastq_delay
25+
_fastq_delay -->|fastq| fastqc
2526
bam_in -->|bam| check_paired
2627
check_paired -->|bam| collatefastq
2728
collatefastq -->|bam| fastqc
@@ -35,28 +36,28 @@ graph LR
3536
optitype_run[OptiType]
3637
_hlahd_delay[ ]
3738
hlahd_run[HLA-HD]
39+
_hlahd_delay2[ ]
40+
_merge1[ ]
3841

3942
yara_index -->|fastq,bam| yara_mapper
4043
yara_mapper -->|fastq,bam| optitype_run
44+
optitype_run -->|fastq,bam| _merge1
4145
_hlahd_delay -->|fastq,bam| hlahd_run
46+
hlahd_run -->|fastq,bam| _hlahd_delay2
47+
_hlahd_delay2 -->|fastq,bam| _merge1
4248
end
4349

4450
subgraph reporting [Reporting]
4551
%%metro entry: left | fastq, bam
46-
_branch2[ ]
47-
_tsv_delay[ ]
4852
report_tsv[ ]
4953
multiqc[MultiQC]
5054
report_html[ ]
5155

52-
_branch2 -->|fastq,bam| _tsv_delay
53-
_tsv_delay -->|fastq,bam| report_tsv
54-
_branch2 -->|fastq,bam| multiqc
5556
multiqc -->|fastq,bam| report_html
5657
end
5758

5859
%% Inter-section edges
5960
fastqc -->|fastq,bam| yara_index
6061
fastqc -->|fastq,bam| _hlahd_delay
61-
optitype_run -->|fastq,bam| _branch2
62-
hlahd_run -->|fastq,bam| _branch2
62+
_merge1 -->|fastq,bam| report_tsv
63+
_merge1 -->|fastq,bam| multiqc

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ nav:
4040
- Home: index.md
4141
- Guide: guide.md
4242
- Nextflow Import: nextflow.md
43+
- nf-core Pipelines: pipelines/index.md
4344
- Gallery: gallery/index.md

scripts/build_gallery.py

Lines changed: 111 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
TOPOLOGIES_DIR = project_root / "examples" / "topologies"
3131
GUIDE_DIR = project_root / "examples" / "guide"
3232
GALLERY_DIR = project_root / "docs" / "gallery"
33+
PIPELINES_DIR = project_root / "docs" / "pipelines"
3334
RENDERS_DIR = project_root / "docs" / "assets" / "renders"
3435

3536
# Ordered list of examples. Each entry is (filename_stem, source_dir, description).
@@ -44,22 +45,14 @@
4445
(
4546
"rnaseq_auto",
4647
EXAMPLES_DIR,
47-
"nf-core/rnaseq with fully auto-inferred layout.",
48+
"Demonstrates fully auto-inferred layout: no `%%metro grid:` directives "
49+
"needed. See [nf-core Pipelines](../pipelines/index.md) for the full gallery.",
4850
),
4951
(
5052
"rnaseq_sections",
5153
EXAMPLES_DIR,
52-
"nf-core/rnaseq with manual grid overrides and file markers.",
53-
),
54-
(
55-
"genomeassembly",
56-
EXAMPLES_DIR,
57-
"sanger-tol/genomeassembly with fan-out/fan-in across optional stages.",
58-
),
59-
(
60-
"variantprioritization",
61-
EXAMPLES_DIR,
62-
"nf-core/variantprioritization with cross-row bypass routing.",
54+
"Same pipeline with manual `%%metro grid:` overrides and file markers, "
55+
"showing how explicit directives can fine-tune placement.",
6356
),
6457
(
6558
"differentialabundance",
@@ -177,19 +170,66 @@
177170
}
178171

179172

173+
# Ordered list of nf-core pipeline examples.
174+
# Each entry is (filename_stem, display_name, repo_url, description).
175+
PIPELINE_ENTRIES: list[tuple[str, str, str, str]] = [
176+
(
177+
"rnaseq_auto",
178+
"nf-core/rnaseq",
179+
"https://github.com/nf-core/rnaseq",
180+
"RNA-seq analysis with multiple aligner and quantification routes "
181+
"(STAR/RSEM, STAR/Salmon, HISAT2, Salmon pseudo-alignment, Kallisto).",
182+
),
183+
(
184+
"epitopeprediction",
185+
"nf-core/epitopeprediction",
186+
"https://github.com/nf-core/epitopeprediction",
187+
"MHC binding prediction from VCF, protein FASTA, or peptide TSV inputs "
188+
"through five prediction tools.",
189+
),
190+
(
191+
"hlatyping",
192+
"nf-core/hlatyping",
193+
"https://github.com/nf-core/hlatyping",
194+
"HLA typing from FASTQ or BAM inputs via OptiType and HLA-HD.",
195+
),
196+
(
197+
"variantprioritization",
198+
"nf-core/variantprioritization",
199+
"https://github.com/nf-core/variantprioritization",
200+
"Somatic and germline variant prioritization using PCGR and CPSR.",
201+
),
202+
(
203+
"variantbenchmarking",
204+
"nf-core/variantbenchmarking",
205+
"https://github.com/nf-core/variantbenchmarking",
206+
"Benchmarking of variant callers against truth sets with "
207+
"Truvari, hap.py, RTGtools, and more.",
208+
),
209+
(
210+
"genomeassembly",
211+
"sanger-tol/genomeassembly",
212+
"https://github.com/sanger-tol/genomeassembly",
213+
"Genome assembly from long reads and Hi-C data through "
214+
"purging, polishing, scaffolding, and QC.",
215+
),
216+
]
217+
180218
# Manifest mapping SVG filename -> section for the render diff page.
181219
# Populated by each render function, written to RENDERS_DIR/manifest.json.
182220
_manifest: dict[str, str] = {}
183221

184222

185-
def render_mmd(mmd_path: Path, svg_path: Path) -> None:
223+
def render_mmd(
224+
mmd_path: Path, svg_path: Path, *, debug: bool = DEBUG_RENDERS
225+
) -> None:
186226
"""Parse, layout, and render a .mmd file to SVG."""
187227
text = mmd_path.read_text()
188228
graph = parse_metro_mermaid(text)
189229
compute_layout(graph)
190230
theme_name = graph.style if graph.style in THEMES else "nfcore"
191231
theme = THEMES[theme_name]
192-
svg_str = render_svg(graph, theme, debug=DEBUG_RENDERS)
232+
svg_str = render_svg(graph, theme, debug=debug)
193233
svg_path.write_text(svg_str)
194234

195235

@@ -360,28 +400,72 @@ def render_nextflow_examples() -> None:
360400
print()
361401

362402

363-
def render_pipeline_examples() -> None:
364-
"""Render pipeline examples not covered by the gallery or guide."""
403+
def build_pipelines_page() -> None:
404+
"""Generate docs/pipelines/index.md and render pipeline SVGs."""
405+
PIPELINES_DIR.mkdir(parents=True, exist_ok=True)
365406
RENDERS_DIR.mkdir(parents=True, exist_ok=True)
366-
section = "Pipeline Examples"
367-
print("Pipeline examples:")
368-
for stem in (
369-
"epitopeprediction",
370-
"hlatyping",
371-
"rnaseq_sections_manual",
372-
"variantprioritization",
373-
):
407+
section = "nf-core Pipelines"
408+
print("nf-core pipelines:")
409+
410+
lines: list[str] = [
411+
"# nf-core Pipelines",
412+
"",
413+
"Real-world pipelines rendered with nf-metro. These are maintained as "
414+
"`.mmd` files alongside the pipeline source code and rendered automatically.",
415+
"",
416+
"See the [Gallery](../gallery/index.md) for layout pattern examples and the "
417+
"[Guide](../guide.md) for how to write your own.",
418+
"",
419+
]
420+
421+
for stem, display_name, repo_url, description in PIPELINE_ENTRIES:
422+
mmd_path = EXAMPLES_DIR / f"{stem}.mmd"
423+
svg_path = RENDERS_DIR / f"pipeline_{stem}.svg"
424+
425+
if not mmd_path.exists():
426+
print(f" WARNING: {mmd_path} not found, skipping")
427+
continue
428+
429+
try:
430+
render_mmd(mmd_path, svg_path, debug=True)
431+
status = "OK"
432+
except Exception as e:
433+
status = f"FAIL: {e}"
434+
print(f" {stem}: {status}")
435+
continue
436+
437+
_manifest[svg_path.name] = section
438+
print(f" {stem}: {status}")
439+
440+
mmd_source = mmd_path.read_text()
441+
442+
lines.append(f"## [{display_name}]({repo_url})\n")
443+
lines.append(f"{description}\n")
444+
lines.append(f"![{display_name}](../assets/renders/pipeline_{stem}.svg)\n")
445+
lines.append('??? note "Mermaid source"\n')
446+
lines.append(" ```text")
447+
for src_line in mmd_source.rstrip().split("\n"):
448+
lines.append(f" {src_line}")
449+
lines.append(" ```\n")
450+
451+
pipelines_md = "\n".join(lines)
452+
pipelines_path = PIPELINES_DIR / "index.md"
453+
pipelines_path.write_text(pipelines_md)
454+
print(f"\nPipelines page written to {pipelines_path}")
455+
print()
456+
457+
# Also render rnaseq_sections_manual for the guide (not on pipelines page)
458+
for stem in ("rnaseq_sections_manual",):
374459
mmd_path = EXAMPLES_DIR / f"{stem}.mmd"
375460
if not mmd_path.exists():
376461
continue
377462
svg_path = RENDERS_DIR / f"{stem}.svg"
378463
try:
379464
render_mmd(mmd_path, svg_path)
380-
_manifest[svg_path.name] = section
465+
_manifest[svg_path.name] = "Guide Examples"
381466
print(f" {stem}: OK")
382467
except Exception as e:
383468
print(f" {stem}: FAIL - {e}")
384-
print()
385469

386470

387471
def render_test_fixtures() -> None:
@@ -417,7 +501,7 @@ def write_manifest() -> None:
417501
old_svg.unlink()
418502
render_guide_examples()
419503
render_nextflow_examples()
420-
render_pipeline_examples()
504+
build_pipelines_page()
421505
render_test_fixtures()
422506
build_gallery()
423507
write_manifest()

0 commit comments

Comments
 (0)