Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 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
15 changes: 13 additions & 2 deletions modules/nf-core/variancepartition/dream/templates/dream.R
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ opt <- list(
winsor_tail_p = "0.05,0.1", # Winsor tail probabilities for eBayes
ddf = "adaptive", # 'Satterthwaite', 'Kenward-Roger', or 'adaptive'
reml = FALSE,
round_digits = NULL,
formula = "$formula", # User-specified formula (e.g. "~ + (1 | sample_number)")
apply_voom = FALSE # Whether to apply `voomWithDreamWeights`
)
Expand Down Expand Up @@ -107,6 +108,10 @@ opt\$p.value <- as.numeric(opt\$p.value)
opt\$lfc <- as.numeric(opt\$lfc)
opt\$confint <- as.logical(opt\$confint)

if (!is.null(opt\$round_digits)){
opt\$round_digits <- as.numeric(opt\$round_digits)
}

# Load metadata
metadata <- read_delim_flexible(opt\$sample_file, header = TRUE, stringsAsFactors = TRUE)
rownames(metadata) <- metadata[[opt\$sample_id_col]]
Expand Down Expand Up @@ -178,22 +183,28 @@ if (!is.null(opt\$contrast_string)) {
stdev.coef.lim = stdev_coef_lim_vals,
trend = opt\$trend, robust = opt\$robust,
winsor.tail.p = winsor_tail_p_vals)
results <- topTable(fit2,
results <- topTable(fit2, number = Inf,
adjust.method = opt\$adjust.method,
p.value = opt\$p.value, lfc = opt\$lfc, confint = opt\$confint)

} else {
coef_name <- paste0(opt\$contrast_variable, opt\$contrast_target)
cat("Using default contrast matrix:", coef_name, "\n")

results <- topTable(fitmm, coef = coef_name,
results <- topTable(fitmm, coef = coef_name, number = Inf,
adjust.method = opt\$adjust.method, p.value = opt\$p.value,
lfc = opt\$lfc, confint = opt\$confint)
}

results\$gene_id <- rownames(results)
results <- results[, c("gene_id", setdiff(names(results), "gene_id"))]

# Round results if required
if (!is.null(opt\$round_digits)) {
numeric_columns <- vapply(results, is.numeric, logical(1))
results[numeric_columns] <- lapply(results[numeric_columns], round, digits = opt\$round_digits)
}

# Export topTable results
write.table(results, file = paste(opt\$output_prefix, 'dream.results.tsv', sep = '.'),
col.names = TRUE, row.names = FALSE, sep = '\t', quote = FALSE )
Expand Down
47 changes: 35 additions & 12 deletions modules/nf-core/variancepartition/dream/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ nextflow_process {

name "Test Process VARIANCEPARTITION_DREAM"
script "../main.nf"
config "./nextflow.config"
process "VARIANCEPARTITION_DREAM"

tag "modules"
Expand All @@ -12,6 +13,9 @@ nextflow_process {
test("RNAseq - Feature Counts - formula + comparison contrast string - interaction") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of([
Expand Down Expand Up @@ -40,8 +44,8 @@ nextflow_process {
assertAll(
{ assert process.success },
{ assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert path(process.out.results[0][1]).getText().contains("0.8333") },
{ assert path(process.out.results[0][1]).getText().contains("13.5\t21.125\t4.40") },
{ assert path(process.out.results[0][1]).getText().contains("0.83") },
{ assert path(process.out.results[0][1]).getText().contains("13.5\t21.12\t4.41") },
{ assert snapshot(process.out.model, process.out.versions).match() }
)
}
Expand All @@ -50,6 +54,9 @@ nextflow_process {
test("Mus musculus - expression table - contrasts") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':null, 'formula':null])
Expand Down Expand Up @@ -77,6 +84,9 @@ nextflow_process {
test("Mus musculus - expression table - contrasts + formula + comparison contrast string") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment', 'comparison':'treatmenthND6'])
Expand All @@ -98,16 +108,20 @@ nextflow_process {
assertAll(
{ assert process.success },
{ assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert path(process.out.results[0][1]).getText().contains("849.6666") },
{ assert path(process.out.results[0][1]).getText().contains("1050\t549\t3.78") }
)
{ assert path(process.out.results[0][1]).getText().contains("849.67") },
{ assert path(process.out.results[0][1]).getText().contains("1050\t549\t3.78") },
{ assert snapshot(process.out.model, process.out.versions).match() }
)
}
}


test("Mus musculus - expression table - contrasts + formula + weighted comparison contrast string") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ 0 + treatment', 'comparison':'2 * treatmenthND6 - treatmentmCherry'])
Expand All @@ -128,17 +142,20 @@ nextflow_process {
then {
assertAll(
{ assert process.success },
{ assert snapshot(process.out.model, process.out.versions).match() },
{ assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert path(process.out.results[0][1]).getText().contains("2124\t549\t4.83") },
{ assert path(process.out.results[0][1]).getText().contains("1707.33") }
)
{ assert path(process.out.results[0][1]).getText().contains("2124\t549\t4.84") },
{ assert path(process.out.results[0][1]).getText().contains("1707.33") },
{ assert snapshot(process.out.model, process.out.versions).match() }
)
}
}

test("Mus musculus - expression table - contrasts + formula + comparison contrast string - no intercept") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ 0 + treatment + sample_number', 'comparison':'treatmenthND6 - treatmentmCherry'])
Expand All @@ -161,15 +178,18 @@ nextflow_process {
{ assert process.success },
{ assert snapshot(process.out.model, process.out.versions).match() },
{ assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert path(process.out.results[0][1]).getText().contains("-95.6666") },
{ assert path(process.out.results[0][1]).getText().contains("1050\t549\t4.15") }
)
{ assert path(process.out.results[0][1]).getText().contains("-95.67") },
{ assert path(process.out.results[0][1]).getText().contains("1050\t549\t4.16") }
)
}
}

test("Mus musculus - expression table - contrasts + blocking factors") {

when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment + (1 | sample_number)'])
Expand Down Expand Up @@ -199,6 +219,9 @@ nextflow_process {

options '-stub'
when {
params {
module_args = "--round_digits 2"
}
process {
"""
input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment + (1 | sample_number)'])
Expand Down
113 changes: 33 additions & 80 deletions modules/nf-core/variancepartition/dream/tests/main.nf.test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
]
],
"meta": {
"nf-test": "0.9.2",
"nextflow": "25.04.6"
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2025-11-10T16:15:40.192241719"
"timestamp": "2025-12-04T21:00:34.198143553"
},
"RNAseq - Feature Counts - formula + comparison contrast string - interaction": {
"content": [
Expand All @@ -46,10 +46,10 @@
]
],
"meta": {
"nf-test": "0.9.2",
"nextflow": "25.04.6"
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2025-11-10T16:14:20.039981065"
"timestamp": "2025-12-04T20:59:55.416875311"
},
"Mus musculus - expression table - contrasts + blocking factors": {
"content": [
Expand All @@ -64,7 +64,7 @@
"blocking_factors": "sample_number",
"formula": "~ treatment + (1 | sample_number)"
},
"treatment_mCherry_hND6.dream.results.tsv:md5,ad7e79a25bf407b210e3ebfbf734f68e"
"treatment_mCherry_hND6.dream.results.tsv:md5,df0717ddf702543c375c1a5f4eae3fd7"
]
],
"1": [
Expand Down Expand Up @@ -106,7 +106,7 @@
"blocking_factors": "sample_number",
"formula": "~ treatment + (1 | sample_number)"
},
"treatment_mCherry_hND6.dream.results.tsv:md5,ad7e79a25bf407b210e3ebfbf734f68e"
"treatment_mCherry_hND6.dream.results.tsv:md5,df0717ddf702543c375c1a5f4eae3fd7"
]
],
"versions": [
Expand All @@ -115,10 +115,10 @@
}
],
"meta": {
"nf-test": "0.9.2",
"nextflow": "25.04.6"
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2025-11-10T16:18:15.340812595"
"timestamp": "2025-12-04T19:20:24.632444115"
},
"Mus musculus - expression table - contrasts + blocking factors stub": {
"content": [
Expand Down Expand Up @@ -210,82 +210,35 @@
]
],
"meta": {
"nf-test": "0.9.2",
"nextflow": "25.04.6"
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2025-11-10T16:15:20.824781388"
"timestamp": "2025-12-04T21:02:12.893838766"
},
"Mus musculus - expression table - contrasts + formula + comparison contrast string": {
"content": [
{
"0": [
[
{
"id": "treatment_mCherry_hND6",
"variable": "treatment",
"reference": "mCherry",
"target": "hND6",
"blocking_factors": "sample_number",
"formula": "~ treatment",
"comparison": "treatmenthND6"
},
"treatment_mCherry_hND6.dream.results.tsv:md5,0b9521f3aafdbc7f2df761bdc8b1a1ea"
]
],
"1": [
[
{
"id": "treatment_mCherry_hND6",
"variable": "treatment",
"reference": "mCherry",
"target": "hND6",
"blocking_factors": "sample_number",
"formula": "~ treatment",
"comparison": "treatmenthND6"
},
"treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17"
]
],
"2": [
"versions.yml:md5,fc1f26eb2194018e99fc2916332676b7"
],
"model": [
[
{
"id": "treatment_mCherry_hND6",
"variable": "treatment",
"reference": "mCherry",
"target": "hND6",
"blocking_factors": "sample_number",
"formula": "~ treatment",
"comparison": "treatmenthND6"
},
"treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17"
]
],
"results": [
[
{
"id": "treatment_mCherry_hND6",
"variable": "treatment",
"reference": "mCherry",
"target": "hND6",
"blocking_factors": "sample_number",
"formula": "~ treatment",
"comparison": "treatmenthND6"
},
"treatment_mCherry_hND6.dream.results.tsv:md5,0b9521f3aafdbc7f2df761bdc8b1a1ea"
]
],
"versions": [
"versions.yml:md5,fc1f26eb2194018e99fc2916332676b7"
[
[
{
"id": "treatment_mCherry_hND6",
"variable": "treatment",
"reference": "mCherry",
"target": "hND6",
"blocking_factors": "sample_number",
"formula": "~ treatment",
"comparison": "treatmenthND6"
},
"treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17"
]
}
],
[
"versions.yml:md5,fc1f26eb2194018e99fc2916332676b7"
]
],
"meta": {
"nf-test": "0.9.2",
"nextflow": "24.10.5"
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2025-04-07T17:45:38.612858235"
"timestamp": "2025-12-04T21:02:02.754734146"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
process {
withName: 'VARIANCEPARTITION_DREAM' {
ext.args = { [
"--round_digits 2"
].join(' ').trim() }
ext.prefix = { "${meta.id}_${meta.differential_method}" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ nextflow_workflow {
tag "variancepartition/dream"

test("dream") {
config './dream.config'
tag "dream_simple"

when {
Expand Down Expand Up @@ -59,8 +60,8 @@ nextflow_workflow {
then {
assertAll(
{ assert workflow.success },
{ assert path(workflow.out.results_genewise[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert snapshot(
workflow.out.results_genewise,
workflow.out.results_genewise_filtered,
workflow.out.model,
workflow.out.versions
Expand All @@ -70,6 +71,7 @@ nextflow_workflow {
}

test("dream - complex contrast - literal contrast string comparison") {
config './dream.config'
tag "dream_complex"

when {
Expand Down Expand Up @@ -114,10 +116,8 @@ nextflow_workflow {
assertAll(
{ assert workflow.success },
{ assert path(workflow.out.results_genewise[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") },
{ assert path(workflow.out.results_genewise[0][1]).getText().contains("-95.6666") },
{ assert path(workflow.out.results_genewise[0][1]).getText().contains("1050\t549\t4.15") },
{ assert snapshot(
file(workflow.out.results_genewise[0][1]).name,
workflow.out.results_genewise_filtered,
workflow.out.model,
workflow.out.versions
).match() }
Expand Down
Loading
Loading