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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [[2.1.0](https://github.com/nf-core/pixelator/releases/tag/x.x.x)] - YYYY-MM-DD
## [[2.1.0](https://github.com/nf-core/pixelator/releases/tag/2.1.0)] - 2025-09-17

### Enhancements & fixes

Expand All @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Template update for nf-core/tools v3.3.2 by @fbdtemme in [#143](https://github.com/nf-core/pixelator/pull/143)
- Add the `experiment_summary` step which generates the Proximity Experiment Summary report by @johandahlberg in [#144](https://github.com/nf-core/pixelator/pull/144)
- Switch PIXELATOR_PNA_LAYOUT process label to process_high to allocate less memory by @ptajvar in [#147](https://github.com/nf-core/pixelator/pull/147)
- Simplify PNA_GENERATE_REPORTS subworkflow by @fbdtemme in [#150](https://github.com/nf-core/pixelator/pull/50)

### Parameters

Expand Down
20 changes: 11 additions & 9 deletions modules/local/experiment_summary/main.nf
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
process EXPERIMENT_SUMMARY {
tag "${meta.id}"
label "process_medium"

container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container
? 'quay.io/pixelgen-technologies/pixelatores:0.4.3'
: 'quay.io/pixelgen-technologies/pixelatores:0.4.3'}"

input:
val(meta)
path samplesheet_path
path amplicon_data , stageAs: "results/amplicon/*"
path demux_data , stageAs: "results/demux/*"
path collapse_data , stageAs: "results/collapse/*"
path graph_data , stageAs: "results/graph/*"
path denoise_data , stageAs: "results/denoise/*"
path analysis_data , stageAs: "results/analysis/*"
path layout_data , stageAs: "results/layout/*"

tuple (
val(meta),
path(amplicon_data , stageAs: "results/amplicon/*"),
path(demux_data , stageAs: "results/demux/*"),
path(collapse_data , stageAs: "results/collapse/*"),
path(graph_data , stageAs: "results/graph/*"),
path(denoise_data , stageAs: "results/denoise/*"),
path(analysis_data , stageAs: "results/analysis/*"),
path(layout_data , stageAs: "results/layout/*")
)

output:
tuple val(meta), path("*experiment-summary.html") , emit: html
Expand Down
214 changes: 108 additions & 106 deletions modules/local/experiment_summary/tests/main.nf.test

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions modules/local/pixelator/single-cell-pna/report/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ process PIXELATOR_PNA_REPORT {
: 'quay.io/pixelgen-technologies/pixelator:0.21.4'}"

input:
tuple val(meta), path(panel_file), val(panel)
path amplicon_data, stageAs: "results/amplicon/*"
path demux_data, stageAs: "results/demux/*"
path collapse_data, stageAs: "results/collapse/*"
path graph_data, stageAs: "results/graph/*"
path analysis_data, stageAs: "results/analysis/*"
path layout_data, stageAs: "results/layout/*"
tuple (
val(meta),
path(panel_file),
val(panel),
path(amplicon_data, stageAs: "results/amplicon/*"),
path(demux_data, stageAs: "results/demux/*"),
path(collapse_data, stageAs: "results/collapse/*"),
path(graph_data, stageAs: "results/graph/*"),
path(denoise_data, stageAs: "results/denoise/*"),
path(analysis_data, stageAs: "results/analysis/*"),
path(layout_data, stageAs: "results/layout/*")
)

output:
tuple val(meta), path("report/*.html"), emit: report
Expand Down
54 changes: 29 additions & 25 deletions modules/local/pixelator/single-cell-pna/report/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,35 @@ nextflow_process {
[ id:'PNA055_Sample07_filtered_S7', design:'pna-2', panel:'proxiome-immuno-155', technology:'pna' ],
[],
'proxiome-immuno-155',
]
input[1] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
]
input[2] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
]
input[3] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
]
input[4] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true),
]
input[5] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
]
input[6] = [
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/amplicon/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/demux/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/collapse/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/graph/PNA055_Sample07_filtered_S7.graph.pxl', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/denoise/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/analysis/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
],
[
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.meta.json', checkIfExists: true),
file(params.pipelines_testdata_base_path + 'testdata/pna/modules/layout/PNA055_Sample07_filtered_S7.report.json', checkIfExists: true),
]
]
"""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"nf-test": "0.9.2",
"nextflow": "25.04.6"
},
"timestamp": "2025-08-28T06:27:29.902626458"
"timestamp": "2025-09-17T14:22:24.534737422"
}
}
111 changes: 44 additions & 67 deletions subworkflows/local/pna/generate_reports.nf
Original file line number Diff line number Diff line change
Expand Up @@ -42,81 +42,58 @@ workflow PNA_GENERATE_REPORTS {
return [id, data]
}

ch_panel_col = panel_files.map { meta, data -> [meta.id, data] }

ch_amplicon_col = amplicon_data.map { meta, data -> [ meta.id, data] }
ch_demux_col = demux_data.map { meta, data -> [ meta.id, data] }
ch_collapse_col = collapse_data.map { meta, data -> [ meta.id, data] }
ch_graph_col = graph_data.map { meta, data -> [meta.id, data] }
ch_analysis_col = analysis_data.map { meta, data -> [meta.id, data] }
ch_denoise_col = denoise_data.map { meta, data -> [meta.id, data] }
ch_layout_col = layout_data.map { meta, data -> [meta.id, data] }

ch_report_data = ch_meta_col
.concat ( ch_panel_col )
.concat ( ch_amplicon_col )
.concat ( ch_demux_col )
.concat ( ch_collapse_col )
.concat ( ch_graph_col )
.concat ( ch_denoise_col)
.concat ( ch_analysis_col )
.concat ( ch_layout_col )
.groupTuple (size: 9)

ch_split_report_data = ch_report_data.multiMap {
_id, data ->
panel_files: [ data[0], data[1], data[1] ? null : data[0].panel ]
amplicon: data[2] ? data[2].flatten() : []
demux: data[3] ? data[3].flatten() : []
collapse: data[4] ? data[4].flatten() : []
graph: data[5] ? data[5].flatten() : []
denoise: data[6] ? data[6].flatten() : []
analysis: data[7] ? data[7].flatten() : []
layout: data[8] ? data[8].flatten() : []
}
.join( panel_files.map { meta, data -> [ meta.id, data ] } )
.join( amplicon_data.map { meta, data -> [ meta.id, data ] } )
.join( demux_data.map { meta, data -> [ meta.id, data ] } )
.join( collapse_data.map { meta, data -> [ meta.id, data ] } )
.join( graph_data.map { meta, data -> [ meta.id, data ] } )
.join( denoise_data.map { meta, data -> [ meta.id, data ] } )
.join( analysis_data.map { meta, data -> [ meta.id, data ] } )
.join( layout_data.map { meta, data -> [ meta.id, data ] } )

ch_pna_report_input = ch_report_data.map {
_id, meta, panels, amplicon, demux, collapse, graph, denoise, analysis, layout ->
[meta, panels, panels ? null : meta.panel, amplicon, demux, collapse, graph, denoise, analysis, layout]
}

PIXELATOR_PNA_REPORT (
ch_split_report_data.panel_files,
ch_split_report_data.amplicon,
ch_split_report_data.demux,
ch_split_report_data.collapse,
ch_split_report_data.graph,
ch_split_report_data.analysis,
ch_split_report_data.layout
)

ch_meta_grouped = ch_report_data.map { _id, data -> data[0] }.flatten().collect().map {
def newMeta = [:]
newMeta.id = "all-samples"
newMeta.samples = it.collect { e -> e.id }
return newMeta
PIXELATOR_PNA_REPORT ( ch_pna_report_input )

// Accumulate results across all samples grouped per stage

def accumulator = [
meta: [ id: "all-samples", samples: [] ],
amplicon: [],
demux: [],
collapse: [],
graph: [],
denoise: [],
analysis: [],
layout: []
]

ch_grouped_data = ch_report_data.reduce ( accumulator ) { acc, val ->
def (_id, meta, _panels, amplicon, demux, collapse, graph, denoise, analysis, layout) = val
acc.meta.samples += meta.id
acc.amplicon += amplicon
acc.demux += demux
acc.collapse += collapse
acc.graph += graph
acc.denoise += denoise
acc.analysis += analysis
acc.layout += layout
return acc
}.map { acc ->
[ acc.meta, acc.amplicon, acc.demux, acc.collapse, acc.graph, acc.denoise, acc.analysis, acc.layout ]
}

ch_amplicon_flat = ch_split_report_data.amplicon.flatten().collect()
ch_demux_flat = ch_split_report_data.demux.flatten().collect()
ch_collapse_flat = ch_split_report_data.collapse.flatten().collect()
ch_graph_flat = ch_split_report_data.graph.flatten().collect()
ch_denoise_flat = ch_split_report_data.denoise.flatten().collect()
ch_analysis_flat = ch_split_report_data.analysis.flatten().collect()
ch_layout_flat = ch_split_report_data.layout.flatten().collect()


if (!skip_experiment_summary) {
EXPERIMENT_SUMMARY(
ch_meta_grouped,
samplesheet,
ch_amplicon_flat,
ch_demux_flat,
ch_collapse_flat,
ch_graph_flat,
ch_denoise_flat,
ch_analysis_flat,
ch_layout_flat
)
EXPERIMENT_SUMMARY ( samplesheet, ch_grouped_data )

ch_versions = ch_versions.mix(EXPERIMENT_SUMMARY.out.versions)
ch_experiment_summary = EXPERIMENT_SUMMARY.out.html
} else {
ch_experiment_summary = ch_meta_grouped.combine(Channel.of([]))
ch_experiment_summary = ch_grouped_data.map { it -> it[0] }.combine(Channel.of([]))
}

ch_versions = ch_versions.mix(PIXELATOR_PNA_REPORT.out.versions.first())
Expand Down