From 020d5552196a445e38f6d1b4ebdd70fae1646ae9 Mon Sep 17 00:00:00 2001 From: Neil Horner Date: Fri, 22 May 2026 17:05:56 +0000 Subject: [PATCH] Add the missing annotation ref summary [CW-7271] --- bin/workflow_glue/report.py | 28 +++++++++++-------- bin/workflow_glue/tests/common/test_report.py | 26 +++++++++++++++++ .../tests/common/test_report_qc.py | 8 ++++-- main.nf | 3 ++ 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/bin/workflow_glue/report.py b/bin/workflow_glue/report.py index 0e86613..32ce8f1 100644 --- a/bin/workflow_glue/report.py +++ b/bin/workflow_glue/report.py @@ -220,6 +220,17 @@ def _load_bambu_qc(bambu_dir): return None +def _load_annotation_reference_summary(summary_file): + """Load reference/annotation preparation summary JSON from a file path.""" + if summary_file is None: + return None + summary_path = Path(summary_file) + if summary_path.exists(): + with open(summary_path) as f: + return json.load(f) + return None + + def _load_de_qc(de_dir): """Load DE/DTU QC statistics JSON.""" qc_file = Path(de_dir) / "de_qc_stats.json" @@ -229,15 +240,6 @@ def _load_de_qc(de_dir): return None -def _load_annotation_reference_summary(cohort_dir): - """Load reference/annotation preparation summary JSON.""" - summary_file = Path(cohort_dir) / "reference" / "annotation_reference_summary.json" - if summary_file.exists(): - with open(summary_file) as f: - return json.load(f) - return None - - def _load_cpm_tables(cohort_dir): """Load cohort-level gene and transcript CPM tables.""" cohort_dir = Path(cohort_dir) @@ -478,8 +480,7 @@ def main(args): .rename(columns={"index": "Field"}), use_index=False, ) - - annotation_reference_summary = _load_annotation_reference_summary(args.cohort_dir) + annotation_reference_summary = _load_annotation_reference_summary(args.ref_summary) if annotation_reference_summary: with report.add_section("Reference and Annotation Checks", "Reference"): @@ -1210,6 +1211,11 @@ def argparser(): default=None, help="Differential analysis directory.", ) + parser.add_argument( + "--ref_summary", + default=None, + help="Annotation reference summary TSV.", + ) parser.add_argument("--versions", required=True, help="Versions directory.") parser.add_argument("--params", required=True, help="Workflow params JSON.") parser.add_argument( diff --git a/bin/workflow_glue/tests/common/test_report.py b/bin/workflow_glue/tests/common/test_report.py index ab5a5c9..77a5e76 100644 --- a/bin/workflow_glue/tests/common/test_report.py +++ b/bin/workflow_glue/tests/common/test_report.py @@ -145,6 +145,8 @@ def _build_report_args(tmp_path, de_qc=None): str(alignment_stats), "--cohort_dir", str(cohort), + "--ref_summary", + str(reference / "annotation_reference_summary.json"), "--samples_dir", str(samples), "--sqanti_dir", @@ -229,6 +231,8 @@ def test_report_main_accepts_optional_file_sentinels(monkeypatch, tmp_path): str(alignment_stats), "--cohort_dir", str(cohort), + "--ref_summary", + str(cohort / "reference" / "annotation_reference_summary.json"), "--samples_dir", str(samples), "--sqanti_dir", @@ -351,6 +355,8 @@ def test_report_main_handles_degenerate_bambu_qc_and_read_summary( str(alignment_stats), "--cohort_dir", str(cohort), + "--ref_summary", + str(cohort / "reference" / "annotation_reference_summary.json"), "--samples_dir", str(samples), "--sqanti_dir", @@ -411,6 +417,24 @@ def test_report_main_uses_cohort_bambu_qc_for_multi_sample_inputs( cohort = tmp_path / "cohort" cohort.mkdir() + reference = cohort / "reference" + reference.mkdir() + _write( + reference / "annotation_reference_summary.json", + json.dumps( + { + "seqname_overlap": ["chr1"], + "only_in_annotation": [], + "only_in_reference": [], + "annotation": { + "kept_records": 10, + "excluded_unstranded_records": 0, + "sanitised_attribute_records": 0, + }, + "warnings": [], + } + ), + ) _write( cohort / "bambu_qc_stats.json", json.dumps( @@ -478,6 +502,8 @@ def test_report_main_uses_cohort_bambu_qc_for_multi_sample_inputs( str(alignment_stats), "--cohort_dir", str(cohort), + "--ref_summary", + str(cohort / "reference" / "annotation_reference_summary.json"), "--samples_dir", str(samples), "--sqanti_dir", diff --git a/bin/workflow_glue/tests/common/test_report_qc.py b/bin/workflow_glue/tests/common/test_report_qc.py index ca5b876..e414deb 100644 --- a/bin/workflow_glue/tests/common/test_report_qc.py +++ b/bin/workflow_glue/tests/common/test_report_qc.py @@ -93,7 +93,9 @@ def test_load_annotation_reference_summary_exists(tmp_path): with open(summary_dir / "annotation_reference_summary.json", "w") as f: json.dump(summary_data, f) - result = _load_annotation_reference_summary(tmp_path / "cohort") + result = _load_annotation_reference_summary( + summary_dir / "annotation_reference_summary.json" + ) assert result is not None assert result["seqname_overlap"] == ["chr1"] assert result["only_in_annotation"] == ["chrMissing"] @@ -106,7 +108,9 @@ def test_load_annotation_reference_summary_missing(tmp_path): cohort_dir = tmp_path / "cohort" cohort_dir.mkdir() - result = _load_annotation_reference_summary(cohort_dir) + result = _load_annotation_reference_summary( + cohort_dir / "reference" / "annotation_reference_summary.json" + ) assert result is None diff --git a/main.nf b/main.nf index 88053f9..908cdb4 100644 --- a/main.nf +++ b/main.nf @@ -43,6 +43,7 @@ process makeReport { path sample_dirs, stageAs: "samples/*" path sqanti_dirs, stageAs: "sqanti/*" path de_files + path "annotation_reference_summary.tsv" val wf_version output: path "wf-transcriptomes-report.html", emit: report @@ -63,6 +64,7 @@ process makeReport { ${de_args} \ --versions versions \ --params params.json \ + --ref_summary annotation_reference_summary.tsv \ --wf_version ${wf_version} """ } @@ -202,6 +204,7 @@ workflow pipeline { sample_dirs_for_report, sqanti_dirs_for_report, de_dir, + transcriptome.annotation_reference_summary, workflow.manifest.version )