From c85de41b6b705668a0354c79f5313eda94c20c79 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Fri, 19 Dec 2025 14:41:44 +0000 Subject: [PATCH 1/2] feat(ribowaltz): Export underlying data from QC plots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add TSV export for data underlying P-site region and frame distribution plots. This makes the raw data available for downstream analysis and reporting tools like MultiQC. Changes: - Export psite_region.tsv from region_psite() in save_psite_region_plot - Export frames.tsv from frame_psite() in save_frame_plots - Export frames_stratified.tsv from frame_psite_length() in save_frame_plots - Add ribowaltz_qc_data output channel for TSV files - Update stub outputs to include new TSV files - Add test assertions for new output channel 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- modules/nf-core/ribowaltz/main.nf | 4 ++++ modules/nf-core/ribowaltz/templates/ribowaltz.r | 15 +++++++++++++++ modules/nf-core/ribowaltz/tests/main.nf.test | 2 ++ 3 files changed, 21 insertions(+) diff --git a/modules/nf-core/ribowaltz/main.nf b/modules/nf-core/ribowaltz/main.nf index e672c794c0bc..075d04786cbe 100644 --- a/modules/nf-core/ribowaltz/main.nf +++ b/modules/nf-core/ribowaltz/main.nf @@ -22,6 +22,7 @@ process RIBOWALTZ { tuple val(meta), path("*.cds_coverage_psite.tsv{,.gz}") , emit: cds_coverage , optional: true tuple val(meta), path("*nt_coverage_psite.tsv{,.gz}") , emit: cds_window_coverage , optional: true tuple val(meta), path("ribowaltz_qc/*.pdf") , emit: ribowaltz_qc , optional: true + tuple val(meta), path("ribowaltz_qc/*.tsv") , emit: ribowaltz_qc_data , optional: true path "versions.yml" , emit: versions when: @@ -41,6 +42,9 @@ process RIBOWALTZ { touch ${prefix}.cds_coverage_psite.tsv mkdir -p offset_plot/${prefix} && touch offset_plot/${prefix}/29.pdf mkdir -p ribowaltz_qc && touch ribowaltz_qc/${prefix}.metaprofile_psite.pdf + touch ribowaltz_qc/${prefix}.psite_region.tsv + touch ribowaltz_qc/${prefix}.frames.tsv + touch ribowaltz_qc/${prefix}.frames_stratified.tsv cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/ribowaltz/templates/ribowaltz.r b/modules/nf-core/ribowaltz/templates/ribowaltz.r index c13c987fff08..665d499f26d2 100644 --- a/modules/nf-core/ribowaltz/templates/ribowaltz.r +++ b/modules/nf-core/ribowaltz/templates/ribowaltz.r @@ -294,6 +294,11 @@ save_psite_region_plot <- function(sample_name, dt.ls, annotation.df) { ggplot2::ggsave(paste0(getwd(), "/ribowaltz_qc/", sample_name, ".psite_region.pdf"), psite_region.gg, dpi = 400, width = 10) + # Export underlying data + region_dt <- psite_region[["count_dt"]] + if (!is.null(region_dt)) { + data.table::fwrite(region_dt, paste0(getwd(), "/ribowaltz_qc/", sample_name, ".psite_region.tsv"), sep = "\t") + } } #' Save Frame Plots @@ -329,12 +334,22 @@ save_frame_plots <- function(sample_name, dt.ls, annotation.df, min_length, max_ ggplot2::ggsave(paste0(getwd(), "/ribowaltz_qc/", sample_name, ".frames_stratified.pdf"), frames_stratified.gg, dpi = 600, height = 9 , width = 12) + # Export underlying data for stratified frames + frames_stratified_dt <- frames_stratified[["count_dt"]] + if (!is.null(frames_stratified_dt)) { + data.table::fwrite(frames_stratified_dt, paste0(getwd(), "/ribowaltz_qc/", sample_name, ".frames_stratified.tsv"), sep = "\t") + } frames <- riboWaltz::frame_psite(dt.ls, region = "all", length_range = min_length:max_length, sample = sample_name, annotation = annotation.df, colour = "grey70") frames.gg <- frames[[paste0("plot_", sample_name)]] ggplot2::ggsave(paste0(getwd(), "/ribowaltz_qc/", sample_name, ".frames.pdf"), frames.gg, dpi = 600, height = 9 , width = 9) + # Export underlying data for aggregated frames + frames_dt <- frames[["count_dt"]] + if (!is.null(frames_dt)) { + data.table::fwrite(frames_dt, paste0(getwd(), "/ribowaltz_qc/", sample_name, ".frames.tsv"), sep = "\t") + } } diff --git a/modules/nf-core/ribowaltz/tests/main.nf.test b/modules/nf-core/ribowaltz/tests/main.nf.test index ace571ca6e61..abd7c77534fe 100644 --- a/modules/nf-core/ribowaltz/tests/main.nf.test +++ b/modules/nf-core/ribowaltz/tests/main.nf.test @@ -36,6 +36,7 @@ nextflow_process { { assert snapshot(process.out.cds_coverage).match('cds_coverage') }, { assert snapshot(process.out.cds_window_coverage).match('cds_window_coverage') }, { assert snapshot(process.out.ribowaltz_qc.size() == 8) }, + { assert snapshot(process.out.ribowaltz_qc_data.size() == 3) }, { assert snapshot(process.out.versions).match('versions') } ) } @@ -69,6 +70,7 @@ nextflow_process { { assert snapshot(process.out.codon_coverage_psite).match('codon_coverage_psite_stub') }, { assert snapshot(process.out.cds_coverage).match('cds_coverage_stub') }, { assert snapshot(process.out.ribowaltz_qc.size() == 1) }, + { assert snapshot(process.out.ribowaltz_qc_data.size() == 3) }, { assert snapshot(process.out.versions).match('versions_stub') } ) } From f6d169488b9cad00ef6d878392781e1dbef41a42 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Fri, 19 Dec 2025 14:55:47 +0000 Subject: [PATCH 2/2] chore(ribowaltz): Update meta.yml with ribowaltz_qc_data output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- modules/nf-core/ribowaltz/meta.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/nf-core/ribowaltz/meta.yml b/modules/nf-core/ribowaltz/meta.yml index 14f85abdcf00..e0098e2b5d92 100644 --- a/modules/nf-core/ribowaltz/meta.yml +++ b/modules/nf-core/ribowaltz/meta.yml @@ -164,6 +164,19 @@ output: description: riboWaltz diagnostic plots (optional) pattern: "ribowaltz_qc/*" ontologies: [] + ribowaltz_qc_data: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - ribowaltz_qc/*.tsv: + type: file + description: TSV files containing data underlying riboWaltz QC plots including + P-site region distribution, frame distribution, and frame distribution + stratified by read length (optional) + pattern: "ribowaltz_qc/*.tsv" + ontologies: [] versions: - versions.yml: type: file