From 7a89066daea83bddcde3b4e56038690025e231a1 Mon Sep 17 00:00:00 2001 From: "Nico DV + Codex 5.4" Date: Fri, 21 Aug 2026 21:21:54 +0200 Subject: [PATCH 1/3] Sort peak QC plot inputs deterministically `collect` emits in task-completion order, and plot_macs3_qc.r / plot_homer_annotatepeaks.r derive sample ids from the order of the file list they are handed. In plot_homer_annotatepeaks.r the summary column order follows the `feature` factor levels, which accumulate by first appearance across the input files, so a reshuffle changes the md5 of macs3_annotatePeaks.*.summary.txt, its _mqc.tsv, and the MultiQC peak annotation plot table. Observed as an intermittent snapshot mismatch in tests/skip_trimming.nf.test on nf-core/atacseq#453. Co-Authored-By: Claude Opus 5 (1M context) --- .../local/bam_peaks_call_qc_annotate_macs3_homer.nf | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf b/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf index d7224280..318185cb 100644 --- a/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf +++ b/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf @@ -107,8 +107,12 @@ workflow BAM_PEAKS_CALL_QC_ANNOTATE_MACS3_HOMER { // // MACS3 QC plots with R // + // Sort by file name: the R scripts derive sample ids from the order of + // the file list, and `collect` emits in task-completion order. PLOT_MACS3_QC ( - ch_macs3_peaks.collect { item -> item[1] }, + ch_macs3_peaks + .map { item -> item[1] } + .toSortedList { a, b -> a.name <=> b.name }, is_narrow_peak ) ch_plot_macs3_qc_txt = PLOT_MACS3_QC.out.txt @@ -119,7 +123,9 @@ workflow BAM_PEAKS_CALL_QC_ANNOTATE_MACS3_HOMER { // Peak annotation QC plots with R // PLOT_HOMER_ANNOTATEPEAKS ( - HOMER_ANNOTATEPEAKS.out.txt.collect { item -> item[1] }, + HOMER_ANNOTATEPEAKS.out.txt + .map { item -> item[1] } + .toSortedList { a, b -> a.name <=> b.name }, ch_peak_annotation_header_multiqc, annotate_peaks_suffix ) From f5a1bca1e7bbeb1bf0adda4df9e82cef3c4a84e2 Mon Sep 17 00:00:00 2001 From: "Nico DV + Codex 5.4" Date: Fri, 21 Aug 2026 21:23:40 +0200 Subject: [PATCH 2/3] Add CHANGELOG entry for #454 Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef758c83..2312802c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [[#438](https://github.com/nf-core/atacseq/issues/438)] - Add `checkIfExists` to file inputs in `PREPARE_GENOME` and prevent S3 access errors during index validation. - [[PR #443](https://github.com/nf-core/atacseq/pull/443)] - Updated pipeline template to [nf-core/tools 4.0.2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [[PR #453](https://github.com/nf-core/atacseq/pull/453)] - Updated pipeline template to [nf-core/tools 4.0.3](https://github.com/nf-core/tools/releases/tag/4.0.3) +- [[PR #454](https://github.com/nf-core/atacseq/pull/454)] - Sort the peak QC plot inputs by file name so that `PLOT_MACS3_QC` and `PLOT_HOMER_ANNOTATEPEAKS` outputs no longer depend on task completion order. ### Parameters From b8039ebb96bedc978fdedaf5be05e84e974dd79c Mon Sep 17 00:00:00 2001 From: "Nico DV + Codex 5.4" Date: Fri, 21 Aug 2026 21:50:03 +0200 Subject: [PATCH 3/3] Sort the plot inputs inside the modules instead of the channel `toSortedList` emits an empty list when its source channel is empty, whereas `collect` emits nothing at all, so the previous version started PLOT_MACS3_QC with no files when no merged-replicate peaks exist and plot_macs3_qc.r died on `flag "i" requires an argument`. Seen in the `bowtie2 with stub` test. Sort the staged file list in the process script instead, which leaves the channel semantics untouched. Co-Authored-By: Claude Opus 5 (1M context) --- modules/local/plot_homer_annotatepeaks.nf | 6 ++++-- modules/local/plot_macs3_qc.nf | 6 ++++-- .../local/bam_peaks_call_qc_annotate_macs3_homer.nf | 10 ++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/local/plot_homer_annotatepeaks.nf b/modules/local/plot_homer_annotatepeaks.nf index ef4b1ce6..6b2833a6 100644 --- a/modules/local/plot_homer_annotatepeaks.nf +++ b/modules/local/plot_homer_annotatepeaks.nf @@ -23,10 +23,12 @@ process PLOT_HOMER_ANNOTATEPEAKS { script: // This script is bundled with the pipeline, in nf-core/chipseq/bin/ def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "annotatepeaks" + // Files arrive in task-completion order; sort so sample order in the outputs is reproducible. + def anno_list = annos.toSorted { anno -> anno.name }.join(',') """ plot_homer_annotatepeaks.r \\ - -i ${annos.join(',')} \\ - -s ${annos.join(',').replaceAll("${suffix}","")} \\ + -i ${anno_list} \\ + -s ${anno_list.replaceAll("${suffix}","")} \\ -p $prefix \\ $args diff --git a/modules/local/plot_macs3_qc.nf b/modules/local/plot_macs3_qc.nf index 9ce2edfe..7cf371c2 100644 --- a/modules/local/plot_macs3_qc.nf +++ b/modules/local/plot_macs3_qc.nf @@ -21,10 +21,12 @@ process PLOT_MACS3_QC { script: // This script is bundled with the pipeline, in nf-core/atacseq/bin/ def args = task.ext.args ?: '' def peak_type = is_narrow_peak ? 'narrowPeak' : 'broadPeak' + // Files arrive in task-completion order; sort so sample order in the outputs is reproducible. + def peak_list = peaks.toSorted { peak -> peak.name }.join(',') """ plot_macs3_qc.r \\ - -i ${peaks.join(',')} \\ - -s ${peaks.join(',').replaceAll("_peaks.${peak_type}","")} \\ + -i ${peak_list} \\ + -s ${peak_list.replaceAll("_peaks.${peak_type}","")} \\ $args cat <<-END_VERSIONS > versions.yml diff --git a/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf b/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf index 318185cb..d7224280 100644 --- a/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf +++ b/subworkflows/local/bam_peaks_call_qc_annotate_macs3_homer.nf @@ -107,12 +107,8 @@ workflow BAM_PEAKS_CALL_QC_ANNOTATE_MACS3_HOMER { // // MACS3 QC plots with R // - // Sort by file name: the R scripts derive sample ids from the order of - // the file list, and `collect` emits in task-completion order. PLOT_MACS3_QC ( - ch_macs3_peaks - .map { item -> item[1] } - .toSortedList { a, b -> a.name <=> b.name }, + ch_macs3_peaks.collect { item -> item[1] }, is_narrow_peak ) ch_plot_macs3_qc_txt = PLOT_MACS3_QC.out.txt @@ -123,9 +119,7 @@ workflow BAM_PEAKS_CALL_QC_ANNOTATE_MACS3_HOMER { // Peak annotation QC plots with R // PLOT_HOMER_ANNOTATEPEAKS ( - HOMER_ANNOTATEPEAKS.out.txt - .map { item -> item[1] } - .toSortedList { a, b -> a.name <=> b.name }, + HOMER_ANNOTATEPEAKS.out.txt.collect { item -> item[1] }, ch_peak_annotation_header_multiqc, annotate_peaks_suffix )