From 75e1e9df89c22ae3cf8e386c512ff27ea799bba0 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 18:58:01 +0000 Subject: [PATCH 01/53] update snapshot --- .../decoupler/decoupler/tests/main.nf.test.snap | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap b/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap index f7133a7585ec..713ead476f37 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap @@ -3,7 +3,7 @@ "content": [ "[deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler.tsv, deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler.tsv]", "[deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler.tsv, deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler.tsv]", - "[deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png, deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler_plot.png, deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png, deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler_plot.png]", + "[deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png, deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png]", 2, 2, [ @@ -26,7 +26,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-17T03:01:11.305706897" + "timestamp": "2025-08-12T18:24:03.118968335" }, "decoupler stub": { "content": [ @@ -52,7 +52,7 @@ { "id": "test" }, - "null_test_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" + "null_test_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "3": [ @@ -79,7 +79,7 @@ { "id": "test" }, - "null_test_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" + "null_test_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "versions": [ @@ -91,13 +91,13 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-17T01:49:26.123404951" + "timestamp": "2025-08-12T18:45:09.567512573" }, "decoupler_test": { "content": [ "[deseq2_test_consensus_estimate_decoupler.tsv, deseq2_test_ulm_estimate_decoupler.tsv]", "[deseq2_test_consensus_pvals_decoupler.tsv, deseq2_test_ulm_pvals_decoupler.tsv]", - "[deseq2_test_consensus_estimate_decoupler_plot.png, deseq2_test_consensus_pvals_decoupler_plot.png, deseq2_test_ulm_estimate_decoupler_plot.png, deseq2_test_ulm_pvals_decoupler_plot.png]", + "[deseq2_test_consensus_estimate_decoupler_plot.png, deseq2_test_ulm_estimate_decoupler_plot.png]", 2, 2, [ @@ -120,6 +120,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-17T04:07:01.430446461" + "timestamp": "2025-08-12T18:27:18.094901759" } } \ No newline at end of file From 46f8d39ea6704c3a69ca58cac5f4567833ebb7d5 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 18:58:24 +0000 Subject: [PATCH 02/53] exchange gtf file for annot tsv file --- modules/nf-core/decoupler/decoupler/tests/main.nf.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test b/modules/nf-core/decoupler/decoupler/tests/main.nf.test index 932807e1d1a9..32d274a46acc 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test @@ -25,7 +25,7 @@ nextflow_process { input[1] = [ file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true) ] - input[2] = [file("https://ftp.ensembl.org/pub/release-81/gtf/mus_musculus/Mus_musculus.GRCm38.81.gtf.gz", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -75,7 +75,7 @@ nextflow_process { input[1] = [ file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://ftp.ensembl.org/pub/release-81/gtf/mus_musculus/Mus_musculus.GRCm38.81.gtf.gz", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -125,7 +125,7 @@ nextflow_process { input[1] = [ file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://ftp.ensembl.org/pub/release-81/gtf/mus_musculus/Mus_musculus.GRCm38.81.gtf.gz", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] """ } } From b5afaa8617e447c4e685a3f2609c0bdfec224e3e Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 18:58:39 +0000 Subject: [PATCH 03/53] remove parse_gtf function --- .../decoupler/templates/decoupler.py | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index b0869c4bf0dd..e55c1279a60d 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -43,50 +43,21 @@ def parse_ext_args(args_string: str): parser.add_argument("--methods", type=str, default = "ulm", help="Comma-separated list of methods to use (e.g., 'mlm,ulm')") return parser.parse_args(args_list) -def parse_gtf(gtf_file: str): - """ - Parse an optional GTF file to create a mapping of ENSEMBL gene IDs to gene symbols (required to use Progeny data). - """ - mapping = {} - opener = gzip.open if gtf_file.endswith('.gz') else open - with opener(gtf_file, 'rt') as f: - for line in f: - if line.startswith("#"): - continue - fields = line.strip().split("\t") - if len(fields) < 9: - continue - attributes_field = fields[8] - attributes = {} - for attr in attributes_field.split(";"): - attr = attr.strip() - if not attr: - continue - parts = attr.split(" ", 1) - if len(parts) != 2: - continue - key, value = parts - attributes[key] = value.replace('"', '').strip() - gene_id = attributes.get("gene_id") - gene_symbol = attributes.get("gene_name") or attributes.get("gene_symbol") or attributes.get("external_gene_name") - if gene_id and gene_symbol: - mapping[gene_id] = gene_symbol - return mapping - # Parse external arguments -raw_args = "${task.ext.args}" +raw_args = """${task.ext.args}""" parsed_args = parse_ext_args(raw_args) methods = [m.strip() for m in parsed_args.methods.split(",") if m.strip()] if parsed_args.ensembl_ids.upper() == "TRUE": try: - gene_mapping = parse_gtf("${gtf}") + annot_df = pd.read_csv("${annot}", sep="\t") + gene_mapping = dict(zip(annot_df["gene_id"], annot_df["gene_name"])) new_index = [gene_mapping.get(ens, None) for ens in mat.index] mat.index = new_index mat = mat[mat.index.notnull()] mat = mat[~mat.index.duplicated(keep='first')] except Exception as e: - print("ERROR: Failed to parse GTF:", e) + print("ERROR: Failed to read annotation file:", e) sys.exit(1) if parsed_args.transpose.upper() == "TRUE": From b879dbbfab2893e27db47f60b8df1942b7ef4500 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 18:58:55 +0000 Subject: [PATCH 04/53] exchange gtf file for annot tsv file --- modules/nf-core/decoupler/decoupler/main.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index 7d2ae333f1f7..e8cde984bc70 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -10,12 +10,12 @@ process DECOUPLER { input: tuple val(meta), path(mat) path(net) - path(gtf) + path(annot) output: tuple val(meta), path("*estimate_decoupler.tsv"), emit: dc_estimate tuple val(meta), path("*pvals_decoupler.tsv"), emit: dc_pvals - tuple val(meta), path("*decoupler_plot.png"), emit: png + tuple val(meta), path("*estimate_decoupler_plot.png"), emit: png path("versions.yml"), emit: versions when: @@ -28,7 +28,7 @@ process DECOUPLER { """ touch ${task.ext.prefix}_estimate_decoupler.tsv touch ${task.ext.prefix}_pvals_decoupler.tsv - touch ${task.ext.prefix}_decoupler_plot.png + touch ${task.ext.prefix}_estimate_decoupler_plot.png touch versions.yml """ } From 595cf263c2ce45442a41e2f667864ba32365c741 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 19:11:23 +0000 Subject: [PATCH 05/53] update --- modules/nf-core/decoupler/decoupler/main.nf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index e8cde984bc70..e95505dcf99b 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -1,7 +1,6 @@ process DECOUPLER { tag "$meta.id" label 'process_medium' - conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/dc/dc0ee6d6033b9f04c6377ad3b1cf5f924e3243626ab8d7be836d9d6617f8da4e/data' : From 049f327de055ff70edb4532c3b4ac958cef46c4a Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 19:46:46 +0000 Subject: [PATCH 06/53] update --- modules/nf-core/decoupler/decoupler/meta.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/meta.yml b/modules/nf-core/decoupler/decoupler/meta.yml index b6866508dfb5..813dcf6e888e 100644 --- a/modules/nf-core/decoupler/decoupler/meta.yml +++ b/modules/nf-core/decoupler/decoupler/meta.yml @@ -50,12 +50,13 @@ input: pattern: "*.tsv" ontologies: - edam: http://edamontology.org/format_3475 # TSV - - gtf: + - annot: type: file description: | - Annotation file in GTF format - pattern: "*.gtf" - ontologies: [] + Annotation file in tsv format + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV output: dc_estimate: - - meta: @@ -90,12 +91,12 @@ output: description: | Groovy Map containing sample information e.g. [ id:‘test’, single_end ] - - "*decoupler_plot.png": + - "*estimate_decoupler_plot.png": type: file description: | The file containing the plots associated to the estimation results of the enrichment(s) - pattern: "*decoupler_plot.png" + pattern: "*estimate_decoupler_plot.png" ontologies: - edam: http://edamontology.org/format_3475 # TSV versions: From f9f4830174767058ddc923e0034c8033a33ead64 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 20:10:16 +0000 Subject: [PATCH 07/53] update meta.yml --- modules/nf-core/decoupler/decoupler/meta.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/meta.yml b/modules/nf-core/decoupler/decoupler/meta.yml index 813dcf6e888e..7e791ff14c79 100644 --- a/modules/nf-core/decoupler/decoupler/meta.yml +++ b/modules/nf-core/decoupler/decoupler/meta.yml @@ -53,8 +53,11 @@ input: - annot: type: file description: | - Annotation file in tsv format + Annotation file in TSV format containing gene ID to gene name mappings. + Used specifically for mapping Ensembl IDs to gene names. + Expected format: two columns with gene_id and gene_name headers. pattern: "*.tsv" + required: false ontologies: - edam: http://edamontology.org/format_3475 # TSV output: From cb092f6919175b3038de6f91ab59f38c10c97c9b Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 20:25:07 +0000 Subject: [PATCH 08/53] fix --- modules/nf-core/decoupler/decoupler/templates/decoupler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index e55c1279a60d..f3b58921ed5a 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -44,7 +44,7 @@ def parse_ext_args(args_string: str): return parser.parse_args(args_list) # Parse external arguments -raw_args = """${task.ext.args}""" +raw_args = "${task.ext.args}" parsed_args = parse_ext_args(raw_args) methods = [m.strip() for m in parsed_args.methods.split(",") if m.strip()] From a081c2753e69023f62dcb04830bfc39d2a4e0410 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 20:41:24 +0000 Subject: [PATCH 09/53] Include annotation file expected format --- modules/nf-core/decoupler/decoupler/templates/decoupler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index f3b58921ed5a..25f708dd2489 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -57,7 +57,7 @@ def parse_ext_args(args_string: str): mat = mat[mat.index.notnull()] mat = mat[~mat.index.duplicated(keep='first')] except Exception as e: - print("ERROR: Failed to read annotation file:", e) + print("Expected format: tsv file with at least two columns with gene_id and gene_name headers. ERROR: Failed to read annotation file:", e) sys.exit(1) if parsed_args.transpose.upper() == "TRUE": From 85f0187a95d3175e1ef61ac5513bc2735a717433 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 12 Aug 2025 22:08:28 +0000 Subject: [PATCH 10/53] Update: reference file --- modules/nf-core/decoupler/decoupler/tests/main.nf.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test b/modules/nf-core/decoupler/decoupler/tests/main.nf.test index 32d274a46acc..feaef0048ef3 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test @@ -25,7 +25,7 @@ nextflow_process { input[1] = [ file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -75,7 +75,7 @@ nextflow_process { input[1] = [ file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -125,7 +125,7 @@ nextflow_process { input[1] = [ file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/SRP254919.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } From e8684dd2dcfd8d9706ce59b3d514cd8efd65caf0 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 21:28:50 +0000 Subject: [PATCH 11/53] include decoupler to subworkflow --- .../main.nf | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index f52ec8197ef5..890c013dd50a 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -8,6 +8,7 @@ include { CUSTOM_TABULARTOGSEACLS } from '../../../modules/nf-core/custom/tabul include { CUSTOM_TABULARTOGSEACHIP } from '../../../modules/nf-core/custom/tabulartogseachip/main.nf' include { GSEA_GSEA } from '../../../modules/nf-core/gsea/gsea/main.nf' include { PROPR_GREA } from "../../../modules/nf-core/propr/grea/main.nf" +include { DECOUPLER } from '../../../modules/nf-core/decoupler/decoupler/main' // Combine meta maps, including merging non-identical values of shared keys (e.g. 'id') def mergeMaps(meta, meta2){ @@ -80,6 +81,25 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { .combine(ch_contrasts_transposed, by:0) .multiMap(criteria) + // In the case of DECOUPLER, it needs additional files coming from other channels that other methods don't use + // here we define the input channel for the DECOUPLER section + + ch_input_for_decoupler = ch_input_for_other.input + .filter{ it[0].functional_method == 'decoupler' } + .map { meta, differential_results -> + // Preserve the method_differential field from the original metadata + def new_meta = [ + id: meta.id, + method_differential: meta.params.differential_method + ] + [new_meta, differential_results] + } + ch_decoupler_network = ch_input_for_other.input + .filter{ it[0].functional_method == 'decoupler' } + .map { meta, differential_results -> + meta.params.decoupler_network ? file(meta.params.decoupler_network, checkIfExists: true) : [] + } + // ---------------------------------------------------- // Perform enrichment analysis with gprofiler2 // ---------------------------------------------------- @@ -116,6 +136,14 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { ch_input_for_gsea.map{ tuple(it[0].reference, it[0].target) }, CUSTOM_TABULARTOGSEACHIP.out.chip.first() ) + // ---------------------------------------------------- + // Perform enrichment analysis with DECOUPLER + // ---------------------------------------------------- + DECOUPLER( + ch_input_for_decoupler, + ch_decoupler_network, + ch_featuresheet.map{ meta, features, features_id, features_symbol -> features } + ) // ---------------------------------------------------- // Perform enrichment analysis with GREA @@ -133,6 +161,7 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { .mix(CUSTOM_TABULARTOGSEACLS.out.versions) .mix(CUSTOM_TABULARTOGSEACHIP.out.versions) .mix(GSEA_GSEA.out.versions) + .mix(DECOUPLER.out.versions) .mix(PROPR_GREA.out.versions) emit: @@ -147,6 +176,11 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // gsea-specific outputs gsea_report = GSEA_GSEA.out.report_tsvs_ref.join(GSEA_GSEA.out.report_tsvs_target) + // decoupler-specific outputs + decoupler_dc_estimate = DECOUPLER.out.dc_estimate + decoupler_dc_pvals = DECOUPLER.out.dc_pvals + decoupler_png = DECOUPLER.out.png + // grea-specific outputs grea_results = PROPR_GREA.out.results From fcdb6a4968dcc6a2c5cafddd9010c434e5556bea Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 21:29:28 +0000 Subject: [PATCH 12/53] Include decoupler test config --- .../tests/decoupler.config | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config new file mode 100644 index 000000000000..d050cc3d281d --- /dev/null +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config @@ -0,0 +1,11 @@ +params { + decoupler_network = "https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv" + method_differential = 'deseq2' +} + +process { + withName: 'DECOUPLER' { + ext.prefix = { "${meta.method_differential}_${meta.id}" } + ext.args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm" + } +} From 86a46199d50a80c54d4dc9299fe26a2bae6a2984 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 21:30:35 +0000 Subject: [PATCH 13/53] Include decoupler to test file --- .../tests/main.nf.test | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index fadbb68a4191..03510966c2ff 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -19,6 +19,7 @@ nextflow_workflow { tag "custom/tabulartogseachip" tag "subworkflows/abundance_differential_filter" tag "abundance_differential_filter" + tag "decoupler_basic" test("test gprofiler2 - mouse") { tag 'gprofiler2_basic' @@ -463,6 +464,60 @@ nextflow_workflow { } + test("deseq2 + decoupler - mouse") { + tag "deseq2+decoupler" + tag "decoupler_basic" + config "./decoupler.config" + + when { + workflow { + """ + ch_input = Channel.of([ + [ + 'id':'treatment_mCherry_hND6', + 'method_differential':'deseq2', + 'params': [ + 'decoupler_network': 'https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv', + 'differential_method': 'deseq2' + ] + ], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/treatment_mCherry_hND6_.deseq2.results.tsv", checkIfExists: true), + [], // genesets (empty for decoupler) + [], // background (empty for decoupler) + 'decoupler' // method + ]) + + ch_contrasts = Channel.of([[], [], [], [], [], []]) + ch_samplesheet = Channel.of([[], []]) + ch_featuresheet = Channel.of([ + [], + file("https://ftp.ensembl.org/pub/release-81/gtf/mus_musculus/Mus_musculus.GRCm38.81.gtf.gz", checkIfExists: true), + [], + [] + ]) + + input[0] = ch_input + input[1] = ch_contrasts + input[2] = ch_samplesheet + input[3] = ch_featuresheet + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.decoupler_dc_estimate, + workflow.out.decoupler_dc_pvals, + workflow.out.decoupler_png, + path(workflow.out.versions.get(0)).yaml, + workflow.out.versions + ).match() } + ) + } + } + test("stub") { tag 'gprofiler2_basic' config './gprofiler2.config' From 30d8dbc0b60a3d734f127e7761bde27fa9378499 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 21:30:49 +0000 Subject: [PATCH 14/53] Update snapshot with decoupler output files --- .../tests/main.nf.test.snap | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 4e6fe0334345..3b9f05944c62 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -353,6 +353,60 @@ }, "timestamp": "2025-07-21T14:58:54.929796085" }, + "deseq2 + decoupler - mouse": { + "content": [ + [ + [ + { + "id": "treatment_mCherry_hND6", + "method_differential": "deseq2" + }, + [ + "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler.tsv:md5,a4f145de6d86d6d77b90d2058225ae65", + "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler.tsv:md5,78395931b16c735f2c345ec087ce5bf2" + ] + ] + ], + [ + [ + { + "id": "treatment_mCherry_hND6", + "method_differential": "deseq2" + }, + [ + "deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler.tsv:md5,a9cae76e3d053e497682de78682e3ab1", + "deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler.tsv:md5,bdf43423d8b3064acc950206687507d5" + ] + ] + ], + [ + [ + { + "id": "treatment_mCherry_hND6", + "method_differential": "deseq2" + }, + [ + "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png:md5,b651ed914213b44ab79851c39f5339f4", + "deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler_plot.png:md5,1638c8b5ac2add25c571e5c8a164bdcd", + "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png:md5,3e3f449c8605e08084f533a4e9996e27", + "deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler_plot.png:md5,4f21dd2d5510b7455365061b58df9be4" + ] + ] + ], + { + "DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:DECOUPLER": null, + "decoupler-py": "1.8.0" + }, + [ + "versions.yml:md5,d268550490df4c6a9e58baa7d08b93e6" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T21:21:54.753311165" + }, "deseq2 + gsea - mouse": { "content": [ [ From bcc16d6c961717a1930a5f4208151689c9379d4d Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 21:30:56 +0000 Subject: [PATCH 15/53] Add decoupler config --- .../differential_functional_enrichment/tests/all.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/all.config b/subworkflows/nf-core/differential_functional_enrichment/tests/all.config index eb32d8ca4bba..57ae06008703 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/all.config +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/all.config @@ -61,4 +61,9 @@ process { withName: "PROPR_GREA"{ ext.args = { "--permutation 10 --set_min 10 --seed 123 --round_digits 5"} } + + withName: 'DECOUPLER' { + ext.prefix = { "${meta.method_differential}_${meta.id}" } + ext.args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm" + } } From f2f035cc166d99cd00eaf610895074fd3424947e Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 22:38:58 +0000 Subject: [PATCH 16/53] Replace gtf annotation file for tsv table for decoupler --- .../differential_functional_enrichment/tests/main.nf.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index 03510966c2ff..83c8faee5d80 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -491,7 +491,7 @@ nextflow_workflow { ch_samplesheet = Channel.of([[], []]) ch_featuresheet = Channel.of([ [], - file("https://ftp.ensembl.org/pub/release-81/gtf/mus_musculus/Mus_musculus.GRCm38.81.gtf.gz", checkIfExists: true), + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/differentialabundance/modules_testdata/Mus_musculus.anno.tsv", checkIfExists: true), [], [] ]) From a9540fa8aee25a3df7fbffd210c8fa7053114ba9 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 22:39:15 +0000 Subject: [PATCH 17/53] Update snapshot to remove pvals plots for decoupler --- .../tests/main.nf.test.snap | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 3b9f05944c62..8fb0b7d4e496 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -387,9 +387,7 @@ }, [ "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png:md5,b651ed914213b44ab79851c39f5339f4", - "deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler_plot.png:md5,1638c8b5ac2add25c571e5c8a164bdcd", - "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png:md5,3e3f449c8605e08084f533a4e9996e27", - "deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler_plot.png:md5,4f21dd2d5510b7455365061b58df9be4" + "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png:md5,3e3f449c8605e08084f533a4e9996e27" ] ] ], @@ -405,7 +403,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-13T21:21:54.753311165" + "timestamp": "2025-08-13T22:19:19.97696954" }, "deseq2 + gsea - mouse": { "content": [ @@ -501,13 +499,31 @@ ] ], "3": [ - + ], "4": [ - + ], "5": [ + + ], + "6": [ + + ], + "7": [ + + ], + "8": [ "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" + ], + "decoupler_dc_estimate": [ + + ], + "decoupler_dc_pvals": [ + + ], + "decoupler_png": [ + ], "gprofiler2_all_enrich": [ [ @@ -549,10 +565,10 @@ ] ], "grea_results": [ - + ], "gsea_report": [ - + ], "versions": [ "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" @@ -563,6 +579,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-21T15:04:23.243032039" + "timestamp": "2025-08-13T22:09:24.891941865" } -} \ No newline at end of file +} From 08128c0cccd10b9d07aa1288bba64117eb024878 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 22:54:56 +0000 Subject: [PATCH 18/53] include decoupler to subworkflow meta.yml --- .../meta.yml | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/meta.yml b/subworkflows/nf-core/differential_functional_enrichment/meta.yml index dc1f80997018..c1762ec73df6 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/meta.yml +++ b/subworkflows/nf-core/differential_functional_enrichment/meta.yml @@ -8,6 +8,7 @@ keywords: components: - gprofiler2/gost - gsea/gsea + - decoupler/decoupler - propr/grea - custom/tabulartogseagct - custom/tabulartogseacls @@ -35,7 +36,7 @@ input: For the moment, it is only required for gprofiler2. - analysis_method: type: value - description: Analysis method (gprofiler2, gsea, or grea) + description: Analysis method (gprofiler2, gsea, decoupler or grea) - ch_contrasts: description: Channel with contrast information structure: @@ -145,6 +146,47 @@ output: type: file description: Main TSV results report file for the target group. pattern: "*gsea_report_for_${target}.tsv" + - decoupler_dc_estimate: + description: Channel containing decoupler estimate results. + structure: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:‘test’, single_end ] + - "*estimate_decoupler.tsv": + type: file + description: | + The file containing the estimation results of the enrichment(s) + pattern: "*estimate_decoupler.tsv" + - decoupler_dc_pvals: + description: Channel containing decoupler pvals results. + structure: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:‘test’, single_end ] + - "*pvals_decoupler.tsv": + type: file + description: | + The file containing the p-value associated to the estimation + results of the enrichment(s) + pattern: "*pvals_decoupler.tsv" + - decoupler_png: + description: Channel containing decoupler png results. + structure: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:‘test’, single_end ] + - "*estimate_decoupler_plot.png": + type: file + description: | + The file containing the plots associated to the estimation + results of the enrichment(s) + pattern: "*estimate_decoupler_plot.png" - grea_results: description: | Channel containing the output from GREA. From 5d4f199f82c809c492c31503754c9c264ba99f3d Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 23:01:44 +0000 Subject: [PATCH 19/53] fix syntax error --- .../nf-core/differential_functional_enrichment/meta.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/meta.yml b/subworkflows/nf-core/differential_functional_enrichment/meta.yml index c1762ec73df6..16927f0a254b 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/meta.yml +++ b/subworkflows/nf-core/differential_functional_enrichment/meta.yml @@ -152,8 +152,8 @@ output: - meta: type: map description: | - Groovy Map containing sample information - e.g. [ id:‘test’, single_end ] + Groovy Map containing sample information + e.g. [ id:'test', single_end ] - "*estimate_decoupler.tsv": type: file description: | @@ -166,7 +166,7 @@ output: type: map description: | Groovy Map containing sample information - e.g. [ id:‘test’, single_end ] + e.g. [ id:'test', single_end ] - "*pvals_decoupler.tsv": type: file description: | @@ -180,7 +180,7 @@ output: type: map description: | Groovy Map containing sample information - e.g. [ id:‘test’, single_end ] + e.g. [ id:'test', single_end ] - "*estimate_decoupler_plot.png": type: file description: | From 595ccef17dfb52fbdef51619d94edeb52f01a9fe Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 23:10:16 +0000 Subject: [PATCH 20/53] add decoupler/decoupler tag --- .../differential_functional_enrichment/tests/main.nf.test | 1 + 1 file changed, 1 insertion(+) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index 83c8faee5d80..cd5d79db0b3f 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -20,6 +20,7 @@ nextflow_workflow { tag "subworkflows/abundance_differential_filter" tag "abundance_differential_filter" tag "decoupler_basic" + tag "decoupler/decoupler" test("test gprofiler2 - mouse") { tag 'gprofiler2_basic' From 9adfd40681a492705ecb1bade36bb4d9a0b86802 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 23:10:25 +0000 Subject: [PATCH 21/53] fix syntax issue --- .../meta.yml | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/meta.yml b/subworkflows/nf-core/differential_functional_enrichment/meta.yml index 16927f0a254b..37e672ca006c 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/meta.yml +++ b/subworkflows/nf-core/differential_functional_enrichment/meta.yml @@ -61,7 +61,7 @@ input: type: list description: List of contrast formula - comparison: - type list: + type: list description: List of contrast comparison - ch_samplesheet: description: Channel with sample information @@ -105,11 +105,12 @@ output: description: Metadata map - all_enrich: type: file - description: table listing all enriched pathways that were found by gprofiler2. + description: | + Table listing all enriched pathways that were found by gprofiler2. It can be empty, if none is found. pattern: "*.gprofiler2.all_enriched_pathways.tsv" - gprofiler2_sub_enrich: - description: Channel containing the secondary enrichment table output from gprofiler. + description: Channel containing the secondary enrichment table output from gprofiler2. structure: - meta: type: map @@ -117,7 +118,7 @@ output: - sub_enrich: type: file description: | - table listing enriched pathways that were found from one particular source. + Table listing enriched pathways that were found from one particular source. Note that it will only be created if any were found. pattern: "*.gprofiler2.*.sub_enriched_pathways.tsv" - gprofiler2_plot_html: @@ -129,7 +130,7 @@ output: - plot_html: type: file description: | - Channel containing HTML file; interactive Manhattan plot of all enriched pathways. + HTML file; interactive Manhattan plot of all enriched pathways. Note that this file will only be generated if enriched pathways were found. pattern: "*.gprofiler2.gostplot.html" - gsea_report: @@ -154,10 +155,10 @@ output: description: | Groovy Map containing sample information e.g. [ id:'test', single_end ] - - "*estimate_decoupler.tsv": + - estimate_files: type: file description: | - The file containing the estimation results of the enrichment(s) + Files containing the estimation results of the enrichment(s) pattern: "*estimate_decoupler.tsv" - decoupler_dc_pvals: description: Channel containing decoupler pvals results. @@ -167,10 +168,10 @@ output: description: | Groovy Map containing sample information e.g. [ id:'test', single_end ] - - "*pvals_decoupler.tsv": + - pvals_files: type: file description: | - The file containing the p-value associated to the estimation + Files containing the p-values associated to the estimation results of the enrichment(s) pattern: "*pvals_decoupler.tsv" - decoupler_png: @@ -181,15 +182,14 @@ output: description: | Groovy Map containing sample information e.g. [ id:'test', single_end ] - - "*estimate_decoupler_plot.png": + - plot_files: type: file description: | - The file containing the plots associated to the estimation + Files containing the plots associated to the estimation results of the enrichment(s) pattern: "*estimate_decoupler_plot.png" - grea_results: - description: | - Channel containing the output from GREA. + description: Channel containing the output from GREA. structure: - meta: type: map From a1f6990f9d61481130092336ae40ba333035ab1b Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Wed, 13 Aug 2025 23:13:16 +0000 Subject: [PATCH 22/53] fix component --- .../nf-core/differential_functional_enrichment/meta.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/meta.yml b/subworkflows/nf-core/differential_functional_enrichment/meta.yml index 37e672ca006c..0882d4b55f03 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/meta.yml +++ b/subworkflows/nf-core/differential_functional_enrichment/meta.yml @@ -8,7 +8,7 @@ keywords: components: - gprofiler2/gost - gsea/gsea - - decoupler/decoupler + - decoupler - propr/grea - custom/tabulartogseagct - custom/tabulartogseacls From 323bea39f5e5691d8e3afb7f5a995b75615b97ce Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Thu, 14 Aug 2025 00:46:51 +0000 Subject: [PATCH 23/53] Upgrade decoupler output assertion --- .../tests/main.nf.test | 16 ++++-- .../tests/main.nf.test.snap | 55 +++++++------------ 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index cd5d79db0b3f..1910c8c122c7 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -508,11 +508,19 @@ nextflow_workflow { then { assertAll( { assert workflow.success }, + { assert workflow.out.decoupler_dc_estimate.size() > 0 }, + { assert workflow.out.decoupler_dc_pvals.size() > 0 }, + { assert workflow.out.decoupler_png.size() > 0 }, { assert snapshot( - workflow.out.decoupler_dc_estimate, - workflow.out.decoupler_dc_pvals, - workflow.out.decoupler_png, - path(workflow.out.versions.get(0)).yaml, + workflow.out.decoupler_dc_estimate.collect { meta, files -> + [meta.id, files.collect { path(it).getFileName().toString() }.sort()] + }, + workflow.out.decoupler_dc_pvals.collect { meta, files -> + [meta.id, files.collect { path(it).getFileName().toString() }.sort()] + }, + workflow.out.decoupler_png.collect { meta, files -> + [meta.id, files.collect { path(it).getFileName().toString() }.sort()] + }, workflow.out.versions ).match() } ) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 8fb0b7d4e496..1fa63b402040 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -357,44 +357,31 @@ "content": [ [ [ - { - "id": "treatment_mCherry_hND6", - "method_differential": "deseq2" - }, + "treatment_mCherry_hND6", [ - "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler.tsv:md5,a4f145de6d86d6d77b90d2058225ae65", - "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler.tsv:md5,78395931b16c735f2c345ec087ce5bf2" + "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler.tsv", + "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler.tsv" ] ] ], [ [ - { - "id": "treatment_mCherry_hND6", - "method_differential": "deseq2" - }, + "treatment_mCherry_hND6", [ - "deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler.tsv:md5,a9cae76e3d053e497682de78682e3ab1", - "deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler.tsv:md5,bdf43423d8b3064acc950206687507d5" + "deseq2_treatment_mCherry_hND6_consensus_pvals_decoupler.tsv", + "deseq2_treatment_mCherry_hND6_mlm_pvals_decoupler.tsv" ] ] ], [ [ - { - "id": "treatment_mCherry_hND6", - "method_differential": "deseq2" - }, + "treatment_mCherry_hND6", [ - "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png:md5,b651ed914213b44ab79851c39f5339f4", - "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png:md5,3e3f449c8605e08084f533a4e9996e27" + "deseq2_treatment_mCherry_hND6_consensus_estimate_decoupler_plot.png", + "deseq2_treatment_mCherry_hND6_mlm_estimate_decoupler_plot.png" ] ] ], - { - "DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:DECOUPLER": null, - "decoupler-py": "1.8.0" - }, [ "versions.yml:md5,d268550490df4c6a9e58baa7d08b93e6" ] @@ -403,7 +390,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-13T22:19:19.97696954" + "timestamp": "2025-08-14T00:38:07.013260339" }, "deseq2 + gsea - mouse": { "content": [ @@ -499,31 +486,31 @@ ] ], "3": [ - + ], "4": [ - + ], "5": [ - + ], "6": [ - + ], "7": [ - + ], "8": [ "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" ], "decoupler_dc_estimate": [ - + ], "decoupler_dc_pvals": [ - + ], "decoupler_png": [ - + ], "gprofiler2_all_enrich": [ [ @@ -565,10 +552,10 @@ ] ], "grea_results": [ - + ], "gsea_report": [ - + ], "versions": [ "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" @@ -581,4 +568,4 @@ }, "timestamp": "2025-08-13T22:09:24.891941865" } -} +} \ No newline at end of file From cd31720b15e4795fd794147c89584ebc7b420fd3 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Thu, 14 Aug 2025 01:39:01 +0000 Subject: [PATCH 24/53] Improve format validation for annotation tsv file --- .../decoupler/decoupler/templates/decoupler.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index 25f708dd2489..4c6944f2a811 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -50,14 +50,23 @@ def parse_ext_args(args_string: str): if parsed_args.ensembl_ids.upper() == "TRUE": try: + if not os.path.exists("${annot}"): + raise FileNotFoundError(f"Annotation file not found: ${annot}") + annot_df = pd.read_csv("${annot}", sep="\t") + + required_cols = {"gene_id", "gene_name"} + missing = required_cols - set(annot_df.columns) + if missing: + raise ValueError(f"Missing required columns in annotation file: {missing}. Available columns: {list(annot_df.columns)}") + gene_mapping = dict(zip(annot_df["gene_id"], annot_df["gene_name"])) new_index = [gene_mapping.get(ens, None) for ens in mat.index] mat.index = new_index mat = mat[mat.index.notnull()] mat = mat[~mat.index.duplicated(keep='first')] except Exception as e: - print("Expected format: tsv file with at least two columns with gene_id and gene_name headers. ERROR: Failed to read annotation file:", e) + print(f"ERROR: Failed to process annotation file: {e}") sys.exit(1) if parsed_args.transpose.upper() == "TRUE": From a1e70bab35514d06232b717def68d4b41340198b Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:36:01 +0000 Subject: [PATCH 25/53] Include meta for all decoupler inputs --- modules/nf-core/decoupler/decoupler/main.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index e95505dcf99b..b3f06654ab4e 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -8,8 +8,8 @@ process DECOUPLER { input: tuple val(meta), path(mat) - path(net) - path(annot) + tuple val(meta2), path(net) + tuple val(meta3), path(annot) output: tuple val(meta), path("*estimate_decoupler.tsv"), emit: dc_estimate From 887d4a646e756783cbbd0e411ac285abeb084e28 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:36:19 +0000 Subject: [PATCH 26/53] Update decoupler test with new meta input requirement --- .../decoupler/decoupler/tests/main.nf.test | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test b/modules/nf-core/decoupler/decoupler/tests/main.nf.test index feaef0048ef3..4acf725623d7 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test @@ -23,9 +23,12 @@ nextflow_process { file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/treatment_mCherry_hND6_.deseq2.results.tsv", checkIfExists: true) ] input[1] = [ + ['id':'network'], file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [ + ['id':'annot'], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -73,9 +76,12 @@ nextflow_process { file(params.test_data['generic']['tsv']['expression'], checkIfExists: true) ] input[1] = [ + ['id':'network'], file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [ + ['id':'annot'], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -123,9 +129,12 @@ nextflow_process { file(params.test_data['generic']['tsv']['expression'], checkIfExists: true) ] input[1] = [ + ['id':'network'], file(params.test_data['generic']['tsv']['network'], checkIfExists: true) ] - input[2] = [file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + input[2] = [ + ['id':'annot'], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } From bb04579583e8bd0decbd004ad868bbbeb2f3db81 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:37:02 +0000 Subject: [PATCH 27/53] Fix decoupler input channels --- .../main.nf | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 890c013dd50a..446e52117c44 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -81,24 +81,6 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { .combine(ch_contrasts_transposed, by:0) .multiMap(criteria) - // In the case of DECOUPLER, it needs additional files coming from other channels that other methods don't use - // here we define the input channel for the DECOUPLER section - - ch_input_for_decoupler = ch_input_for_other.input - .filter{ it[0].functional_method == 'decoupler' } - .map { meta, differential_results -> - // Preserve the method_differential field from the original metadata - def new_meta = [ - id: meta.id, - method_differential: meta.params.differential_method - ] - [new_meta, differential_results] - } - ch_decoupler_network = ch_input_for_other.input - .filter{ it[0].functional_method == 'decoupler' } - .map { meta, differential_results -> - meta.params.decoupler_network ? file(meta.params.decoupler_network, checkIfExists: true) : [] - } // ---------------------------------------------------- // Perform enrichment analysis with gprofiler2 @@ -139,10 +121,11 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // ---------------------------------------------------- // Perform enrichment analysis with DECOUPLER // ---------------------------------------------------- + DECOUPLER( - ch_input_for_decoupler, - ch_decoupler_network, - ch_featuresheet.map{ meta, features, features_id, features_symbol -> features } + ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, + ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, + ch_featuresheet.map{ meta, features, features_id, features_symbol -> [meta, features] } ) // ---------------------------------------------------- From 45f36e6058b0c5a3148c465f87159f7379d8787e Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:37:16 +0000 Subject: [PATCH 28/53] Update decoupler prefix --- .../tests/decoupler.config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config index d050cc3d281d..944e0567cf80 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config @@ -5,7 +5,11 @@ params { process { withName: 'DECOUPLER' { - ext.prefix = { "${meta.method_differential}_${meta.id}" } + ext.prefix = { + def method = meta.params.differential_method ?: meta.differential_method ?: "unknown" + def prefix = "${method}_${meta.id}" + return prefix + } ext.args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm" } } From b791daa1b6753ecd6b1eb967c4567b805aab3c3a Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:37:32 +0000 Subject: [PATCH 29/53] Update decoupler test with new input channels --- .../differential_functional_enrichment/tests/main.nf.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index 1910c8c122c7..51d484d8fc32 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -478,12 +478,11 @@ nextflow_workflow { 'id':'treatment_mCherry_hND6', 'method_differential':'deseq2', 'params': [ - 'decoupler_network': 'https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv', 'differential_method': 'deseq2' ] ], file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/treatment_mCherry_hND6_.deseq2.results.tsv", checkIfExists: true), - [], // genesets (empty for decoupler) + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true), // network file as genesets [], // background (empty for decoupler) 'decoupler' // method ]) From 7062ed9bf3eb85fe5c1c50a7ced87cb3d30ef1f6 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 15 Aug 2025 21:37:47 +0000 Subject: [PATCH 30/53] Update snapshot --- .../differential_functional_enrichment/tests/main.nf.test.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 1fa63b402040..1a92071eb4a5 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -390,7 +390,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-14T00:38:07.013260339" + "timestamp": "2025-08-15T21:34:27.044413972" }, "deseq2 + gsea - mouse": { "content": [ From 4ad16ef5b1a320ef1557117ca11b87e76e8b14b5 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Sun, 17 Aug 2025 17:45:32 +0000 Subject: [PATCH 31/53] add meta for net and annot inputs --- modules/nf-core/decoupler/decoupler/meta.yml | 44 +++++++++++--------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/meta.yml b/modules/nf-core/decoupler/decoupler/meta.yml index 7e791ff14c79..fb20282e1872 100644 --- a/modules/nf-core/decoupler/decoupler/meta.yml +++ b/modules/nf-core/decoupler/decoupler/meta.yml @@ -41,25 +41,31 @@ input: pattern: "*.tsv" ontologies: - edam: http://edamontology.org/format_3475 # TSV - - net: - type: file - description: | - The prior knowledge network linking the features of the - expression matrix to a process/component (e.g. gene set, - transcription factor, kinase, etc.) - pattern: "*.tsv" - ontologies: - - edam: http://edamontology.org/format_3475 # TSV - - annot: - type: file - description: | - Annotation file in TSV format containing gene ID to gene name mappings. - Used specifically for mapping Ensembl IDs to gene names. - Expected format: two columns with gene_id and gene_name headers. - pattern: "*.tsv" - required: false - ontologies: - - edam: http://edamontology.org/format_3475 # TSV + - - meta2: + type: map + description: Groovy map + - net: + type: file + description: | + The prior knowledge network linking the features of the + expression matrix to a process/component (e.g. gene set, + transcription factor, kinase, etc.) + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - - meta3: + type: map + description: Groovy map + - annot: + type: file + description: | + Annotation file in TSV format containing gene ID to gene name mappings. + Used specifically for mapping Ensembl IDs to gene names. + Expected format: two columns with gene_id and gene_name headers. + pattern: "*.tsv" + required: false + ontologies: + - edam: http://edamontology.org/format_3475 # TSV output: dc_estimate: - - meta: From 015248f378542093d9321eb9542df6623932ccff Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 25 Aug 2025 18:43:35 +0000 Subject: [PATCH 32/53] Include method differential to stub results to avoid null names --- modules/nf-core/decoupler/decoupler/main.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index b3f06654ab4e..8d7c5e713b26 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -25,9 +25,9 @@ process DECOUPLER { stub: """ - touch ${task.ext.prefix}_estimate_decoupler.tsv - touch ${task.ext.prefix}_pvals_decoupler.tsv - touch ${task.ext.prefix}_estimate_decoupler_plot.png + touch deseq2_estimate_decoupler.tsv + touch deseq2_pvals_decoupler.tsv + touch deseq2_estimate_decoupler_plot.png touch versions.yml """ } From 4e9f96604c28aa6cec52c0ef67647790feae5a1f Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 25 Aug 2025 18:53:59 +0000 Subject: [PATCH 33/53] Add method differential to stub results to avoid null --- .../decoupler/decoupler/tests/main.nf.test.snap | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap b/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap index 713ead476f37..cdc1a1999472 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test.snap @@ -36,7 +36,7 @@ { "id": "test" }, - "null_test_estimate_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_estimate_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ @@ -44,7 +44,7 @@ { "id": "test" }, - "null_test_pvals_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_pvals_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "2": [ @@ -52,7 +52,7 @@ { "id": "test" }, - "null_test_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "3": [ @@ -63,7 +63,7 @@ { "id": "test" }, - "null_test_estimate_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_estimate_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "dc_pvals": [ @@ -71,7 +71,7 @@ { "id": "test" }, - "null_test_pvals_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_pvals_decoupler.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "png": [ @@ -79,7 +79,7 @@ { "id": "test" }, - "null_test_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" + "deseq2_estimate_decoupler_plot.png:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "versions": [ @@ -91,7 +91,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-12T18:45:09.567512573" + "timestamp": "2025-08-25T18:51:20.453145611" }, "decoupler_test": { "content": [ From e0318a3962658cef8cf7c9dfa3d7288ee5646023 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 01:09:55 +0000 Subject: [PATCH 34/53] Include ch_featuresheet into ch_input_for_other --- .../nf-core/differential_functional_enrichment/main.nf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 446e52117c44..62c01381cde6 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -40,8 +40,9 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // Also, reorganize the structure to match them with the modules' input organization ch_input_for_other = ch_input + .join(ch_featuresheet, by: 0) .multiMap { - meta, file, genesets, background, method -> + meta, file, genesets, background, method, features_sheet, features_id, features_symbol -> def meta_with_method = meta + [ 'functional_method': method ] input: [ meta_with_method, file ] @@ -49,8 +50,10 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { [ meta_with_method, genesets ] background: [ meta_with_method, background ] + featuresheet: + [ meta_with_method, features_sheet] } - + // In the case of GSEA, it needs additional files coming from other channels that other methods don't use // here we define the input channel for the GSEA section @@ -125,7 +128,7 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { DECOUPLER( ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, - ch_featuresheet.map{ meta, features, features_id, features_symbol -> [meta, features] } + ch_input_for_other.featuresheet.filter{ it[0].functional_method == 'decoupler'} ) // ---------------------------------------------------- From b43aea40f0df9c9a04b8757b38e25c74b5ca7d7c Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 01:35:44 +0000 Subject: [PATCH 35/53] Separate channel for other and channel for decoupler including features to not disturb other profiles tests --- .../main.nf | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 62c01381cde6..878e8721ee75 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -40,6 +40,19 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // Also, reorganize the structure to match them with the modules' input organization ch_input_for_other = ch_input + .multiMap { + meta, file, genesets, background, method -> + def meta_with_method = meta + [ 'functional_method': method ] + input: + [ meta_with_method, file ] + genesets: + [ meta_with_method, genesets ] + background: + [ meta_with_method, background ] + + } + + ch_input_for_decoupler = ch_input .join(ch_featuresheet, by: 0) .multiMap { meta, file, genesets, background, method, features_sheet, features_id, features_symbol -> @@ -50,10 +63,9 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { [ meta_with_method, genesets ] background: [ meta_with_method, background ] - featuresheet: + features: [ meta_with_method, features_sheet] } - // In the case of GSEA, it needs additional files coming from other channels that other methods don't use // here we define the input channel for the GSEA section @@ -126,9 +138,9 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // ---------------------------------------------------- DECOUPLER( - ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, - ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, - ch_input_for_other.featuresheet.filter{ it[0].functional_method == 'decoupler'} + ch_input_for_decoupler.input.filter{ it[0].functional_method == 'decoupler' }, + ch_input_for_decoupler.genesets.filter{ it[0].functional_method == 'decoupler'}, + ch_input_for_decoupler.features.filter{ it[0].functional_method == 'decoupler'} ) // ---------------------------------------------------- From 9a54972bce4e402c5d2a2f74057ddb8714de0596 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 02:10:35 +0000 Subject: [PATCH 36/53] update decoupler test --- .../tests/main.nf.test | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index 51d484d8fc32..0aed00fba4c7 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -490,10 +490,16 @@ nextflow_workflow { ch_contrasts = Channel.of([[], [], [], [], [], []]) ch_samplesheet = Channel.of([[], []]) ch_featuresheet = Channel.of([ - [], + [ + 'id':'treatment_mCherry_hND6', + 'method_differential':'deseq2', + 'params': [ + 'differential_method': 'deseq2' + ] + ], file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/differentialabundance/modules_testdata/Mus_musculus.anno.tsv", checkIfExists: true), - [], - [] + 'gene_id', // features_id + 'gene_name' // features_symbol ]) input[0] = ch_input From 4dc74a412f2b73f753e210cdb2bc69295d74c285 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 02:42:58 +0000 Subject: [PATCH 37/53] Remove hardcode of gene_id and gene_name columns --- modules/nf-core/decoupler/decoupler/main.nf | 2 +- modules/nf-core/decoupler/decoupler/templates/decoupler.py | 5 +++-- .../nf-core/differential_functional_enrichment/main.nf | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index 8d7c5e713b26..6649de102364 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -9,7 +9,7 @@ process DECOUPLER { input: tuple val(meta), path(mat) tuple val(meta2), path(net) - tuple val(meta3), path(annot) + tuple val(meta3), path(annot), val(features_id), val(features_symbol) output: tuple val(meta), path("*estimate_decoupler.tsv"), emit: dc_estimate diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index 4c6944f2a811..5c7dc5706f27 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -55,12 +55,13 @@ def parse_ext_args(args_string: str): annot_df = pd.read_csv("${annot}", sep="\t") - required_cols = {"gene_id", "gene_name"} + required_cols = {"${features_id}", "${features_symbol}"} + missing = required_cols - set(annot_df.columns) if missing: raise ValueError(f"Missing required columns in annotation file: {missing}. Available columns: {list(annot_df.columns)}") - gene_mapping = dict(zip(annot_df["gene_id"], annot_df["gene_name"])) + gene_mapping = dict(zip(annot_df["${features_id}"], annot_df["${features_symbol}"])) new_index = [gene_mapping.get(ens, None) for ens in mat.index] mat.index = new_index mat = mat[mat.index.notnull()] diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 878e8721ee75..d4fa856ca111 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -64,7 +64,7 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { background: [ meta_with_method, background ] features: - [ meta_with_method, features_sheet] + [ meta_with_method, features_sheet, features_id, features_symbol] } // In the case of GSEA, it needs additional files coming from other channels that other methods don't use // here we define the input channel for the GSEA section From bb5f16b8e495d6c8c9ea52b898c75496f1ddd646 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 02:49:14 +0000 Subject: [PATCH 38/53] update decoupler meta.yml --- modules/nf-core/decoupler/decoupler/meta.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/nf-core/decoupler/decoupler/meta.yml b/modules/nf-core/decoupler/decoupler/meta.yml index fb20282e1872..2b25a4f32f3b 100644 --- a/modules/nf-core/decoupler/decoupler/meta.yml +++ b/modules/nf-core/decoupler/decoupler/meta.yml @@ -66,6 +66,18 @@ input: required: false ontologies: - edam: http://edamontology.org/format_3475 # TSV + - features_id: + type: string + description: | + Column name in the annotation file containing the feature identifiers + (e.g., 'gene_id', 'protein_id', 'metabolite_id') + required: true + - features_symbol: + type: string + description: | + Column name in the annotation file containing the feature symbols/names + (e.g., 'gene_name', 'protein_name', 'metabolite_name') + required: true output: dc_estimate: - - meta: From 9994318a195d55b0d73cbce3f463d860cbfef18d Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 03:02:25 +0000 Subject: [PATCH 39/53] update decoupler test --- .../nf-core/decoupler/decoupler/tests/main.nf.test | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test b/modules/nf-core/decoupler/decoupler/tests/main.nf.test index 4acf725623d7..85c991a299eb 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test @@ -28,7 +28,9 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), + 'gene_id', + 'gene_name'] """ } } @@ -81,7 +83,9 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), + 'gene_id', + 'gene_name'] """ } } @@ -134,7 +138,9 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), + 'gene_id', + 'gene_name'] """ } } From eb0adaa1ef304d4542daadb91629c6648f4d271d Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 20:40:09 +0000 Subject: [PATCH 40/53] Fix: Remove features id and symbol from decoupler meta.yml --- modules/nf-core/decoupler/decoupler/meta.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/meta.yml b/modules/nf-core/decoupler/decoupler/meta.yml index 2b25a4f32f3b..fb20282e1872 100644 --- a/modules/nf-core/decoupler/decoupler/meta.yml +++ b/modules/nf-core/decoupler/decoupler/meta.yml @@ -66,18 +66,6 @@ input: required: false ontologies: - edam: http://edamontology.org/format_3475 # TSV - - features_id: - type: string - description: | - Column name in the annotation file containing the feature identifiers - (e.g., 'gene_id', 'protein_id', 'metabolite_id') - required: true - - features_symbol: - type: string - description: | - Column name in the annotation file containing the feature symbols/names - (e.g., 'gene_name', 'protein_name', 'metabolite_name') - required: true output: dc_estimate: - - meta: From 9b5ef028add31e5a309ec0056da236891c8b4e49 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 20:40:21 +0000 Subject: [PATCH 41/53] Fix: Remove features id and symbol from decoupler input --- modules/nf-core/decoupler/decoupler/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/decoupler/decoupler/main.nf b/modules/nf-core/decoupler/decoupler/main.nf index 6649de102364..8d7c5e713b26 100644 --- a/modules/nf-core/decoupler/decoupler/main.nf +++ b/modules/nf-core/decoupler/decoupler/main.nf @@ -9,7 +9,7 @@ process DECOUPLER { input: tuple val(meta), path(mat) tuple val(meta2), path(net) - tuple val(meta3), path(annot), val(features_id), val(features_symbol) + tuple val(meta3), path(annot) output: tuple val(meta), path("*estimate_decoupler.tsv"), emit: dc_estimate From 1437782d0bf824fc90ca1e17db1412cc5b8564ac Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 20:40:45 +0000 Subject: [PATCH 42/53] Fix: Take features id and symbol as external arguments --- modules/nf-core/decoupler/decoupler/templates/decoupler.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index 5c7dc5706f27..f7ca4a0f5205 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -41,6 +41,8 @@ def parse_ext_args(args_string: str): parser.add_argument("--column", type=str, default="log2FoldChange", help="Column name to use for transposition") parser.add_argument("--ensembl_ids", type=str, default="FALSE", help="Convert ENSEMBL IDs to gene symbols if TRUE") parser.add_argument("--methods", type=str, default = "ulm", help="Comma-separated list of methods to use (e.g., 'mlm,ulm')") + parser.add_argument("--features_id_col", type=str, default="gene_id", help="Column name for feature IDs") + parser.add_argument("--features_symbol_col", type=str, default="gene_name", help="Column name for feature symbols") return parser.parse_args(args_list) # Parse external arguments @@ -55,13 +57,13 @@ def parse_ext_args(args_string: str): annot_df = pd.read_csv("${annot}", sep="\t") - required_cols = {"${features_id}", "${features_symbol}"} + required_cols = {parsed_args.features_id_col, parsed_args.features_symbol_col} missing = required_cols - set(annot_df.columns) if missing: raise ValueError(f"Missing required columns in annotation file: {missing}. Available columns: {list(annot_df.columns)}") - gene_mapping = dict(zip(annot_df["${features_id}"], annot_df["${features_symbol}"])) + gene_mapping = dict(zip(annot_df[parsed_args.features_id_col], annot_df[parsed_args.features_symbol_col])) new_index = [gene_mapping.get(ens, None) for ens in mat.index] mat.index = new_index mat = mat[mat.index.notnull()] From abbfed230f6b03cfcf7b8b557ce5aa3dfdf34d32 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 20:41:05 +0000 Subject: [PATCH 43/53] Fix: Take features id and symbol as external arguments --- .../tests/decoupler.config | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config index 944e0567cf80..395d4bb592bd 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config @@ -10,6 +10,13 @@ process { def prefix = "${method}_${meta.id}" return prefix } - ext.args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm" + ext.args = { + def features_id = meta.params?.features_id_col ?: 'gene_id' + def features_symbol = meta.params?.features_name_col ?: 'gene_name' + def min_n = meta.params?.decoupler_min_n ?: 5 + def methods = meta.params?.decoupler_methods ?: 'ulm' + + "--min_n ${min_n} --transpose TRUE --ensembl_ids TRUE --methods ${methods} --features_id_col ${features_id} --features_symbol_col ${features_symbol}" + } } } From fe99b36325d39dca05293e3774b512f3127769a5 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 20:41:27 +0000 Subject: [PATCH 44/53] Fix: Take features id and symbol as external arguments --- .../decoupler/decoupler/tests/main.nf.test | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/tests/main.nf.test b/modules/nf-core/decoupler/decoupler/tests/main.nf.test index 85c991a299eb..9e1b826e541e 100644 --- a/modules/nf-core/decoupler/decoupler/tests/main.nf.test +++ b/modules/nf-core/decoupler/decoupler/tests/main.nf.test @@ -14,7 +14,7 @@ nextflow_process { when { params { - module_args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm" + module_args = "--min_n 2 --transpose TRUE --ensembl_ids TRUE --methods mlm --features_id_col gene_id --features_symbol_col gene_name" } process { """ @@ -28,9 +28,7 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), - 'gene_id', - 'gene_name'] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -68,7 +66,7 @@ nextflow_process { when { params { - module_args = "--min_n 1" + module_args = "--min_n 1 --features_id_col gene_id --features_symbol_col gene_name" } process { @@ -83,9 +81,7 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), - 'gene_id', - 'gene_name'] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } @@ -124,7 +120,7 @@ nextflow_process { when { params { - module_args = "--min_n 1" + module_args = "--min_n 1 --features_id_col gene_id --features_symbol_col gene_name" } process { """ @@ -138,9 +134,7 @@ nextflow_process { ] input[2] = [ ['id':'annot'], - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true), - 'gene_id', - 'gene_name'] + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/Mus_musculus.anno.feature_metadata.tsv", checkIfExists: true)] """ } } From f9b8cb2d717ec70b4a69cb54d493cc797cac4d6f Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 21:24:03 +0000 Subject: [PATCH 45/53] Fix: remove ch_input_for_decoupler --- .../main.nf | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index d4fa856ca111..ea9e4fa75d96 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -40,19 +40,6 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // Also, reorganize the structure to match them with the modules' input organization ch_input_for_other = ch_input - .multiMap { - meta, file, genesets, background, method -> - def meta_with_method = meta + [ 'functional_method': method ] - input: - [ meta_with_method, file ] - genesets: - [ meta_with_method, genesets ] - background: - [ meta_with_method, background ] - - } - - ch_input_for_decoupler = ch_input .join(ch_featuresheet, by: 0) .multiMap { meta, file, genesets, background, method, features_sheet, features_id, features_symbol -> @@ -138,9 +125,11 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // ---------------------------------------------------- DECOUPLER( - ch_input_for_decoupler.input.filter{ it[0].functional_method == 'decoupler' }, - ch_input_for_decoupler.genesets.filter{ it[0].functional_method == 'decoupler'}, - ch_input_for_decoupler.features.filter{ it[0].functional_method == 'decoupler'} + ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, + ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, + ch_input_for_other.features.filter{ it[0].functional_method == 'decoupler'} + .map{ meta, features_sheet, features_id, features_symbol -> [meta, features_sheet] + } ) // ---------------------------------------------------- From 9fb43a24f675e5793e972205cd41e4465477439b Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 21:24:21 +0000 Subject: [PATCH 46/53] correct method --- .../differential_functional_enrichment/tests/decoupler.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config index 395d4bb592bd..763d65ae6deb 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config @@ -14,7 +14,7 @@ process { def features_id = meta.params?.features_id_col ?: 'gene_id' def features_symbol = meta.params?.features_name_col ?: 'gene_name' def min_n = meta.params?.decoupler_min_n ?: 5 - def methods = meta.params?.decoupler_methods ?: 'ulm' + def methods = meta.params?.decoupler_methods ?: 'mlm' "--min_n ${min_n} --transpose TRUE --ensembl_ids TRUE --methods ${methods} --features_id_col ${features_id} --features_symbol_col ${features_symbol}" } From 363e41e457165ade9195a20306d89d588cb9dfb9 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Tue, 26 Aug 2025 21:35:01 +0000 Subject: [PATCH 47/53] Update: update nf-test to work with new input channel --- .../tests/main.nf.test | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index 0aed00fba4c7..a2c3c9af74e6 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -41,7 +41,12 @@ nextflow_workflow { input[0] = ch_input input[1] = Channel.of([[], [], [], [], [], []]) input[2] = Channel.of([[], []]) - input[3] = Channel.of([[], [], [], []]) + input[3] = Channel.of([ + ['id':'Condition_genotype_WT_KO', 'variable':'Condition genotype', 'reference':'WT', 'target':'KO', 'blocking':'batch'], + [], // + '', // + '' // + ]) """ } } @@ -116,10 +121,15 @@ nextflow_workflow { [meta, results, [], [], 'gprofiler2'] } + ch_featuresheet = ch_input + .map { meta, file, genesets, background, method -> + [meta, [], '', ''] + } + input[0] = ch_input input[1] = Channel.of([[], [], [], [], [], []]) input[2] = Channel.of([[], []]) - input[3] = Channel.of([[], [], [], []]) + input[3] = ch_featuresheet """ } } @@ -305,11 +315,14 @@ nextflow_workflow { .map { meta, results, genesets -> [meta, results, genesets, [], 'grea'] } - + ch_featuresheet = ch_input + .map { meta, file, genesets, background, method -> + [meta, [], '', ''] + } input[0] = ch_input input[1] = Channel.of([[], [], [], [], [], []]) input[2] = Channel.of([[], []]) - input[3] = Channel.of([[], [], [], []]) + input[3] = ch_featuresheet """ } } @@ -482,9 +495,9 @@ nextflow_workflow { ] ], file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/treatment_mCherry_hND6_.deseq2.results.tsv", checkIfExists: true), - file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true), // network file as genesets - [], // background (empty for decoupler) - 'decoupler' // method + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/progeny/mouse_network.tsv", checkIfExists: true), + [], + 'decoupler' ]) ch_contrasts = Channel.of([[], [], [], [], [], []]) @@ -498,8 +511,8 @@ nextflow_workflow { ] ], file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/differentialabundance/modules_testdata/Mus_musculus.anno.tsv", checkIfExists: true), - 'gene_id', // features_id - 'gene_name' // features_symbol + 'gene_id', + 'gene_name' ]) input[0] = ch_input @@ -551,7 +564,12 @@ nextflow_workflow { input[0] = ch_input input[1] = Channel.of([[], [], [], [], [], []]) input[2] = Channel.of([[], []]) - input[3] = Channel.of([[], [], [], []]) + input[3] = Channel.of([ + ['id':'Condition_genotype_WT_KO', 'variable':'Condition genotype', 'reference':'WT', 'target':'KO', 'blocking':'batch'], + [], + '', + '' + ]) """ } } From 24a1f74fa87902031d6432169863d0e149353c00 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 1 Sep 2025 02:00:07 +0000 Subject: [PATCH 48/53] Fix: change method --- .../differential_functional_enrichment/tests/decoupler.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config index 395d4bb592bd..763d65ae6deb 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/decoupler.config @@ -14,7 +14,7 @@ process { def features_id = meta.params?.features_id_col ?: 'gene_id' def features_symbol = meta.params?.features_name_col ?: 'gene_name' def min_n = meta.params?.decoupler_min_n ?: 5 - def methods = meta.params?.decoupler_methods ?: 'ulm' + def methods = meta.params?.decoupler_methods ?: 'mlm' "--min_n ${min_n} --transpose TRUE --ensembl_ids TRUE --methods ${methods} --features_id_col ${features_id} --features_symbol_col ${features_symbol}" } From 36b354c8c682022764ee686c1989e3ff9cbde7ea Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 1 Sep 2025 02:00:52 +0000 Subject: [PATCH 49/53] Fix: update ch_input_for_other channel to include featuresheet only for decoupler --- .../main.nf | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index d4fa856ca111..357ee026c3cc 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -40,22 +40,13 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // Also, reorganize the structure to match them with the modules' input organization ch_input_for_other = ch_input - .multiMap { - meta, file, genesets, background, method -> - def meta_with_method = meta + [ 'functional_method': method ] - input: - [ meta_with_method, file ] - genesets: - [ meta_with_method, genesets ] - background: - [ meta_with_method, background ] - - } - - ch_input_for_decoupler = ch_input - .join(ch_featuresheet, by: 0) - .multiMap { - meta, file, genesets, background, method, features_sheet, features_id, features_symbol -> + .join(ch_featuresheet, by: 0, remainder: true) + .multiMap { tuple -> + def (meta, file, genesets, background, method) = tuple[0..4] + def features_sheet = tuple.size() > 5 ? tuple[5] : null + def features_id = tuple.size() > 6 ? tuple[6] : '' + def features_symbol = tuple.size() > 7 ? tuple[7] : '' + def meta_with_method = meta + [ 'functional_method': method ] input: [ meta_with_method, file ] @@ -64,7 +55,7 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { background: [ meta_with_method, background ] features: - [ meta_with_method, features_sheet, features_id, features_symbol] + [ meta_with_method, features_sheet ?: [], features_id, features_symbol] } // In the case of GSEA, it needs additional files coming from other channels that other methods don't use // here we define the input channel for the GSEA section @@ -138,9 +129,10 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // ---------------------------------------------------- DECOUPLER( - ch_input_for_decoupler.input.filter{ it[0].functional_method == 'decoupler' }, - ch_input_for_decoupler.genesets.filter{ it[0].functional_method == 'decoupler'}, - ch_input_for_decoupler.features.filter{ it[0].functional_method == 'decoupler'} + ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, + ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, + ch_input_for_other.features.filter{ it[0].functional_method == 'decoupler'} + .map{ meta, features_sheet, features_id, features_symbol -> [meta, features_sheet] } ) // ---------------------------------------------------- From e5ef67e01c0a1080b8d6461f9d2974c873c64de3 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 1 Sep 2025 02:00:59 +0000 Subject: [PATCH 50/53] Update snapshot --- .../tests/main.nf.test.snap | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 1a92071eb4a5..13103a42d22b 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -132,12 +132,12 @@ "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", "versions.yml:md5,cd9cd1563a983e586b15fd2276da8bfb", "versions.yml:md5,cd9cd1563a983e586b15fd2276da8bfb", "versions.yml:md5,f2db818ec8143f64399247548098b643", @@ -155,7 +155,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-21T15:04:08.996414207" + "timestamp": "2025-09-01T01:52:47.804479109" }, "deseq2 + gprofiler2 - mouse": { "content": [ @@ -238,19 +238,19 @@ "\"DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:GPROFILER2_GOST\"": { "r-ggplot2": "3.4.3", "r-gprofiler2": "0.2.2", - "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_f6a03c19\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" + "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_12548d0\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" } }, [ - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0" + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-21T15:00:06.659273279" + "timestamp": "2025-09-01T01:48:52.921625825" }, "propd + grea - mouse": { "content": [ @@ -340,18 +340,18 @@ "\"DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:GPROFILER2_GOST\"": { "r-ggplot2": "3.4.3", "r-gprofiler2": "0.2.2", - "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_f6a03c19\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" + "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_12548d0\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" } }, [ - "versions.yml:md5,48ce57c814471f53329615d311b1f5a0" + "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-21T14:58:54.929796085" + "timestamp": "2025-09-01T01:47:39.19110988" }, "deseq2 + decoupler - mouse": { "content": [ @@ -390,7 +390,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-15T21:34:27.044413972" + "timestamp": "2025-09-01T01:56:15.175941185" }, "deseq2 + gsea - mouse": { "content": [ @@ -501,7 +501,7 @@ ], "8": [ - "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" + "versions.yml:md5,538ba13593605c79eb5b0f060c3e42e9" ], "decoupler_dc_estimate": [ @@ -558,7 +558,7 @@ ], "versions": [ - "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" + "versions.yml:md5,538ba13593605c79eb5b0f060c3e42e9" ] } ], @@ -566,6 +566,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-13T22:09:24.891941865" + "timestamp": "2025-09-01T01:56:46.933726001" } } \ No newline at end of file From 59092256c9728dbfe3e0d6b3df3e0cde7fb2e237 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Mon, 1 Sep 2025 02:02:56 +0000 Subject: [PATCH 51/53] Fix --- .../nf-core/differential_functional_enrichment/main.nf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 7fb1c12addd6..357ee026c3cc 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -129,9 +129,10 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // ---------------------------------------------------- DECOUPLER( - ch_input_for_decoupler.input.filter{ it[0].functional_method == 'decoupler' }, - ch_input_for_decoupler.genesets.filter{ it[0].functional_method == 'decoupler'}, - ch_input_for_decoupler.features.filter{ it[0].functional_method == 'decoupler'} + ch_input_for_other.input.filter{ it[0].functional_method == 'decoupler' }, + ch_input_for_other.genesets.filter{ it[0].functional_method == 'decoupler'}, + ch_input_for_other.features.filter{ it[0].functional_method == 'decoupler'} + .map{ meta, features_sheet, features_id, features_symbol -> [meta, features_sheet] } ) // ---------------------------------------------------- From 8ed6172b2525afbb2d22b0fa1457e8348e6d8022 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 12 Sep 2025 13:58:39 +0000 Subject: [PATCH 52/53] Fix: Simplify features form input channel --- .../differential_functional_enrichment/main.nf | 13 ++++--------- .../tests/main.nf.test | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/main.nf b/subworkflows/nf-core/differential_functional_enrichment/main.nf index 357ee026c3cc..c75b5b58fcc0 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/main.nf +++ b/subworkflows/nf-core/differential_functional_enrichment/main.nf @@ -38,15 +38,9 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { // Add method information into meta map of ch_input // This information is used later to determine which method to run for each input // Also, reorganize the structure to match them with the modules' input organization - ch_input_for_other = ch_input - .join(ch_featuresheet, by: 0, remainder: true) - .multiMap { tuple -> - def (meta, file, genesets, background, method) = tuple[0..4] - def features_sheet = tuple.size() > 5 ? tuple[5] : null - def features_id = tuple.size() > 6 ? tuple[6] : '' - def features_symbol = tuple.size() > 7 ? tuple[7] : '' - + .join(ch_featuresheet) + .multiMap { meta, file, genesets, background, method, features_sheet, features_id, features_symbol -> def meta_with_method = meta + [ 'functional_method': method ] input: [ meta_with_method, file ] @@ -55,8 +49,9 @@ workflow DIFFERENTIAL_FUNCTIONAL_ENRICHMENT { background: [ meta_with_method, background ] features: - [ meta_with_method, features_sheet ?: [], features_id, features_symbol] + [ meta_with_method, features_sheet, features_id, features_symbol] } + // In the case of GSEA, it needs additional files coming from other channels that other methods don't use // here we define the input channel for the GSEA section diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test index a2c3c9af74e6..0e69dc9d210d 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test @@ -582,4 +582,4 @@ nextflow_workflow { } } -} +} \ No newline at end of file From 516ecd0b83be96dfb3a109864f0b5ae5d1274908 Mon Sep 17 00:00:00 2001 From: Maria Antonia Saracco Date: Fri, 12 Sep 2025 13:58:46 +0000 Subject: [PATCH 53/53] Update snapshot --- .../tests/main.nf.test.snap | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap index 13103a42d22b..6c892fc00f28 100644 --- a/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap +++ b/subworkflows/nf-core/differential_functional_enrichment/tests/main.nf.test.snap @@ -132,12 +132,12 @@ "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", "versions.yml:md5,25ab98049a601f4940f3e5a24aa73f55", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", "versions.yml:md5,cd9cd1563a983e586b15fd2276da8bfb", "versions.yml:md5,cd9cd1563a983e586b15fd2276da8bfb", "versions.yml:md5,f2db818ec8143f64399247548098b643", @@ -155,7 +155,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-09-01T01:52:47.804479109" + "timestamp": "2025-09-12T13:53:45.331513742" }, "deseq2 + gprofiler2 - mouse": { "content": [ @@ -238,19 +238,19 @@ "\"DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:GPROFILER2_GOST\"": { "r-ggplot2": "3.4.3", "r-gprofiler2": "0.2.2", - "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_12548d0\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" + "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_f6a03c19\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" } }, [ - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463", - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463" + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0", + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-09-01T01:48:52.921625825" + "timestamp": "2025-09-12T13:50:16.438987978" }, "propd + grea - mouse": { "content": [ @@ -340,18 +340,18 @@ "\"DIFFERENTIAL_FUNCTIONAL_ENRICHMENT:GPROFILER2_GOST\"": { "r-ggplot2": "3.4.3", "r-gprofiler2": "0.2.2", - "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_12548d0\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" + "gprofiler-data": "biomart: Ensembl\nbiomart_version: '113'\ndisplay_name: Mouse\ngenebuild: GRCm39\ngprofiler_version: e113_eg59_p19_f6a03c19\norganism: mmusculus\nsources:\n CORUM:\n name: CORUM protein complexes\n version: 28.11.2022 Corum 4.1\n GO:BP:\n name: biological process\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:CC:\n name: cellular component\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n GO:MF:\n name: molecular function\n version: |-\n annotations: BioMart\n classes: releases/2025-03-16\n HP:\n name: Human Phenotype Ontology\n version: |-\n annotations: 05.2025\n classes: None\n KEGG:\n name: Kyoto Encyclopedia of Genes and Genomes\n version: KEGG FTP Release 2024-01-22\n REAC:\n name: Reactome\n version: |-\n annotations: BioMart\n classes: 2025-5-23\n TF:\n name: Transfac\n version: |-\n annotations: TRANSFAC Release 2024.2\n classes: v2\n WP:\n name: WikiPathways\n version: '20250510'\ntaxonomy_id: '10090'\n" } }, [ - "versions.yml:md5,cc1cabec2639e78a3e3afb351a98f463" + "versions.yml:md5,48ce57c814471f53329615d311b1f5a0" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-09-01T01:47:39.19110988" + "timestamp": "2025-09-12T13:48:59.907490432" }, "deseq2 + decoupler - mouse": { "content": [ @@ -501,7 +501,7 @@ ], "8": [ - "versions.yml:md5,538ba13593605c79eb5b0f060c3e42e9" + "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" ], "decoupler_dc_estimate": [ @@ -558,7 +558,7 @@ ], "versions": [ - "versions.yml:md5,538ba13593605c79eb5b0f060c3e42e9" + "versions.yml:md5,71d562114ad0a46a870b75ac423ab82c" ] } ], @@ -566,6 +566,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-09-01T01:56:46.933726001" + "timestamp": "2025-09-12T13:57:00.483231081" } } \ No newline at end of file