Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [[5.1.0dev]($tag_url)] - $date

### Patches

#### Enhancements & fixes

- Pass the collated software versions to the experiment summary report. By @Aratz [#248](https://github.com/nf-core/pixelator/pull/248)

## [[5.0.1](https://github.com/nf-core/pixelator/releases/tag/5.0.1)] - 2026-08-17

### Patches
Expand Down
9 changes: 8 additions & 1 deletion modules/local/experiment_summary/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ process EXPERIMENT_SUMMARY {
input:
path samplesheet_path
tuple val(meta), val(result_stages), path(results_data, arity: "1..*", stageAs: "results_raw/?/*")
path versions_yml, stageAs: 'software_versions.yml'

output:
tuple val(meta), path("*experiment-summary.html") , emit: html
tuple val("${task.process}"), val('experiment-summary'), eval("Rscript -e 'cat(as.character(packageVersion(\"pixelatorES\")), \"\\n\")'"), emit: versions_experiment_summary, topic: versions
// This process must not push its version to the `versions` topic. It consumes a file
// collated from that topic, and a topic only closes once all of its publishers have
// finished, so publishing to it would hang the pipeline forever.
// This mimics how MultiQC handles version reporting.
tuple val("${task.process}"), val('experiment-summary'), eval("Rscript -e 'cat(as.character(packageVersion(\"pixelatorES\")), \"\\n\")'"), emit: versions_experiment_summary

script:
def args = task.ext.args ?: ''
Expand All @@ -28,6 +33,8 @@ process EXPERIMENT_SUMMARY {
cp -r /workspace/inst/quarto/ ./quarto/
mkdir -p results

cp software_versions.yml results/software_versions.yml

# Stage each result file into results/<stage>/. Files are staged into
# results_raw/1, results_raw/2, ... in the same order as the stage names.
stages=(${stageArray})
Expand Down
16 changes: 5 additions & 11 deletions modules/local/experiment_summary/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ input:
type: file
description: Result files to organize under stage folders in the report input.
ontologies: []
- - versions_yml:
type: file
description: Collated software versions, copied into the report data folder.
pattern: "*.{yml,yaml}"
ontologies: []
output:
html:
- - meta:
Expand All @@ -51,17 +56,6 @@ output:
- Rscript -e 'cat(as.character(packageVersion("pixelatorES")), "\n")':
type: eval
description: The expression used to obtain the tool version.
topics:
versions:
- - ${task.process}:
type: string
description: The process the versions were collected from.
- experiment-summary:
type: string
description: The tool name.
- Rscript -e 'cat(as.character(packageVersion("pixelatorES")), "\n")':
type: eval
description: The expression used to obtain the tool version.
authors:
- "@Aratz"
- "@johandahlberg"
Expand Down
14 changes: 14 additions & 0 deletions modules/local/experiment_summary/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ nextflow_process {
file(params.pipelines_testdata_base_path + 'new-test-data/pna/modules/amplicon/pool1.report.json', checkIfExists: true),
]
]
input[2] = channel.of(
'PIXELATOR_AMPLICON:',
' pixelator: 0.30.0',
'Workflow:',
' nf-core/pixelator: 5.1.0dev',
' Nextflow: 25.10.4',
).collectFile(name: 'software_versions.yml', newLine: true)
"""
}
}
Expand Down Expand Up @@ -130,6 +137,13 @@ nextflow_process {
file(params.pipelines_testdata_base_path + 'new-test-data/pna/modules/sample_calling/sample4.report.json', checkIfExists: true),
]
]
input[2] = channel.of(
'PIXELATOR_AMPLICON:',
' pixelator: 0.30.0',
'Workflow:',
' nf-core/pixelator: 5.1.0dev',
' Nextflow: 25.10.4',
).collectFile(name: 'software_versions.yml', newLine: true)
"""
}
}
Expand Down
40 changes: 23 additions & 17 deletions subworkflows/local/pna/v1/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ include { PIXELATOR_DENOISE } from '../../../../modules/local/pixelator
include { PIXELATOR_ANALYSIS } from '../../../../modules/local/pixelator/analysis/main'
include { PIXELATOR_COMBINE_COLLAPSE } from '../../../../modules/local/pixelator/combine_collapse/main'
include { PIXELATOR_LAYOUT } from '../../../../modules/local/pixelator/layout/main'
include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main'
include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main'
include { collateVersionsFromTopic } from '../../utils_nfcore_pixelator_pipeline'

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -193,26 +194,31 @@ workflow PIXELATOR_PNA_V1 {
PIXELATOR_LAYOUT(ch_analysis)

// Prepare all data needed by reporting for each pixelator step
ch_input = channel.fromPath(params.input)
ch_experiment_summary_input = channel
.topic('all_results_for_reports')
.map { stage, files ->
def values = files instanceof List ? files : [files]
values.collect { f -> tuple(stage, f) }
}
.flatMap { it }
.collect(flat: false)
.map { stageFilePairs ->
def meta = [id: 'all']
def stages = stageFilePairs.collect { it[0] }
def files = stageFilePairs.collect { it[1] }
tuple(meta, stages, files)
}

if (!params.skip_experiment_summary) {
ch_input = channel.fromPath(params.input)
ch_experiment_summary_input = channel
.topic('all_results_for_reports')
.map { stage, files ->
def values = files instanceof List ? files : [files]
values.collect { f -> tuple(stage, f) }
}
.flatMap { it }
.collect(flat: false)
.map { stageFilePairs ->
def meta = [id: 'all']
def stages = stageFilePairs.collect { it[0] }
def files = stageFilePairs.collect { it[1] }
tuple(meta, stages, files)
}

ch_versions_yml = collateVersionsFromTopic()
.collectFile(name: 'software_versions.yml', sort: true, newLine: true)
.first()

EXPERIMENT_SUMMARY(
ch_input,
ch_experiment_summary_input,
ch_versions_yml,
)
}

Expand Down
2 changes: 1 addition & 1 deletion subworkflows/local/pna/v1/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ components:
- pixelator/analysis
- pixelator/layout
- experiment/summary
- pna_generate_reports
- collateversionsfromtopic
input:
- fastq:
type: file
Expand Down
45 changes: 24 additions & 21 deletions subworkflows/local/pna/v2/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ include { PIXELATOR_COMBINE_COLLAPSE } from '../../../../modules/local/pixelator
include { PIXELATOR_LAYOUT } from '../../../../modules/local/pixelator/layout'


include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main'
include { CAT_FASTQ } from '../../../../modules/nf-core/cat/fastq/main'
include { EXPERIMENT_SUMMARY } from '../../../../modules/local/experiment_summary/main'
include { CAT_FASTQ } from '../../../../modules/nf-core/cat/fastq/main'
include { collateVersionsFromTopic } from '../../utils_nfcore_pixelator_pipeline'

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -57,9 +58,6 @@ workflow PIXELATOR_PNA_V2 {
ch_panel_files // channel: [ meta, path(panel_file) | ]

main:
ch_versions = Channel.empty()


ch_fastq_grouped_by_pool = ch_fastq
.map { meta, fq -> tuple(meta.pool, [meta, fq]) }
.groupTuple()
Expand Down Expand Up @@ -239,26 +237,31 @@ workflow PIXELATOR_PNA_V2 {
PIXELATOR_LAYOUT( ch_analysis )

// Prepare all data needed by reporting for each pixelator step
ch_input = channel.fromPath(params.input)
ch_experiment_summary_input = channel
.topic('all_results_for_reports')
.map { stage, files ->
def values = files instanceof List ? files : [files]
values.collect { f -> tuple(stage, f) }
}
.flatMap { it }
.collect(flat: false)
.map { stageFilePairs ->
def meta = [id: 'all']
def stages = stageFilePairs.collect { it[0] }
def files = stageFilePairs.collect { it[1] }
tuple(meta, stages, files)
}

if (!params.skip_experiment_summary) {
ch_input = channel.fromPath(params.input)
ch_experiment_summary_input = channel
.topic('all_results_for_reports')
.map { stage, files ->
def values = files instanceof List ? files : [files]
values.collect { f -> tuple(stage, f) }
}
.flatMap { it }
.collect(flat: false)
.map { stageFilePairs ->
def meta = [id: 'all']
def stages = stageFilePairs.collect { it[0] }
def files = stageFilePairs.collect { it[1] }
tuple(meta, stages, files)
}

ch_versions_yml = collateVersionsFromTopic()
.collectFile(name: 'software_versions.yml', sort: true, newLine: true)
.first()

EXPERIMENT_SUMMARY(
ch_input,
ch_experiment_summary_input,
ch_versions_yml,
)
}

Expand Down
2 changes: 1 addition & 1 deletion subworkflows/local/pna/v2/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ components:
- pixelator/analysis
- pixelator/layout
- experiment/summary
- pna_generate_reports
- collateversionsfromtopic
input:
- fastq:
type: file
Expand Down
33 changes: 28 additions & 5 deletions subworkflows/local/utils_nfcore_pixelator_pipeline/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema'
include { samplesheetToList } from 'plugin/nf-schema'
include { completionEmail } from '../../nf-core/utils_nfcore_pipeline'
include { completionSummary } from '../../nf-core/utils_nfcore_pipeline'
include { softwareVersionsToYAML } from '../../nf-core/utils_nfcore_pipeline'
include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline'
include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline'

Expand Down Expand Up @@ -106,11 +107,6 @@ workflow PIPELINE_INITIALISATION {
nextflow_cli_args
)

//
// Create channel from input file provided through params.input
//
ch_versions = channel.empty()

//
// Resolve relative paths and validate fastq files existence
//
Expand Down Expand Up @@ -239,6 +235,33 @@ def getGenomeAttribute(attribute) {
return null
}

//
// Collate the `versions` topic into a channel of YAML fragments
//
// Any process consuming the result must not emit to the `versions` topic itself,
// as the topic only closes once all of its publishers have finished.
//
def collateVersionsFromTopic() {
def topic_versions = channel.topic("versions")
.distinct()
.branch { entry ->
versions_file: entry instanceof Path
versions_tuple: true
}

def topic_versions_string = topic_versions.versions_tuple
.map { process, tool, version ->
[ process[process.lastIndexOf(':')+1..-1], " ${tool}: ${version}" ]
}
.groupTuple(by:0)
.map { process, tool_versions ->
tool_versions.unique().sort()
"${process}:\n${tool_versions.join('\n')}"
}

return softwareVersionsToYAML(topic_versions.versions_file).mix(topic_versions_string)
}

//
// Generate methods description for MultiQC
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ components:
- pixelator/list/options
- completionemail
- completionsummary
- softwareversionstoyaml
input:
- version:
type: boolean
Expand Down
10 changes: 2 additions & 8 deletions tests/proxiome_v1.nf.test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@
"CAT_FASTQ": {
"cat": 9.5
},
"EXPERIMENT_SUMMARY": {
"experiment-summary": "0.12.0"
},
"PIXELATOR_AMPLICON": {
"pixelator": "0.30.0"
},
Expand Down Expand Up @@ -137,7 +134,7 @@
}
}
],
"timestamp": "2026-08-11T08:23:21.795999696",
"timestamp": "2026-08-17T11:09:58.197955852",
"meta": {
"nf-test": "0.9.5",
"nextflow": "26.04.2"
Expand All @@ -150,9 +147,6 @@
"CAT_FASTQ": {
"cat": 9.5
},
"EXPERIMENT_SUMMARY": {
"experiment-summary": "0.12.0"
},
"PIXELATOR_AMPLICON": {
"pixelator": "0.30.0"
},
Expand Down Expand Up @@ -279,7 +273,7 @@

]
],
"timestamp": "2026-08-11T08:22:39.094080602",
"timestamp": "2026-08-17T11:09:13.418847968",
"meta": {
"nf-test": "0.9.5",
"nextflow": "26.04.2"
Expand Down
10 changes: 2 additions & 8 deletions tests/proxiome_v2.nf.test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@
"CAT_FASTQ": {
"cat": 9.5
},
"EXPERIMENT_SUMMARY": {
"experiment-summary": "0.12.0"
},
"PIXELATOR_AMPLICON": {
"pixelator": "0.30.0"
},
Expand Down Expand Up @@ -171,7 +168,7 @@
}
}
],
"timestamp": "2026-08-11T08:27:56.30759346",
"timestamp": "2026-08-17T11:14:37.297215197",
"meta": {
"nf-test": "0.9.5",
"nextflow": "26.04.2"
Expand All @@ -184,9 +181,6 @@
"CAT_FASTQ": {
"cat": 9.5
},
"EXPERIMENT_SUMMARY": {
"experiment-summary": "0.12.0"
},
"PIXELATOR_AMPLICON": {
"pixelator": "0.30.0"
},
Expand Down Expand Up @@ -357,7 +351,7 @@

]
],
"timestamp": "2026-08-11T08:27:04.705573587",
"timestamp": "2026-08-17T11:13:43.166533768",
"meta": {
"nf-test": "0.9.5",
"nextflow": "26.04.2"
Expand Down
Loading
Loading