Skip to content
Closed
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
2 changes: 1 addition & 1 deletion modules/nf-core/deseq2/differential/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ process DESEQ2_DIFFERENTIAL {
tuple val(meta), path("*.vst.tsv") , optional: true, emit: vst_counts
tuple val(meta), path("*.deseq2.model.txt") , emit: model
tuple val(meta), path("*.R_sessionInfo.log") , emit: session_info
path "versions.yml" , emit: versions
path "versions.yml" , emit: versions_deseq2, topic: versions

when:
task.ext.when == null || task.ext.when
Expand Down
12 changes: 12 additions & 0 deletions modules/nf-core/deseq2/differential/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@ output:
description: Dump of R SessionInfo
pattern: "*.R_sessionInfo.log"
ontologies: []
versions_deseq2:
- versions.yml:
type: file
description: File containing software versions
pattern: "versions.yml"
ontologies:
- edam: http://edamontology.org/format_3750 # YAML
topics:
versions:
- versions.yml:
type: file
Expand All @@ -206,3 +214,7 @@ authors:
- "@pinin4fjords"
maintainers:
- "@pinin4fjords"
versions:
- versions.yml:
type: file
description: YAML file containing versions of tools used in the module
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,65 @@ is_valid_string <- function(input) {
!is.null(input) && nzchar(trimws(input))
}

#' Rewrite a contrast expression using sanitised design column names
#'
#' `makeContrasts()` requires syntactically valid coefficient names. The DREAM
#' design matrix is sanitised with `make.names()`, so a user may provide
#' contrasts using the original names (for example containing spaces). This
#' helper rewrites exact design-column matches to their sanitised equivalents.
#'
#' @param contrast_string User-provided contrast expression.
#' @param design_names Original design matrix column names.
#' original_design_names
#' @return Contrast expression compatible with `makeContrasts()`.
normalise_contrast_string <- function(contrast_string, design_names) {
if (!is_valid_string(contrast_string)) {
return(contrast_string)
}

sanitised_names <- make.names(design_names)
replacement_order <- order(nchar(design_names), decreasing = TRUE)
normalised <- contrast_string

for (idx in replacement_order) {
normalised <- gsub(
design_names[[idx]],
sanitised_names[[idx]],
normalised,
fixed = TRUE
)
}

normalised
}

#' Resolve user-supplied metadata column names against loaded metadata
#'
#' Metadata is read with `check.names = TRUE`, so columns containing spaces are
#' sanitised by R. This helper accepts either the original column name or the
#' sanitised version and returns the column present in `metadata`.
#'
#' @param column_name Column name provided by the user.
#' @param metadata Loaded metadata data frame.
#'
#' @return Resolved column name present in metadata.
resolve_metadata_column <- function(column_name, metadata) {
if (!is_valid_string(column_name)) {
return(column_name)
}

if (column_name %in% colnames(metadata)) {
return(column_name)
}

sanitised_name <- make.names(column_name)
if (sanitised_name %in% colnames(metadata)) {
return(sanitised_name)
}

column_name
}

#' Parse out options from a string without recourse to optparse
#'
#' @param x Long-form argument list like --opt1 val1 --opt2 val2
Expand Down Expand Up @@ -192,7 +251,11 @@ if ( ! is.null(opt\$round_digits)){
}

# If there is no option supplied, convert string "null" to NULL
keys <- c("formula", "contrast_string", "contrast_variable", "reference_level", "target_level", "seed", "blocking_variable", "transcript_lengths_file")
keys <- c(
"formula", "contrast_string", "contrast_variable", "reference_level",
"target_level", "seed", "blocking_variables", "transcript_lengths_file",
"exclude_samples_col", "exclude_samples_values"
)
opt[keys] <- lapply(opt[keys], nullify)

if ( ! is.null(opt\$seed)){
Expand Down Expand Up @@ -286,9 +349,11 @@ if (length(missing_samples) > 0) {
## CHECK CONTRAST SPECIFICATION ##
################################################
################################################
contrast_variable <- NULL
blocking.vars <- c()

if (! is_valid_string(opt\$formula)) {
contrast_variable <- make.names(opt\$contrast_variable)
blocking.vars <- c()
contrast_variable <- resolve_metadata_column(opt\$contrast_variable, sample.sheet)

if (!contrast_variable %in% colnames(sample.sheet)) {
stop(
Expand All @@ -307,7 +372,12 @@ if (! is_valid_string(opt\$formula)) {
)
)
} else if (is_valid_string(opt\$blocking_variables)) {
blocking.vars = make.names(unlist(strsplit(opt\$blocking_variables, split = ';')))
blocking.vars <- vapply(
unlist(strsplit(opt\$blocking_variables, split = ';')),
resolve_metadata_column,
character(1),
metadata = sample.sheet
)
if (!all(blocking.vars %in% colnames(sample.sheet))) {
missing_block <- paste(blocking.vars[! blocking.vars %in% colnames(sample.sheet)], collapse = ',')
stop(
Expand Down Expand Up @@ -435,9 +505,12 @@ if (!is.null(opt\$contrast_string)) {
} else {
# Parse as limma-style contrast expression
design_mat <- model.matrix(as.formula(model), data = as.data.frame(colData(dds)))
colnames(design_mat) <- make.names(colnames(design_mat))
original_design_names <- colnames(design_mat)
colnames(design_mat) <- make.names(original_design_names)
contrast_string <- normalise_contrast_string(opt\$contrast_string, original_design_names)
message("Normalised contrast string: ", contrast_string)
numeric_contrast <- as.numeric(
limma::makeContrasts(contrasts = opt\$contrast_string, levels = colnames(design_mat))
limma::makeContrasts(contrasts = contrast_string, levels = colnames(design_mat))
)

# Run DESeq2 results with numeric contrast
Expand Down
24 changes: 12 additions & 12 deletions modules/nf-core/deseq2/differential/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -97,7 +97,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -146,7 +146,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -195,7 +195,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -249,7 +249,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -299,7 +299,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -351,7 +351,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -403,7 +403,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -458,7 +458,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -507,7 +507,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -556,7 +556,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down Expand Up @@ -605,7 +605,7 @@ nextflow_process {
process.out.rlog_counts,
process.out.vst_counts,
process.out.model,
process.out.versions,
process.out.versions_deseq2,
file(process.out.dispersion_plot_png[0][1]).name,
file(process.out.dispersion_plot_pdf[0][1]).name,
file(process.out.rdata[0][1]).name
Expand Down
6 changes: 3 additions & 3 deletions modules/nf-core/deseq2/differential/tests/main.nf.test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@
"treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,d41d8cd98f00b204e9800998ecf8427e"
]
],
"versions": [
"versions_deseq2": [
"versions.yml:md5,2d67217d8adb1fa0d143b4017e6657fe",
"versions.yml:md5,2d67217d8adb1fa0d143b4017e6657fe"
],
Expand All @@ -1730,8 +1730,8 @@
],
"meta": {
"nf-test": "0.9.3",
"nextflow": "25.04.2"
"nextflow": "25.10.3"
},
"timestamp": "2026-01-20T14:57:21.703291049"
"timestamp": "2026-03-27T18:06:42.719478946"
}
}
4 changes: 0 additions & 4 deletions subworkflows/nf-core/abundance_differential_filter/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,13 @@ workflow ABUNDANCE_DIFFERENTIAL_FILTER {
norm_inputs.transcript_length.filter{index -> index[0].differential_method == 'deseq2'}
)

ch_versions = ch_versions.mix(DESEQ2_NORM.out.versions.first())

DESEQ2_DIFFERENTIAL(
inputs.contrasts_for_diff_with_formula.filter{index -> index[0].differential_method == 'deseq2'},
inputs.samples_and_matrix.filter{index -> index[0].differential_method == 'deseq2'},
inputs.control_features.filter{index -> index[0].differential_method == 'deseq2'},
inputs.transcript_length.filter{index -> index[0].differential_method == 'deseq2'}
)

ch_versions = ch_versions.mix(DESEQ2_DIFFERENTIAL.out.versions.first())

// ----------------------------------------------------
// Run propd
// ----------------------------------------------------
Expand Down
Loading
Loading