From fa8a8601b0258dd406acd9bb57d2a3c23a2c428a Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sun, 27 Sep 2026 18:28:45 +0000 Subject: [PATCH 01/13] feat(dia_proteomics_analysis): emit pg_matrix and diann_log Expose DIANN_FINALQUANTIFICATION pg_matrix and log as subworkflow emits so downstream QPX/AnnData export can consume them. Recorded as an nf-core patch (dia_proteomics_analysis.diff, modules.json patch entry). --- modules.json | 3 +- .../dia_proteomics_analysis.diff | 50 +++++++++++++++++++ .../nf-core/dia_proteomics_analysis/main.nf | 2 + .../nf-core/dia_proteomics_analysis/meta.yml | 20 ++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff diff --git a/modules.json b/modules.json index e81f7896..24ec9588 100644 --- a/modules.json +++ b/modules.json @@ -64,7 +64,8 @@ "git_sha": "146a155d778ba9a944ded6939ed5644307a8600a", "installed_by": [ "subworkflows" - ] + ], + "patch": "subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff" }, "utils_nextflow_pipeline": { "branch": "master", diff --git a/subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff b/subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff new file mode 100644 index 00000000..0f0441ad --- /dev/null +++ b/subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff @@ -0,0 +1,50 @@ +Changes in component 'nf-core/dia_proteomics_analysis' +Changes in 'dia_proteomics_analysis/main.nf': +--- subworkflows/nf-core/dia_proteomics_analysis/main.nf ++++ subworkflows/nf-core/dia_proteomics_analysis/main.nf +@@ -450,6 +450,8 @@ + versions = ch_versions + diann_report = DIANN_FINALQUANTIFICATION.out.main_report + diann_report_parquet = DIANN_FINALQUANTIFICATION.out.report_parquet ++ pg_matrix = DIANN_FINALQUANTIFICATION.out.pg_matrix ++ diann_log = DIANN_FINALQUANTIFICATION.out.log + mzml_statistics = QUANTMSUTILS_MZMLSTATISTICS.out.ms_statistics + msstats_in = QUANTMSUTILS_DIANN2MZTAB.out.out_msstats + out_triqler = QUANTMSUTILS_DIANN2MZTAB.out.out_triqler + +Changes in 'dia_proteomics_analysis/meta.yml': +--- subworkflows/nf-core/dia_proteomics_analysis/meta.yml ++++ subworkflows/nf-core/dia_proteomics_analysis/meta.yml +@@ -147,6 +147,26 @@ + type: file + description: Main DIA-NN report in Parquet format + pattern: "*.parquet" ++ - pg_matrix: ++ description: DIA-NN protein group matrix from the final quantification step ++ structure: ++ - meta: ++ type: map ++ description: Groovy Map containing experiment and search database information ++ - pg_matrix: ++ type: file ++ description: DIA-NN protein group quantification matrix ++ pattern: "*.pg_matrix.tsv" ++ - diann_log: ++ description: DIA-NN log from the final quantification step ++ structure: ++ - meta: ++ type: map ++ description: Groovy Map containing experiment and search database information ++ - log: ++ type: file ++ description: DIA-NN final quantification log ++ pattern: "*.log.txt" + - mzml_statistics: + description: Statistics extracted from mzML files + structure: + +'subworkflows/nf-core/dia_proteomics_analysis/nextflow.config' is unchanged +'subworkflows/nf-core/dia_proteomics_analysis/tests/nextflow.config' is unchanged +'subworkflows/nf-core/dia_proteomics_analysis/tests/main.nf.test.snap' is unchanged +'subworkflows/nf-core/dia_proteomics_analysis/tests/main.nf.test' is unchanged +************************************************************ diff --git a/subworkflows/nf-core/dia_proteomics_analysis/main.nf b/subworkflows/nf-core/dia_proteomics_analysis/main.nf index 6c686a6c..a89ff8c3 100644 --- a/subworkflows/nf-core/dia_proteomics_analysis/main.nf +++ b/subworkflows/nf-core/dia_proteomics_analysis/main.nf @@ -450,6 +450,8 @@ workflow DIA_PROTEOMICS_ANALYSIS { versions = ch_versions diann_report = DIANN_FINALQUANTIFICATION.out.main_report diann_report_parquet = DIANN_FINALQUANTIFICATION.out.report_parquet + pg_matrix = DIANN_FINALQUANTIFICATION.out.pg_matrix + diann_log = DIANN_FINALQUANTIFICATION.out.log mzml_statistics = QUANTMSUTILS_MZMLSTATISTICS.out.ms_statistics msstats_in = QUANTMSUTILS_DIANN2MZTAB.out.out_msstats out_triqler = QUANTMSUTILS_DIANN2MZTAB.out.out_triqler diff --git a/subworkflows/nf-core/dia_proteomics_analysis/meta.yml b/subworkflows/nf-core/dia_proteomics_analysis/meta.yml index 481614a6..4d4cb8c1 100644 --- a/subworkflows/nf-core/dia_proteomics_analysis/meta.yml +++ b/subworkflows/nf-core/dia_proteomics_analysis/meta.yml @@ -147,6 +147,26 @@ output: type: file description: Main DIA-NN report in Parquet format pattern: "*.parquet" + - pg_matrix: + description: DIA-NN protein group matrix from the final quantification step + structure: + - meta: + type: map + description: Groovy Map containing experiment and search database information + - pg_matrix: + type: file + description: DIA-NN protein group quantification matrix + pattern: "*.pg_matrix.tsv" + - diann_log: + description: DIA-NN log from the final quantification step + structure: + - meta: + type: map + description: Groovy Map containing experiment and search database information + - log: + type: file + description: DIA-NN final quantification log + pattern: "*.log.txt" - mzml_statistics: description: Statistics extracted from mzML files structure: From a3f87428ba85da01aae5ed3395269d62a4bd4163 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 02:22:04 +0000 Subject: [PATCH 02/13] fix(fragpipe_headless): honour manifest_content and match file names exactly manifest_content was declared but never read: every LFQ file fell back to experiment1 / bioreplicate 1 / DDA, so allinone runs collapsed all samples into one experiment and lost DDA+ and empty (fraction) bioreplicates. - manifest_content is authoritative when non-empty (file, experiment, bioreplicate, data type); file_experiment_map is the fallback (bioreplicate 1, DDA) - file names are matched on the whole first column instead of grep -F, which gave A1.mzML the experiment of XA1.mzML - fail loudly on a staged file without a row, a row for an unstaged file, duplicate file names, a TMT experiment missing from annotation_content, or both manifest_content and file_experiment_map empty - pass pasted values base64-encoded so they can neither expand in bash nor break the script indentation (versions.yml carried a stray END_VERSIONS) - single-plex TMT uses the per-experiment subdirectory layout of multi-plex - stub writes results/fragpipe-files.fp-manifest and results/experiment_annotation.tsv - tests: fake-FragPipe tests of the real script block (DDA+ manifest, fractions, exact file_experiment_map match, missing row, empty inputs) --- CHANGELOG.md | 14 ++ modules/local/fragpipe_headless/main.nf | 191 +++++++++------ modules/local/fragpipe_headless/meta.yml | 18 +- .../tests/fake_fragpipe/bin/java | 28 +++ .../tests/fake_fragpipe/tools/README.txt | 1 + .../fragpipe_headless/tests/main.nf.test | 222 ++++++++++++++++++ .../fragpipe_headless/tests/main.nf.test.snap | 82 ++++++- .../fragpipe_headless/tests/nextflow.config | 18 ++ .../local/fragpipe_headless_wf/main.nf | 4 +- .../local/fragpipe_headless_wf/meta.yml | 7 +- .../fragpipe_headless_wf/tests/main.nf.test | 2 +- .../tests/main.nf.test.snap | 4 +- 12 files changed, 510 insertions(+), 81 deletions(-) create mode 100755 modules/local/fragpipe_headless/tests/fake_fragpipe/bin/java create mode 100644 modules/local/fragpipe_headless/tests/fake_fragpipe/tools/README.txt create mode 100644 modules/local/fragpipe_headless/tests/nextflow.config diff --git a/CHANGELOG.md b/CHANGELOG.md index 78f09842..b4e4e99e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- `FRAGPIPE_HEADLESS`: `manifest_content` is used again and is authoritative (file, experiment, bioreplicate, data type), so allinone runs keep one experiment per sample, empty bioreplicates for fractions, and `DDA+`; before, every LFQ file fell back to `experiment1` / `1` / `DDA`. +- `FRAGPIPE_HEADLESS`: file names are matched exactly against the manifest (or `file_experiment_map`) first column; the substring lookup (`grep -F`) gave `A1.mzML` the experiment of `XA1.mzML`. +- `FRAGPIPE_HEADLESS`: the task fails loudly when a staged file has no row, a row names an unstaged file, a file is listed twice, a TMT file's experiment is not in `annotation_content`, or both `manifest_content` and `file_experiment_map` are empty (TMT files were silently dropped before). +- `FRAGPIPE_HEADLESS`: `versions.yml` no longer carries a stray `END_VERSIONS` line when a multi-line value was pasted into the script (inputs are now passed base64-encoded, so no value can break indentation or expand in bash). + +### Changed + +- `FRAGPIPE_HEADLESS`: single-plex TMT files are placed in `raw_files//` like multi-plex ones. +- `FRAGPIPE_HEADLESS` stub writes `results/fragpipe-files.fp-manifest` and `results/experiment_annotation.tsv`. + ## v1.0.0 - Initial Release ### Added diff --git a/modules/local/fragpipe_headless/main.nf b/modules/local/fragpipe_headless/main.nf index 387006f8..3086ff1b 100644 --- a/modules/local/fragpipe_headless/main.nf +++ b/modules/local/fragpipe_headless/main.nf @@ -8,12 +8,19 @@ * This produces results identical to running FragPipe from the GUI. * * Input: - * - raw_files: All raw data files (.d, .raw, .mzML) + * - raw_files: All raw data files (.d, .mzML) staged into raw_files/ * - database: FASTA database file * - workflow_file: FragPipe .workflow configuration file - * - manifest_content: Tab-separated manifest content (filename\texperiment\tbioreplicate\tdata_type) + * - manifest_content: Manifest rows (file name\texperiment\tbioreplicate\tdata_type). + * Authoritative when non-empty; bioreplicate may be empty (fractions) * - annotation_content: TMT annotation content (experiment\tchannel\tsample_name), empty for LFQ - * - file_experiment_map: File-to-experiment mapping (filename\texperiment), empty for LFQ + * - file_experiment_map: File-to-experiment mapping (file name\texperiment), used only when + * manifest_content is empty (bioreplicate 1, data type DDA) + * + * File names are matched exactly against the first column. The task fails if a staged + * .mzML/.d file has no row, a row names a file that is not staged, a file name is listed + * twice, a TMT file's experiment is not in annotation_content, or manifest_content and + * file_experiment_map are both empty. * * Output: * - all_results: All FragPipe output files @@ -51,91 +58,45 @@ process FRAGPIPE_HEADLESS { def mem_gb = (task.memory.toGiga() * 0.9).intValue() def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' def lib_dir = tools_dir.replaceAll('/tools$', '/lib') + def annotation_b64 = annotation_content.toString().getBytes('UTF-8').encodeBase64().toString() """ export JAVA_OPTS="-Xmx${mem_gb}G" mkdir -p results - ANNOTATION_CONTENT="${annotation_content}" - FILE_EXP_MAP="${file_experiment_map}" + ${fragpipeLookupScript(manifest_content, file_experiment_map)} - # Determine TMT mode - IS_MULTIPLEX=false - if [ -n "\${ANNOTATION_CONTENT}" ]; then - NUM_TMT_EXP=\$(echo "\${ANNOTATION_CONTENT}" | cut -f1 | sort -u | wc -l) - [ "\${NUM_TMT_EXP}" -gt 1 ] && IS_MULTIPLEX=true - fi + printf '%s' '${annotation_b64}' | base64 -d > input_annotation.tsv - if [ "\${IS_MULTIPLEX}" = true ]; then + if [ -s input_annotation.tsv ]; then # - # MULTI-PLEX TMT: Per-experiment subdirectories with annotation files. - # FragPipe auto-discovers *annotation.txt in each mzML's parent directory. - # Requires exactly 1 annotation file per directory (TmtiPanel.java:868-880). + # TMT: one subdirectory per plex (experiment) holding its mzML files and annotation. + # FragPipe auto-discovers *annotation.txt in each mzML's parent directory and + # requires exactly 1 annotation file per directory (TmtiPanel.java:868-880). # - EXPERIMENTS=\$(echo "\${ANNOTATION_CONTENT}" | cut -f1 | sort -u) - - # Create per-experiment subdirectories and move files - for EXP in \${EXPERIMENTS}; do + cut -f1 input_annotation.tsv | sort -u > tmt_experiments.txt + UNKNOWN=\$(awk -F'\\t' 'NR == FNR { plex[\$0] = 1; next } !(\$2 in plex) { print \$1 " -> " \$2 }' tmt_experiments.txt lookup.tsv) + if [ -n "\${UNKNOWN}" ]; then + echo "ERROR: FRAGPIPE_HEADLESS: \${LOOKUP_SOURCE} experiment(s) not in annotation_content: \${UNKNOWN}" >&2 + exit 1 + fi + + while IFS= read -r EXP; do mkdir -p "raw_files/\${EXP}" - done + # space-separated: channel sample_name + EXP="\${EXP}" awk -F'\\t' '\$1 == ENVIRON["EXP"] { print \$2" "\$3 }' input_annotation.tsv > "raw_files/\${EXP}/\${EXP}_annotation.txt" + done < tmt_experiments.txt - for f in raw_files/*.mzML raw_files/*.d; do - [ -e "\$f" ] || continue - fname=\$(basename "\$f") - # Look up experiment from file-experiment map - TARGET_EXP=\$(echo "\${FILE_EXP_MAP}" | grep -F "\${fname}" | head -1 | cut -f2) - if [ -n "\${TARGET_EXP}" ] && [ -d "raw_files/\${TARGET_EXP}" ]; then - cp "\$f" "raw_files/\${TARGET_EXP}/\${fname}" - fi + cut -f1,2 lookup.tsv | while IFS=\$'\\t' read -r fname EXP; do + cp -R "raw_files/\${fname}" "raw_files/\${EXP}/\${fname}" done - # Create per-experiment annotation files (space-separated: channel sample_name) - for EXP in \${EXPERIMENTS}; do - echo "\${ANNOTATION_CONTENT}" | awk -F'\\t' -v expname="\${EXP}" '\$1==expname {print \$2" "\$3}' > "raw_files/\${EXP}/\${EXP}_annotation.txt" - done - - # Generate manifest pointing into subdirectories - >| manifest.fp-manifest - for EXP in \${EXPERIMENTS}; do - for f in raw_files/\${EXP}/*.mzML raw_files/\${EXP}/*.d; do - [ -e "\$f" ] || continue - fname=\$(basename "\$f") - [[ "\$fname" == *annotation.txt ]] && continue - echo -e "\$(pwd)/raw_files/\${EXP}/\${fname}\\t\${EXP}\\t1\\tDDA" - done - done >> manifest.fp-manifest - - elif [ -n "\${ANNOTATION_CONTENT}" ]; then - # - # SINGLE-PLEX TMT: One annotation file in raw_files/ (no subdirs needed). - # All files from one experiment share the directory. - # - EXP=\$(echo "\${ANNOTATION_CONTENT}" | cut -f1 | sort -u | head -1) - echo "\${ANNOTATION_CONTENT}" | awk -F'\\t' '{print \$2" "\$3}' > "raw_files/\${EXP}_annotation.txt" - - >| manifest.fp-manifest - for f in raw_files/*.mzML raw_files/*.d; do - [ -e "\$f" ] || continue - fname=\$(basename "\$f") - [[ "\$fname" == *annotation.txt ]] && continue - echo -e "\$(pwd)/raw_files/\${fname}\\t\${EXP}\\t1\\tDDA" - done >> manifest.fp-manifest - + RAW_DIR="\$(pwd)/raw_files" awk -F'\\t' -v OFS='\\t' '{ print ENVIRON["RAW_DIR"] "/" \$2 "/" \$1, \$2, \$3, \$4 }' lookup.tsv > manifest.fp-manifest else # - # LFQ MODE: No annotation, flat directory. + # LFQ: flat directory. # - FILE_EXP_MAP_FOR_LFQ="${file_experiment_map}" - >| manifest.fp-manifest - for f in raw_files/*.mzML raw_files/*.d; do - [ -e "\$f" ] || continue - fname=\$(basename "\$f") - MATCHED_EXP="" - if echo "\${FILE_EXP_MAP_FOR_LFQ}" | grep -qF "\${fname}"; then - MATCHED_EXP=\$(echo "\${FILE_EXP_MAP_FOR_LFQ}" | grep -F "\${fname}" | head -1 | cut -f2) - fi - echo -e "\$(pwd)/raw_files/\${fname}\\t\${MATCHED_EXP:-experiment1}\\t1\\tDDA" - done >> manifest.fp-manifest + RAW_DIR="\$(pwd)/raw_files" awk -F'\\t' -v OFS='\\t' '{ print ENVIRON["RAW_DIR"] "/" \$1, \$2, \$3, \$4 }' lookup.tsv > manifest.fp-manifest fi # Update workflow file for container environment @@ -192,6 +153,8 @@ process FRAGPIPE_HEADLESS { stub: """ + ${fragpipeLookupScript(manifest_content, file_experiment_map)} + mkdir -p results/sample1 touch results/combined_protein.tsv touch results/combined_peptide.tsv @@ -199,9 +162,93 @@ process FRAGPIPE_HEADLESS { touch results/sample1/psm.tsv touch results/sample1/protein.tsv + # Manifest and LFQ experiment annotation as FragPipe writes them into the work dir + # (ToolingUtils.generateLFQExperimentAnnotation); relative paths keep stub output deterministic + awk -F'\\t' -v OFS='\\t' '{ print "raw_files/" \$1, \$2, \$3, \$4 }' lookup.tsv > results/fragpipe-files.fp-manifest + awk -F'\\t' -v OFS='\\t' ' + BEGIN { print "file", "sample", "sample_name", "condition", "replicate" } + { + sample = (\$3 == "") ? \$2 : \$2 "_" \$3 + split(\$2, parts, "_") + print "raw_files/" \$1, sample, sample, parts[1], ((\$3 == "") ? 1 : \$3) + } + ' lookup.tsv > results/experiment_annotation.tsv + cat <<-END_VERSIONS >| versions.yml "${task.process}": fragpipe: "24.0" END_VERSIONS """ } + +/* + * Bash shared by script: and stub: that writes lookup.tsv (file name, experiment, + * bioreplicate, data type; one row per staged .mzML/.d file) and sets LOOKUP_SOURCE. + * manifest_content is authoritative; file_experiment_map is the fallback. + * Values are base64-encoded so '$', backticks and quotes in them never expand in bash. + */ +def fragpipeLookupScript(manifest_content, file_experiment_map) { + def manifest_b64 = manifest_content.toString().getBytes('UTF-8').encodeBase64().toString() + def map_b64 = file_experiment_map.toString().getBytes('UTF-8').encodeBase64().toString() + return """ + printf '%s' '${manifest_b64}' | base64 -d > input_manifest.tsv + printf '%s' '${map_b64}' | base64 -d > input_file_experiment_map.tsv + + if [ -s input_manifest.tsv ]; then + LOOKUP_SOURCE=manifest_content + awk -F'\\t' -v OFS='\\t' ' + NF == 0 { next } + NF != 4 || \$1 == "" || \$2 == "" || \$4 == "" { + print "ERROR: FRAGPIPE_HEADLESS: manifest_content line " NR " is not fileexperimentbioreplicatedata_type: " \$0 > "/dev/stderr" + bad = 1 + next + } + { print } + END { exit bad } + ' input_manifest.tsv > lookup.tsv + elif [ -s input_file_experiment_map.tsv ]; then + LOOKUP_SOURCE=file_experiment_map + awk -F'\\t' -v OFS='\\t' ' + NF == 0 { next } + NF != 2 || \$1 == "" || \$2 == "" { + print "ERROR: FRAGPIPE_HEADLESS: file_experiment_map line " NR " is not fileexperiment: " \$0 > "/dev/stderr" + bad = 1 + next + } + { print \$1, \$2, "1", "DDA" } + END { exit bad } + ' input_file_experiment_map.tsv > lookup.tsv + else + echo "ERROR: FRAGPIPE_HEADLESS: manifest_content and file_experiment_map are both empty" >&2 + exit 1 + fi + + for f in raw_files/*.mzML raw_files/*.d; do + [ -e "\$f" ] || continue + basename "\$f" + done > staged_files.txt + + if [ ! -s staged_files.txt ] || [ ! -s lookup.tsv ]; then + echo "ERROR: FRAGPIPE_HEADLESS: no staged .mzML/.d files or no \${LOOKUP_SOURCE} rows" >&2 + exit 1 + fi + + DUPLICATES=\$(cut -f1 lookup.tsv | sort | uniq -d) + if [ -n "\${DUPLICATES}" ]; then + echo "ERROR: FRAGPIPE_HEADLESS: file name(s) listed more than once in \${LOOKUP_SOURCE}: \${DUPLICATES}" >&2 + exit 1 + fi + + MISSING=\$(awk -F'\\t' 'NR == FNR { listed[\$1] = 1; next } !(\$0 in listed)' lookup.tsv staged_files.txt) + if [ -n "\${MISSING}" ]; then + echo "ERROR: FRAGPIPE_HEADLESS: no \${LOOKUP_SOURCE} row for staged file(s): \${MISSING}" >&2 + exit 1 + fi + + UNSTAGED=\$(awk -F'\\t' 'NR == FNR { staged[\$0] = 1; next } !(\$1 in staged) { print \$1 }' staged_files.txt lookup.tsv) + if [ -n "\${UNSTAGED}" ]; then + echo "ERROR: FRAGPIPE_HEADLESS: \${LOOKUP_SOURCE} row(s) for file(s) not staged in raw_files/: \${UNSTAGED}" >&2 + exit 1 + fi + """ +} diff --git a/modules/local/fragpipe_headless/meta.yml b/modules/local/fragpipe_headless/meta.yml index e94e9901..09943f92 100644 --- a/modules/local/fragpipe_headless/meta.yml +++ b/modules/local/fragpipe_headless/meta.yml @@ -29,7 +29,23 @@ input: pattern: "*.workflow" - manifest_content: type: value - description: Tab-separated manifest content (filename, experiment, bioreplicate, data_type) + description: | + Tab-separated manifest rows (file name, experiment, bioreplicate, data_type), no header. + Authoritative when non-empty: each staged .mzML/.d file must have exactly one row whose + first column equals its file name. Bioreplicate may be empty (fractions of one sample); + data_type is passed through (e.g. DDA, DDA+). + - annotation_content: + type: value + description: | + TMT annotation rows (experiment, channel, sample_name), empty for LFQ. + When non-empty, each file is placed in raw_files// with that experiment's + annotation, and every file's experiment must appear in this annotation. + - file_experiment_map: + type: value + description: | + Tab-separated rows (file name, experiment), used only when manifest_content is empty; + bioreplicate is then 1 and data_type DDA. File names are matched exactly. + The task fails when both manifest_content and file_experiment_map are empty. output: - all_results: type: file diff --git a/modules/local/fragpipe_headless/tests/fake_fragpipe/bin/java b/modules/local/fragpipe_headless/tests/fake_fragpipe/bin/java new file mode 100755 index 00000000..48ba5b20 --- /dev/null +++ b/modules/local/fragpipe_headless/tests/fake_fragpipe/bin/java @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Fake `java` for modules/local/fragpipe_headless/tests/main.nf.test. +# Stands in for FragPipe so the REAL script: block of FRAGPIPE_HEADLESS runs without the licensed image. +# --help -> prints the FragPipe version banner parsed into versions.yml +# --headless -> copies the --manifest file to /fragpipe-files.fp-manifest +# (as FragPipe does) and touches the combined_*.tsv reports +set -euo pipefail + +if [[ " $* " == *" --help "* ]]; then + echo "FragPipePlus v24.0" + exit 0 +fi + +manifest="" +workdir="" +while [[ $# -gt 0 ]]; do + case "$1" in + --manifest) manifest="$2"; shift 2 ;; + --workdir) workdir="$2"; shift 2 ;; + *) shift ;; + esac +done + +[[ -n "${manifest}" && -n "${workdir}" ]] || { echo "fake java: --manifest and --workdir are required" >&2; exit 1; } + +mkdir -p "${workdir}" +cp "${manifest}" "${workdir}/fragpipe-files.fp-manifest" +touch "${workdir}/combined_protein.tsv" "${workdir}/combined_peptide.tsv" "${workdir}/combined_ion.tsv" diff --git a/modules/local/fragpipe_headless/tests/fake_fragpipe/tools/README.txt b/modules/local/fragpipe_headless/tests/fake_fragpipe/tools/README.txt new file mode 100644 index 00000000..c4aec90a --- /dev/null +++ b/modules/local/fragpipe_headless/tests/fake_fragpipe/tools/README.txt @@ -0,0 +1 @@ +Placeholder FragPipe tools folder (task.ext.fragpipe_tools_dir) for the fake-java module test. diff --git a/modules/local/fragpipe_headless/tests/main.nf.test b/modules/local/fragpipe_headless/tests/main.nf.test index afa6ccbe..8fa1ebea 100644 --- a/modules/local/fragpipe_headless/tests/main.nf.test +++ b/modules/local/fragpipe_headless/tests/main.nf.test @@ -1,8 +1,17 @@ +/* + * FRAGPIPE_HEADLESS tests. + * + * The stub test covers -stub output. The manifest tests run the REAL script: block with a + * fake `java` on PATH (fake_fragpipe/bin/java, see ./nextflow.config) that copies the manifest + * handed to FragPipe into results/fragpipe-files.fp-manifest, so they check the experiment, + * bioreplicate and data type FragPipe would actually receive. + */ nextflow_process { name "Test Process FRAGPIPE_HEADLESS" script "../main.nf" process "FRAGPIPE_HEADLESS" + config "./nextflow.config" tag "modules" tag "modules_nfcore" @@ -13,6 +22,9 @@ nextflow_process { options "-stub" when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } process { """ def raw_file = file("\${workDir}/sample.mzML") @@ -44,4 +56,214 @@ nextflow_process { ) } } + + test("fragpipe_headless - manifest_content is authoritative: 3 experiments, DDA+") { + tag "stub" + + when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } + process { + """ + input[0] = ['S1.mzML', 'S2.mzML', 'S3.mzML'].collect { name -> + def spectra = file("\${workDir}/fake_spectra/\${name}") + spectra.parent.mkdirs() + spectra.text = "mock" + spectra + } + def fasta_file = file("\${workDir}/test.fasta") + fasta_file.text = ">sp|P00001|TEST\\nMKTEST" + def workflow_file = file("\${workDir}/test.workflow") + workflow_file.text = "database.db-path=/placeholder.fasta" + + input[1] = fasta_file + input[2] = workflow_file + input[3] = "S1.mzML\\tS1\\t1\\tDDA+\\nS2.mzML\\tS2\\t1\\tDDA+\\nS3.mzML\\tS3\\t1\\tDDA+" + input[4] = "" + input[5] = "" + """ + } + } + + then { + // [file name, experiment, bioreplicate, data_type] per manifest row handed to FragPipe + // (the fake java copies it to results/fragpipe-files.fp-manifest; absolute paths differ per run) + def manifest = process.out.all_results.flatten().find { it.toString().endsWith('fragpipe-files.fp-manifest') } + def rows = path(manifest.toString()).readLines().collect { line -> + def cols = line.split('\t', -1) + [ file(cols[0]).name, cols[1], cols[2], cols[3] ] + } + assertAll( + { assert process.success }, + { assert rows.collect { it[1] } == ['S1', 'S2', 'S3'] : "experiments: ${rows.collect { it[1] }}" }, + { assert rows.every { it[3] == 'DDA+' } : "data types: ${rows.collect { it[3] }}" }, + { assert snapshot(rows, process.out.versions).match() } + ) + } + } + + test("fragpipe_headless - manifest_content keeps the empty bioreplicate of fractions") { + tag "stub" + + when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } + process { + """ + input[0] = ['F1.mzML', 'F2.mzML'].collect { name -> + def spectra = file("\${workDir}/fake_spectra/\${name}") + spectra.parent.mkdirs() + spectra.text = "mock" + spectra + } + def fasta_file = file("\${workDir}/test.fasta") + fasta_file.text = ">sp|P00001|TEST\\nMKTEST" + def workflow_file = file("\${workDir}/test.workflow") + workflow_file.text = "database.db-path=/placeholder.fasta" + + input[1] = fasta_file + input[2] = workflow_file + input[3] = "F1.mzML\\tG1\\t\\tDDA\\nF2.mzML\\tG1\\t\\tDDA" + input[4] = "" + input[5] = "" + """ + } + } + + then { + // [file name, experiment, bioreplicate, data_type] per manifest row handed to FragPipe + // (the fake java copies it to results/fragpipe-files.fp-manifest; absolute paths differ per run) + def manifest = process.out.all_results.flatten().find { it.toString().endsWith('fragpipe-files.fp-manifest') } + def rows = path(manifest.toString()).readLines().collect { line -> + def cols = line.split('\t', -1) + [ file(cols[0]).name, cols[1], cols[2], cols[3] ] + } + assertAll( + { assert process.success }, + { assert snapshot(rows).match() } + ) + } + } + + test("fragpipe_headless - file_experiment_map matches file names exactly: A1 keeps GA, XA1 keeps GX") { + // XA1.mzML is listed first: a substring lookup (grep -F A1.mzML) would give A1.mzML experiment GX. + tag "stub" + + when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } + process { + """ + input[0] = ['A1.mzML', 'XA1.mzML'].collect { name -> + def spectra = file("\${workDir}/fake_spectra/\${name}") + spectra.parent.mkdirs() + spectra.text = "mock" + spectra + } + def fasta_file = file("\${workDir}/test.fasta") + fasta_file.text = ">sp|P00001|TEST\\nMKTEST" + def workflow_file = file("\${workDir}/test.workflow") + workflow_file.text = "database.db-path=/placeholder.fasta" + + input[1] = fasta_file + input[2] = workflow_file + input[3] = "" + input[4] = "" + input[5] = "XA1.mzML\\tGX\\nA1.mzML\\tGA" + """ + } + } + + then { + // [file name, experiment, bioreplicate, data_type] per manifest row handed to FragPipe + // (the fake java copies it to results/fragpipe-files.fp-manifest; absolute paths differ per run) + def manifest = process.out.all_results.flatten().find { it.toString().endsWith('fragpipe-files.fp-manifest') } + def rows = path(manifest.toString()).readLines().collect { line -> + def cols = line.split('\t', -1) + [ file(cols[0]).name, cols[1], cols[2], cols[3] ] + } + assertAll( + { assert process.success }, + { assert rows.collectEntries { [ (it[0]): it[1] ] } == ['A1.mzML': 'GA', 'XA1.mzML': 'GX'] : "rows: ${rows}" }, + { assert snapshot(rows).match() } + ) + } + } + + test("fragpipe_headless - staged file without a manifest row fails") { + tag "stub" + + when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } + process { + """ + input[0] = ['S1.mzML', 'S2.mzML'].collect { name -> + def spectra = file("\${workDir}/fake_spectra/\${name}") + spectra.parent.mkdirs() + spectra.text = "mock" + spectra + } + def fasta_file = file("\${workDir}/test.fasta") + fasta_file.text = ">sp|P00001|TEST\\nMKTEST" + def workflow_file = file("\${workDir}/test.workflow") + workflow_file.text = "database.db-path=/placeholder.fasta" + + input[1] = fasta_file + input[2] = workflow_file + input[3] = "S1.mzML\\tS1\\t1\\tDDA" + input[4] = "" + input[5] = "" + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert process.errorReport.contains('ERROR: FRAGPIPE_HEADLESS: no manifest_content row for staged file(s): S2.mzML') : process.errorReport } + ) + } + } + + test("fragpipe_headless - manifest_content and file_experiment_map both empty fails") { + tag "stub" + + when { + params { + fake_fragpipe_dir = "${projectDir}/modules/local/fragpipe_headless/tests/fake_fragpipe" + } + process { + """ + input[0] = ['S1.mzML'].collect { name -> + def spectra = file("\${workDir}/fake_spectra/\${name}") + spectra.parent.mkdirs() + spectra.text = "mock" + spectra + } + def fasta_file = file("\${workDir}/test.fasta") + fasta_file.text = ">sp|P00001|TEST\\nMKTEST" + def workflow_file = file("\${workDir}/test.workflow") + workflow_file.text = "database.db-path=/placeholder.fasta" + + input[1] = fasta_file + input[2] = workflow_file + input[3] = "" + input[4] = "" + input[5] = "" + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert process.errorReport.contains('ERROR: FRAGPIPE_HEADLESS: manifest_content and file_experiment_map are both empty') : process.errorReport } + ) + } + } } diff --git a/modules/local/fragpipe_headless/tests/main.nf.test.snap b/modules/local/fragpipe_headless/tests/main.nf.test.snap index 5612c758..de7265bd 100644 --- a/modules/local/fragpipe_headless/tests/main.nf.test.snap +++ b/modules/local/fragpipe_headless/tests/main.nf.test.snap @@ -1,4 +1,82 @@ { + "fragpipe_headless - file_experiment_map matches file names exactly: A1 keeps GA, XA1 keeps GX": { + "content": [ + [ + [ + "XA1.mzML", + "GX", + "1", + "DDA" + ], + [ + "A1.mzML", + "GA", + "1", + "DDA" + ] + ] + ], + "timestamp": "2026-09-29T00:00:00.000000000", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.2" + } + }, + "fragpipe_headless - manifest_content is authoritative: 3 experiments, DDA+": { + "content": [ + [ + [ + "S1.mzML", + "S1", + "1", + "DDA+" + ], + [ + "S2.mzML", + "S2", + "1", + "DDA+" + ], + [ + "S3.mzML", + "S3", + "1", + "DDA+" + ] + ], + [ + "versions.yml:md5,bb4d13cb9bebee2a60cd249d64401e43" + ] + ], + "timestamp": "2026-09-29T00:00:00.000000000", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.2" + } + }, + "fragpipe_headless - manifest_content keeps the empty bioreplicate of fractions": { + "content": [ + [ + [ + "F1.mzML", + "G1", + "", + "DDA" + ], + [ + "F2.mzML", + "G1", + "", + "DDA" + ] + ] + ], + "timestamp": "2026-09-29T00:00:00.000000000", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.2" + } + }, "fragpipe_headless - stub": { "content": [ [ @@ -6,6 +84,8 @@ "combined_ion.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "combined_peptide.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "combined_protein.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "experiment_annotation.tsv:md5,179b76ced1e83e291436194016eabcb4", + "fragpipe-files.fp-manifest:md5,01e0f6fada67016e2eee50ba854551c6", "protein.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "psm.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] @@ -20,7 +100,7 @@ "combined_ion.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "timestamp": "2026-03-25T03:48:50.692202093", + "timestamp": "2026-09-29T00:00:00.000000000", "meta": { "nf-test": "0.9.5", "nextflow": "25.10.2" diff --git a/modules/local/fragpipe_headless/tests/nextflow.config b/modules/local/fragpipe_headless/tests/nextflow.config new file mode 100644 index 00000000..418c3597 --- /dev/null +++ b/modules/local/fragpipe_headless/tests/nextflow.config @@ -0,0 +1,18 @@ +/* + * Config for modules/local/fragpipe_headless/tests/main.nf.test. + * + * The manifest tests run the REAL script: block without the licensed FragPipe image: + * no container engine, and a fake `java` (fake_fragpipe/bin/java) first on PATH. + * params.fake_fragpipe_dir is set by each test (absolute path to fake_fragpipe/). + */ + +docker.enabled = false +singularity.enabled = false +conda.enabled = false + +process { + withName: 'FRAGPIPE_HEADLESS' { + beforeScript = "export PATH=${params.fake_fragpipe_dir}/bin:\$PATH" + ext.fragpipe_tools_dir = "${params.fake_fragpipe_dir}/tools" + } +} diff --git a/subworkflows/local/fragpipe_headless_wf/main.nf b/subworkflows/local/fragpipe_headless_wf/main.nf index bbf4ba26..879febe3 100644 --- a/subworkflows/local/fragpipe_headless_wf/main.nf +++ b/subworkflows/local/fragpipe_headless_wf/main.nf @@ -26,9 +26,9 @@ workflow FRAGPIPE_HEADLESS_WF { ch_files // channel: [ val(meta), path(spectra) ] - sample files ch_database // channel: path(fasta) - FASTA database ch_workflow_file // channel: path(workflow) - FragPipe .workflow file - ch_manifest_content // channel: val(manifest_string) - TSV manifest content + ch_manifest_content // channel: val(manifest_string) - manifest (filename\texperiment\tbioreplicate\tdata_type), authoritative when non-empty ch_annotation_content // channel: val(annotation_string) - TMT annotation (experiment\tchannel\tsample_name), empty for LFQ - ch_file_experiment_map // channel: val(map_string) - file-to-experiment mapping (filename\texperiment), empty for LFQ + ch_file_experiment_map // channel: val(map_string) - file-to-experiment mapping (filename\texperiment), used only when the manifest is empty main: // diff --git a/subworkflows/local/fragpipe_headless_wf/meta.yml b/subworkflows/local/fragpipe_headless_wf/meta.yml index b212c172..5cb47f7b 100644 --- a/subworkflows/local/fragpipe_headless_wf/meta.yml +++ b/subworkflows/local/fragpipe_headless_wf/meta.yml @@ -33,7 +33,8 @@ input: - ch_manifest_content: type: channel description: | - TSV-formatted manifest content mapping spectra files to experiments. + TSV-formatted manifest content mapping spectra files to experiments + (file name, experiment, bioreplicate, data_type; no header). Authoritative when non-empty. Structure: val(manifest_string) - ch_annotation_content: type: channel @@ -44,8 +45,8 @@ input: - ch_file_experiment_map: type: channel description: | - File-to-experiment mapping (filename, experiment columns). - Pass empty string for LFQ workflows. + File-to-experiment mapping (file name, experiment columns). + Used only when ch_manifest_content is empty; pass an empty string otherwise. Structure: val(map_string) output: - all_results: diff --git a/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test b/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test index a7e9cef4..cb46e77b 100644 --- a/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test +++ b/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test @@ -26,7 +26,7 @@ nextflow_workflow { input[0] = channel.of([ [ id: 'test', mzml_id: 'test' ], raw_file ]) input[1] = channel.value(fasta_file) input[2] = channel.value(workflow_file) - input[3] = channel.value("sample.mzML\\texperiment1\\t1\\tDDA") + input[3] = channel.value("test.mzML\\texperiment1\\t1\\tDDA") // THERMORAWFILEPARSER names the mzML after meta.id input[4] = channel.value("") // No TMT annotation (LFQ mode) input[5] = channel.value("") // No file-experiment map (LFQ mode) """ diff --git a/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test.snap b/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test.snap index 69e63e88..69a60bd4 100644 --- a/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test.snap +++ b/subworkflows/local/fragpipe_headless_wf/tests/main.nf.test.snap @@ -18,6 +18,8 @@ "combined_ion.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "combined_peptide.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "combined_protein.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", + "experiment_annotation.tsv:md5,06327882b6286afe11a95dd992652b86", + "fragpipe-files.fp-manifest:md5,2a1def4e29fed5625a78459589607e67", "protein.tsv:md5,d41d8cd98f00b204e9800998ecf8427e", "psm.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] @@ -32,7 +34,7 @@ "combined_ion.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "timestamp": "2026-03-31T18:32:04.260052282", + "timestamp": "2026-09-29T00:00:00.000000000", "meta": { "nf-test": "0.9.5", "nextflow": "25.10.2" From 6ec81cf9745c38f8a018efe45accfd0ec2eb0d05 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 15:48:39 +0000 Subject: [PATCH 03/13] refactor: move FragPipe helper functions into utils_nfcore_msproteomics_pipeline `nf-core pipelines lint` (tools 3.5.2) crashed with `IndexError: list index out of range` in nf_core/subworkflows/lint/main_nf.py (`self.workflow_name = lines[0].split()[1]`): every entry in subworkflows/local/ is linted as a local subworkflow, and subworkflows/local/fragpipe_utils.nf is a functions-only file with no `workflow` block, so no workflow line was ever collected. It crashes the same way on unmodified dev. - Move shouldRunTool, getToolArgs, getToolModmasses, getToolField, getToolReportArgs and generateFragpipeManifest into the FUNCTIONS section of subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf, using fully-qualified groovy.json names (strict syntax rejects `import`). - Repoint all includes; delete subworkflows/local/fragpipe_utils.nf. - Delete lib/FragpipeUtils.nf: an unused, never-included stale copy. --- CHANGELOG.md | 1 + docs/modules/parse_fragpipe_workflow.md | 2 +- lib/FragpipeUtils.nf | 96 --------------- subworkflows/local/fragpipe/main.nf | 2 +- subworkflows/local/fragpipe_convert/main.nf | 2 +- subworkflows/local/fragpipe_export/main.nf | 2 +- subworkflows/local/fragpipe_glyco/main.nf | 2 +- subworkflows/local/fragpipe_inference/main.nf | 2 +- subworkflows/local/fragpipe_ptm/main.nf | 2 +- subworkflows/local/fragpipe_quant/main.nf | 2 +- subworkflows/local/fragpipe_search/main.nf | 2 +- subworkflows/local/fragpipe_speclib/main.nf | 2 +- subworkflows/local/fragpipe_utils.nf | 116 ------------------ subworkflows/local/fragpipe_validate/main.nf | 2 +- .../main.nf | 106 ++++++++++++++++ workflows/fragpipe.nf | 5 +- 16 files changed, 119 insertions(+), 227 deletions(-) delete mode 100644 lib/FragpipeUtils.nf delete mode 100644 subworkflows/local/fragpipe_utils.nf diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e4e99e..005b6810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `FRAGPIPE_HEADLESS`: single-plex TMT files are placed in `raw_files//` like multi-plex ones. - `FRAGPIPE_HEADLESS` stub writes `results/fragpipe-files.fp-manifest` and `results/experiment_annotation.tsv`. +- FragPipe helper functions (`shouldRunTool`, `getToolArgs`, `getToolModmasses`, `getToolField`, `getToolReportArgs`, `generateFragpipeManifest`) moved from `subworkflows/local/fragpipe_utils.nf` into `subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf`; `nf-core pipelines lint` crashed (`IndexError` in the subworkflow `main_nf` check) on the functions-only file. The unused duplicate `lib/FragpipeUtils.nf` is removed. ## v1.0.0 - Initial Release diff --git a/docs/modules/parse_fragpipe_workflow.md b/docs/modules/parse_fragpipe_workflow.md index 0586716a..14926856 100644 --- a/docs/modules/parse_fragpipe_workflow.md +++ b/docs/modules/parse_fragpipe_workflow.md @@ -45,7 +45,7 @@ The JSON output includes run flags, args, and config_type for each tool, enablin ## Usage Used in the `FRAGPIPE` subworkflow (`subworkflows/local/fragpipe/main.nf`) and `TMT_LABELCHECK` subworkflow (`subworkflows/local/tmt_labelcheck/main.nf`) to parse `.workflow` files into tool-specific configs that drive downstream module execution. -Also used via the `fragpipe_utils.nf` helper subworkflow. +Its `tool_configs` JSON is read by the helper functions (`shouldRunTool`, `getToolArgs`, ...) in `subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf`. ## References diff --git a/lib/FragpipeUtils.nf b/lib/FragpipeUtils.nf deleted file mode 100644 index 5f112642..00000000 --- a/lib/FragpipeUtils.nf +++ /dev/null @@ -1,96 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FragPipe Utility Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Shared helper functions for FragPipe Nextflow subworkflows. - Import via: include { shouldRunTool; getToolArgs } from '../fragpipe_utils' - - These functions accept a JSON text string (from tool_configs value channel) - and parse it on demand. JSON parsing of the ~2-5KB config is microseconds, - so the overhead of repeated parsing is negligible. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -import groovy.json.JsonSlurper -import groovy.json.JsonParserType - -/** - * Check if a tool should run based on the tool_configs JSON string. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool to check (e.g., 'msfragger', 'msbooster') - * @return true if the tool should run, false otherwise - */ -def shouldRunTool(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.run ?: false -} - -/** - * Get the args string for a tool from the tool_configs JSON string. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Args string for the tool, or empty string if not found - */ -def getToolArgs(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.args ?: '' -} - -/** - * Get the modmasses string for a tool from the tool_configs JSON string. - * - * Used by IonQuant for --modlist (MBR modification mass tracking). - * Returns comma-separated modification masses, or empty string if not set. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Comma-separated modmasses string, or empty string if not found - */ -def getToolModmasses(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.modmasses ?: '' -} - -/** - * Get an arbitrary field value for a tool from the tool_configs JSON string. - * - * Used to extract individual algorithm parameters that the parser emits as - * separate JSON fields (e.g., FPOP's region_size, control_label). - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool (e.g., 'fpop') - * @param field_name Name of the field to retrieve (e.g., 'region_size') - * @param default_val Default value if the field is not found - * @return Field value as a string, or default_val if not found - */ -def getToolField(json_text, tool_name, field_name, default_val = '') { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.get(field_name) ?: default_val -} - -/** - * Get the report_args string for a tool from the tool_configs JSON string. - * - * Used by philosopher filter to pass report flags (--decoys, --removecontam) - * to the `philosopher report` command. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Report args string, or empty string if not found - */ -def getToolReportArgs(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.report_args ?: '' -} diff --git a/subworkflows/local/fragpipe/main.nf b/subworkflows/local/fragpipe/main.nf index 2a9b00e8..ee441409 100644 --- a/subworkflows/local/fragpipe/main.nf +++ b/subworkflows/local/fragpipe/main.nf @@ -31,7 +31,7 @@ include { PARSE_FRAGPIPE_WORKFLOW } from '../../../modules/local/parse_fragpipe_workflow/main' // Import utility functions -include { shouldRunTool } from '../fragpipe_utils' +include { shouldRunTool } from '../utils_nfcore_msproteomics_pipeline' // Import subworkflows include { FRAGPIPE_DATABASE } from '../fragpipe_database/main' diff --git a/subworkflows/local/fragpipe_convert/main.nf b/subworkflows/local/fragpipe_convert/main.nf index 820782e8..ac41dfae 100644 --- a/subworkflows/local/fragpipe_convert/main.nf +++ b/subworkflows/local/fragpipe_convert/main.nf @@ -16,7 +16,7 @@ include { THERMORAWFILEPARSER } from '../../../modules/nf-core/thermorawfileparser/main' include { DIAUMPIRE } from '../../../modules/local/diaumpire/main' include { DIATRACER } from '../../../modules/local/diatracer/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_CONVERT { take: diff --git a/subworkflows/local/fragpipe_export/main.nf b/subworkflows/local/fragpipe_export/main.nf index c04d2cce..3c346f8a 100644 --- a/subworkflows/local/fragpipe_export/main.nf +++ b/subworkflows/local/fragpipe_export/main.nf @@ -18,7 +18,7 @@ include { SKYLINE } from '../../../modules/local/skyline/main' include { SAINTEXPRESS } from '../../../modules/local/saintexpress/main' include { FPOP } from '../../../modules/local/fpop/main' include { METAPROTEOMICS } from '../../../modules/local/metaproteomics/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_EXPORT { take: diff --git a/subworkflows/local/fragpipe_glyco/main.nf b/subworkflows/local/fragpipe_glyco/main.nf index fb8b27fe..0d646693 100644 --- a/subworkflows/local/fragpipe_glyco/main.nf +++ b/subworkflows/local/fragpipe_glyco/main.nf @@ -14,7 +14,7 @@ include { MBG } from '../../../modules/local/mbg/main' include { OPAIR } from '../../../modules/local/opair/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_GLYCO { take: diff --git a/subworkflows/local/fragpipe_inference/main.nf b/subworkflows/local/fragpipe_inference/main.nf index 89069fc3..b1f45acb 100644 --- a/subworkflows/local/fragpipe_inference/main.nf +++ b/subworkflows/local/fragpipe_inference/main.nf @@ -14,7 +14,7 @@ include { PROTEINPROPHET } from '../../../modules/local/philosopher/proteinprophet/main' include { PHILOSOPHER_FILTER } from '../../../modules/local/philosopher/filter/main' -include { shouldRunTool; getToolArgs; getToolReportArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs; getToolReportArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_INFERENCE { take: diff --git a/subworkflows/local/fragpipe_ptm/main.nf b/subworkflows/local/fragpipe_ptm/main.nf index 38b58df8..9e033fb7 100644 --- a/subworkflows/local/fragpipe_ptm/main.nf +++ b/subworkflows/local/fragpipe_ptm/main.nf @@ -12,7 +12,7 @@ */ include { PTMSHEPHERD } from '../../../modules/local/ptmshepherd/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_PTM { take: diff --git a/subworkflows/local/fragpipe_quant/main.nf b/subworkflows/local/fragpipe_quant/main.nf index 2428618a..3c4d3b35 100644 --- a/subworkflows/local/fragpipe_quant/main.nf +++ b/subworkflows/local/fragpipe_quant/main.nf @@ -22,7 +22,7 @@ include { TMTINTEGRATOR } from '../../../modules/local/tmtintegrator/ include { FREEQUANT } from '../../../modules/local/freequant/main' include { PHILOSOPHER_LABELQUANT } from '../../../modules/local/philosopher/labelquant/main' include { PHILOSOPHER_REPORT } from '../../../modules/local/philosopher/report/main' -include { shouldRunTool; getToolArgs; getToolModmasses; getToolReportArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs; getToolModmasses; getToolReportArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_QUANT { take: diff --git a/subworkflows/local/fragpipe_search/main.nf b/subworkflows/local/fragpipe_search/main.nf index 912a352b..7b1b9345 100644 --- a/subworkflows/local/fragpipe_search/main.nf +++ b/subworkflows/local/fragpipe_search/main.nf @@ -35,7 +35,7 @@ include { SPLIT_FASTA } from '../../../modules/local/split_fasta/main' include { MERGE_SPLIT_SEARCH } from '../../../modules/local/merge_split_search/main' include { MSBOOSTER } from '../../../modules/local/msbooster/main' include { CRYSTALC } from '../../../modules/local/crystalc/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_SEARCH { take: diff --git a/subworkflows/local/fragpipe_speclib/main.nf b/subworkflows/local/fragpipe_speclib/main.nf index 941015f1..8e6d291d 100644 --- a/subworkflows/local/fragpipe_speclib/main.nf +++ b/subworkflows/local/fragpipe_speclib/main.nf @@ -12,7 +12,7 @@ */ include { SPECLIBGEN } from '../../../modules/local/speclibgen/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_SPECLIB { take: diff --git a/subworkflows/local/fragpipe_utils.nf b/subworkflows/local/fragpipe_utils.nf deleted file mode 100644 index 05905aab..00000000 --- a/subworkflows/local/fragpipe_utils.nf +++ /dev/null @@ -1,116 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FragPipe Utility Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Shared helper functions for FragPipe Nextflow subworkflows. - Import via: include { shouldRunTool; getToolArgs } from '../fragpipe_utils' - - These functions accept a JSON text string (from tool_configs value channel) - and parse it on demand. JSON parsing of the ~2-5KB config is microseconds, - so the overhead of repeated parsing is negligible. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -import groovy.json.JsonSlurper -import groovy.json.JsonParserType - -/** - * Check if a tool should run based on the tool_configs JSON string. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool to check (e.g., 'msfragger', 'msbooster') - * @return true if the tool should run, false otherwise - */ -def shouldRunTool(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.run ?: false -} - -/** - * Get the args string for a tool from the tool_configs JSON string. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Args string for the tool, or empty string if not found - */ -def getToolArgs(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.args ?: '' -} - -/** - * Get the modmasses string for a tool from the tool_configs JSON string. - * - * Used by IonQuant for --modlist (MBR modification mass tracking). - * Returns comma-separated modification masses, or empty string if not set. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Comma-separated modmasses string, or empty string if not found - */ -def getToolModmasses(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.modmasses ?: '' -} - -/** - * Get an arbitrary field value for a tool from the tool_configs JSON string. - * - * Used to extract individual algorithm parameters that the parser emits as - * separate JSON fields (e.g., FPOP's region_size, control_label). - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool (e.g., 'fpop') - * @param field_name Name of the field to retrieve (e.g., 'region_size') - * @param default_val Default value if the field is not found - * @return Field value as a string, or default_val if not found - */ -def getToolField(json_text, tool_name, field_name, default_val = '') { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.get(field_name) ?: default_val -} - -/** - * Get the report_args string for a tool from the tool_configs JSON string. - * - * Used by philosopher filter to pass report flags (--decoys, --removecontam) - * to the `philosopher report` command. - * - * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel - * @param tool_name Name of the tool - * @return Report args string, or empty string if not found - */ -def getToolReportArgs(json_text, tool_name) { - def configs = new JsonSlurper() - .setType(JsonParserType.CHARACTER_SOURCE) - .parseText(json_text) - return configs?.get(tool_name)?.report_args ?: '' -} - -/** - * Generate a FragPipe manifest from a list of [group, filename] entries. - * Determines bioreplicate assignment based on fractionation grouping: - * files that share a group (fractionated) get empty bioreplicate, - * files with unique groups get bioreplicate = 1. - * - * @param entries List of [group, filename] pairs - * @param data_type Data type string (e.g., 'DDA', 'DDA+') - * @return Tab-separated manifest string - */ -def generateFragpipeManifest(entries, data_type) { - def group_counts = entries.countBy { it[0] } - return entries.collect { entry -> - def group = entry[0] - def fname = entry[1] - def biorep = group_counts[group] > 1 ? '' : '1' - "${fname}\t${group}\t${biorep}\t${data_type}" - }.join('\n') -} diff --git a/subworkflows/local/fragpipe_validate/main.nf b/subworkflows/local/fragpipe_validate/main.nf index 68032337..c56953ba 100644 --- a/subworkflows/local/fragpipe_validate/main.nf +++ b/subworkflows/local/fragpipe_validate/main.nf @@ -16,7 +16,7 @@ include { PERCOLATOR } from '../../../modules/local/percolator/main' include { PEPTIDEPROPHET } from '../../../modules/local/philosopher/peptideprophet/main' include { PTMPROPHET } from '../../../modules/local/ptmprophet/main' -include { shouldRunTool; getToolArgs } from '../fragpipe_utils' +include { shouldRunTool; getToolArgs } from '../utils_nfcore_msproteomics_pipeline' workflow FRAGPIPE_VALIDATE { take: diff --git a/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf b/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf index 68313c67..3b96aae5 100644 --- a/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf @@ -286,3 +286,109 @@ def methodsDescriptionText(mqc_methods_yaml) { return description_html.toString() } + +// +// FragPipe tool_configs helpers: each accepts the JSON text string emitted by the +// PARSE_FRAGPIPE_WORKFLOW tool_configs value channel and parses it on demand +// (~2-5KB, microseconds per parse). +// +/** + * Check if a tool should run based on the tool_configs JSON string. + * + * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel + * @param tool_name Name of the tool to check (e.g., 'msfragger', 'msbooster') + * @return true if the tool should run, false otherwise + */ +def shouldRunTool(json_text, tool_name) { + def configs = new groovy.json.JsonSlurper() + .setType(groovy.json.JsonParserType.CHARACTER_SOURCE) + .parseText(json_text) + return configs?.get(tool_name)?.run ?: false +} + +/** + * Get the args string for a tool from the tool_configs JSON string. + * + * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel + * @param tool_name Name of the tool + * @return Args string for the tool, or empty string if not found + */ +def getToolArgs(json_text, tool_name) { + def configs = new groovy.json.JsonSlurper() + .setType(groovy.json.JsonParserType.CHARACTER_SOURCE) + .parseText(json_text) + return configs?.get(tool_name)?.args ?: '' +} + +/** + * Get the modmasses string for a tool from the tool_configs JSON string. + * + * Used by IonQuant for --modlist (MBR modification mass tracking). + * Returns comma-separated modification masses, or empty string if not set. + * + * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel + * @param tool_name Name of the tool + * @return Comma-separated modmasses string, or empty string if not found + */ +def getToolModmasses(json_text, tool_name) { + def configs = new groovy.json.JsonSlurper() + .setType(groovy.json.JsonParserType.CHARACTER_SOURCE) + .parseText(json_text) + return configs?.get(tool_name)?.modmasses ?: '' +} + +/** + * Get an arbitrary field value for a tool from the tool_configs JSON string. + * + * Used to extract individual algorithm parameters that the parser emits as + * separate JSON fields (e.g., FPOP's region_size, control_label). + * + * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel + * @param tool_name Name of the tool (e.g., 'fpop') + * @param field_name Name of the field to retrieve (e.g., 'region_size') + * @param default_val Default value if the field is not found + * @return Field value as a string, or default_val if not found + */ +def getToolField(json_text, tool_name, field_name, default_val = '') { + def configs = new groovy.json.JsonSlurper() + .setType(groovy.json.JsonParserType.CHARACTER_SOURCE) + .parseText(json_text) + return configs?.get(tool_name)?.get(field_name) ?: default_val +} + +/** + * Get the report_args string for a tool from the tool_configs JSON string. + * + * Used by philosopher filter to pass report flags (--decoys, --removecontam) + * to the `philosopher report` command. + * + * @param json_text JSON string from PARSE_FRAGPIPE_WORKFLOW tool_configs channel + * @param tool_name Name of the tool + * @return Report args string, or empty string if not found + */ +def getToolReportArgs(json_text, tool_name) { + def configs = new groovy.json.JsonSlurper() + .setType(groovy.json.JsonParserType.CHARACTER_SOURCE) + .parseText(json_text) + return configs?.get(tool_name)?.report_args ?: '' +} + +/** + * Generate a FragPipe manifest from a list of [group, filename] entries. + * Determines bioreplicate assignment based on fractionation grouping: + * files that share a group (fractionated) get empty bioreplicate, + * files with unique groups get bioreplicate = 1. + * + * @param entries List of [group, filename] pairs + * @param data_type Data type string (e.g., 'DDA', 'DDA+') + * @return Tab-separated manifest string + */ +def generateFragpipeManifest(entries, data_type) { + def group_counts = entries.countBy { it[0] } + return entries.collect { entry -> + def group = entry[0] + def fname = entry[1] + def biorep = group_counts[group] > 1 ? '' : '1' + "${fname}\t${group}\t${biorep}\t${data_type}" + }.join('\n') +} diff --git a/workflows/fragpipe.nf b/workflows/fragpipe.nf index a1f66cd6..4ba4d2da 100644 --- a/workflows/fragpipe.nf +++ b/workflows/fragpipe.nf @@ -12,7 +12,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' -include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_msproteomics_pipeline' +include { methodsDescriptionText; generateFragpipeManifest } from '../subworkflows/local/utils_nfcore_msproteomics_pipeline' // SDRF generation (bookkeeping only) include { GENERATE_SDRF_FROM_SAMPLESHEET } from '../modules/local/generate_sdrf_from_samplesheet/main' @@ -21,9 +21,6 @@ include { GENERATE_SDRF_FROM_SAMPLESHEET } from '../modules/local/generate_sdrf_ include { FRAGPIPE_WF as FRAGPIPE_PIPELINE } from '../subworkflows/local/fragpipe/main' include { FRAGPIPE_HEADLESS_WF } from '../subworkflows/local/fragpipe_headless_wf/main' -// FragPipe utilities -include { generateFragpipeManifest } from '../subworkflows/local/fragpipe_utils' - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HELPER FUNCTIONS From 6fb89c7b50979cdeb7e39e4c55d97535d2b7afee Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 15:48:39 +0000 Subject: [PATCH 04/13] chore: sync ro-crate-metadata.json description with README nf-core's rocrate_readme_sync lint check compares the RO-Crate description with README.md; the committed description was stale. --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 0d75ba7e..5dc9cabc 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "InProgress", "datePublished": "2026-03-22T02:20:14+00:00", - "description": "

\n \n \n \"nf-core/msproteomics\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/msproteomics)\n[![GitHub Actions CI Status](https://github.com/nf-core/msproteomics/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/msproteomics/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/msproteomics/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/msproteomics/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/msproteomics/results)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/msproteomics)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23msproteomics-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/msproteomics)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/msproteomics** is a bioinformatics pipeline for mass spectrometry-based proteomics preprocessing.\nIt accepts raw instrument data with a CSV samplesheet and produces quantified protein/peptide/ion matrices ready for downstream statistical analysis.\nThe pipeline supports multiple acquisition strategies through dedicated workflow types:\n\n- **DIA** (Data-Independent Acquisition) -- analyzed with [DIA-NN](https://github.com/vdemichev/DiaNN), with optional MSstats and MaxLFQ quantification\n- **DDA LFQ** (Data-Dependent Acquisition, Label-Free Quantification) -- analyzed with the [FragPipe](https://fragpipe.nesvilab.org/) computational platform (MSFragger, MSBooster, Percolator, IonQuant)\n- **TMT Label Check** -- TMT labeling efficiency QC using FragPipe search followed by label incorporation analysis\n- **Generic FragPipe** -- fully configurable FragPipe workflows driven by `.workflow` files\n\nInstrument-specific settings are applied via optional config files (`-c conf/instruments/*.config`).\n\n## Analysis Modes\n\nThe `--mode` parameter selects the analysis engine.\nFragPipe sub-modes are controlled with `--tmt_mode` for TMT workflows.\n\n| Mode | Sub-mode | Description | Engine |\n| --- | --- | --- | --- |\n| `diann` | -- | DIA quantitative proteomics (standard, phospho) | [DIA-NN](https://github.com/vdemichev/DiaNN) |\n| `fragpipe` | *(none)* | Generic FragPipe workflows, configured by [workflow files](https://github.com/Nesvilab/FragPipe/tree/develop/workflows) | [FragPipe](https://fragpipe.nesvilab.org/) |\n| `fragpipe` | `--tmt_mode labelcheck` | TMT labeling efficiency QC | [FragPipe](https://fragpipe.nesvilab.org/) |\n| `fragpipe` | `--tmt_mode quant` | TMT isobaric quantification | [FragPipe](https://fragpipe.nesvilab.org/) |\n\nDIA method variants (phospho) and instrument-specific settings are applied via `-c` config files.\nSee [docs/usage.md](docs/usage.md) for full details.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow.\n> Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a CSV samplesheet describing your samples:\n\n```csv\nsample,spectra\nSample1,/path/to/sample1.raw\nSample2,/path/to/sample2.raw\nSample3,/path/to/sample3.raw\n```\n\nOptional columns: `condition` (experimental group), `label` (TMT channel, e.g. TMT126), `fraction` (fraction number). If present, these are parsed automatically.\n\nThen run the pipeline:\n\n```bash\n# DIA analysis\nnextflow run nf-core/msproteomics \\\n --mode diann \\\n --input samplesheet.csv \\\n --database /path/to/database.fasta \\\n --outdir results \\\n -profile docker\n\n# FragPipe DDA LFQ analysis\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --fragpipe_workflow LFQ-MBR.workflow \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -profile docker\n\n# TMT label check (TMT18 example — choose tmtlbl6/10/11/16/18/pro)\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --tmt_mode labelcheck \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -c conf/tmt/tmt18.config \\\n -profile docker\n\n# TMT quantification (TMT18 example)\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --tmt_mode quant \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -c conf/tmt/tmt18.config \\\n -profile docker\n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option.\n> Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](docs/usage.md) and the [parameter documentation](https://nf-co.re/msproteomics/parameters).\n\n## Pipeline Output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/msproteomics/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the [output documentation](docs/output.md).\n\n## FragPipe License\n\nFragPipe-based workflows (DDA LFQ, TMT Label Check, generic FragPipe) require a [FragPipe](https://fragpipe.nesvilab.org/) installation with a valid license.\nFragPipe is free for academic use; commercial users must obtain a license from the University of Michigan.\nYou must build or provide a Docker/Singularity container that includes FragPipe, MSFragger, IonQuant, and Philosopher under your own license terms.\n\n## Documentation\n\n- [Usage guide](docs/usage.md) -- full parameter reference and workflow examples\n- [Output documentation](docs/output.md) -- description of pipeline output files and reports\n- [Module documentation](docs/modules/README.md) -- per-module reference for all local modules\n- [Docker build instructions](docs/fragpipe-docker/README.md) -- building the FragPipe container image\n\n## Credits\n\nnf-core/msproteomics was originally written by Dongze He ([@dongzehe](https://github.com/dongzehe)).\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- The [quantms](https://github.com/bigbio/quantms) team for the quantms-utils tools and DIA proteomics analysis subworkflow\n- The [Nesvizhskii Lab](https://nesvilab.org/) for the FragPipe computational platform\n- The [DIA-NN](https://github.com/vdemichev/DiaNN) developers\n- The [nf-core](https://nf-co.re) community\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#msproteomics` channel](https://nfcore.slack.com/channels/msproteomics) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/msproteomics for your analysis, please cite it using the nf-core publication.\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

\n \n \n \"nf-core/msproteomics\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/msproteomics)\n[![GitHub Actions CI Status](https://github.com/nf-core/msproteomics/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/msproteomics/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/msproteomics/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/msproteomics/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/msproteomics/results)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/msproteomics)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23msproteomics-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/msproteomics)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/msproteomics** is a bioinformatics pipeline for mass spectrometry-based proteomics preprocessing.\nIt accepts raw instrument data with a CSV samplesheet and produces quantified protein/peptide/ion matrices ready for downstream statistical analysis.\nThe pipeline supports multiple acquisition strategies through dedicated workflow types:\n\n- **DIA** (Data-Independent Acquisition) -- analyzed with [DIA-NN](https://github.com/vdemichev/DiaNN), with optional MSstats and MaxLFQ quantification\n- **DDA LFQ** (Data-Dependent Acquisition, Label-Free Quantification) -- analyzed with the [FragPipe](https://fragpipe.nesvilab.org/) computational platform (MSFragger, MSBooster, Percolator, IonQuant)\n- **TMT Label Check** -- TMT labeling efficiency QC using FragPipe search followed by label incorporation analysis\n- **Generic FragPipe** -- fully configurable FragPipe workflows driven by `.workflow` files\n\nInstrument-specific settings are applied via optional config files (`-c conf/instruments/*.config`).\n\n## Analysis Modes\n\nThe `--mode` parameter selects the analysis engine.\nFragPipe sub-modes are controlled with `--tmt_mode` for TMT workflows.\n\n| Mode | Sub-mode | Description | Engine |\n| --- | --- | --- | --- |\n| `diann` | -- | DIA quantitative proteomics (standard, phospho) | [DIA-NN](https://github.com/vdemichev/DiaNN) |\n| `fragpipe` | *(none)* | Generic FragPipe workflows, configured by [workflow files](https://github.com/Nesvilab/FragPipe/tree/develop/workflows) | [FragPipe](https://fragpipe.nesvilab.org/) |\n| `fragpipe` | `--tmt_mode labelcheck` | TMT labeling efficiency QC | [FragPipe](https://fragpipe.nesvilab.org/) |\n| `fragpipe` | `--tmt_mode quant` | TMT isobaric quantification | [FragPipe](https://fragpipe.nesvilab.org/) |\n\nDIA method variants (e.g., phospho) and instrument-specific settings are applied via `-c` config files.\nSee [docs/usage.md](docs/usage.md) for full details.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow.\n> Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a CSV samplesheet describing your samples:\n\n```csv\nsample,spectra\nSample1,/path/to/sample1.raw\nSample2,/path/to/sample2.raw\nSample3,/path/to/sample3.raw\n```\n\nOptional columns: `condition` (experimental group), `label` (TMT channel, e.g. TMT126), `fraction` (fraction number). If present, these are parsed automatically.\n\nThen run the pipeline:\n\n```bash\n# DIA analysis\nnextflow run nf-core/msproteomics \\\n --mode diann \\\n --input samplesheet.csv \\\n --database /path/to/database.fasta \\\n --outdir results \\\n -profile docker\n\n# FragPipe DDA LFQ analysis\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --fragpipe_workflow LFQ-MBR.workflow \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -profile docker\n\n# TMT label check (TMT18 example)\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --tmt_mode labelcheck \\\n --tmt_type TMT18 \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -profile docker\n\n# TMT quantification (TMT18 example)\nnextflow run nf-core/msproteomics \\\n --mode fragpipe \\\n --fragpipe_container your-registry/fragpipe:24.0 \\\n --tmt_mode quant \\\n --tmt_type TMT18 \\\n --fragpipe_workflow /path/to/TMT-quant.workflow \\\n --input samplesheet.csv \\\n --database /path/to/uniprot_human.fasta \\\n --outdir results \\\n -profile docker\n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option.\n> Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](docs/usage.md) and the [parameter documentation](https://nf-co.re/msproteomics/parameters).\n\n## Pipeline Output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/msproteomics/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the [output documentation](docs/output.md).\n\n## FragPipe License\n\nFragPipe-based workflows (DDA LFQ, TMT Label Check, generic FragPipe) require a [FragPipe](https://fragpipe.nesvilab.org/) installation with a valid license.\nFragPipe is free for academic use; commercial users must obtain a license from the University of Michigan.\nYou must build or provide a Docker/Singularity container that includes FragPipe, MSFragger, IonQuant, and Philosopher under your own license terms.\n\n## Documentation\n\n- [Usage guide](docs/usage.md) -- full parameter reference and workflow examples\n- [Output documentation](docs/output.md) -- description of pipeline output files and reports\n- [Module documentation](docs/modules/README.md) -- per-module reference for all local modules\n- [Docker build instructions](docs/fragpipe-docker/README.md) -- building the FragPipe container image\n\n## Credits\n\nThe pipeline was originally created by [Dongze He](https://github.com/DongzeHE) and is maintained and developed by [Dongze He](https://github.com/DongzeHE) and [Fengchao Yu](https://github.com/fcyu).\n\nThe DIA-NN workflow is inherited from [quantms](https://github.com/bigbio/quantms), developed by the [bigbio](https://github.com/bigbio) community.\n\nThe advisory team includes Dr. Stefka Tyanova (Altos Labs), Dr. Daniel Itzhak (Altos Labs), Dr. Felix Krueger (Altos Labs), and [Dr. Alexey I. Nesvizhskii](https://medschool.umich.edu/profile/3401/alexey-nesvizhskii) (University of Michigan Medical School).\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#msproteomics` channel](https://nfcore.slack.com/channels/msproteomics) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/msproteomics for your analysis, please cite it using the nf-core publication and the underlying tools.\n\n### Underlying Tools\n\nPlease cite the tools used by this pipeline depending on the workflow you run:\n\n**FragPipe** (DDA LFQ, TMT workflows):\nSee the full list of key references at [FragPipe GitHub](https://github.com/Nesvilab/FragPipe#key-references), including MSFragger, Philosopher, IonQuant, and TMT-Integrator.\n\n**DIA-NN** (DIA workflows):\nSee the key publications at [DIA-NN GitHub](https://github.com/vdemichev/diann#key-publications).\n\nAn extensive list of references for all tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\n### nf-core\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 4ec3617507d9a5946b9508817b4313088c01f6ea Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 16:40:47 +0000 Subject: [PATCH 05/13] fix: resolve nf-core pipelines lint failures - nextflow_config: params.diann_additional_analysis_args = null in nextflow.config and no schema default (nf-core fetch_wf_config maps a config '' to "null", so '' vs "" can never match); consumers in conf/modules.config all use `?: ''`, so behaviour is unchanged. - nextflow_config / schema_params: drop max_cpus, max_memory, max_time from nextflow_schema.json and the test profile; limits come from process.resourceLimits and no code reads params.max_*. - schema_params: drop params.proteomes = null from conf/reference_proteomes_ignored.config; nothing reads params.proteomes. - check_local_copy (utils_nfcore_pipeline): restore tests/main.nf.test to nf-core/modules f0b535b and remove the stale tests/main.workflow.nf.test (+ snap), renamed upstream in that commit. The remaining main.nf delta (imNotification kept for hook_url) must be recorded with `nf-core subworkflows patch utils_nfcore_pipeline`. --- CHANGELOG.md | 4 +++ conf/reference_proteomes_ignored.config | 1 - nextflow.config | 5 +--- nextflow_schema.json | 27 ----------------- .../utils_nfcore_pipeline/tests/main.nf.test | 2 +- .../tests/main.workflow.nf.test | 29 ------------------- .../tests/main.workflow.nf.test.snap | 19 ------------ 7 files changed, 6 insertions(+), 81 deletions(-) delete mode 100644 subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test delete mode 100644 subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 005b6810..15250349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `FRAGPIPE_HEADLESS`: file names are matched exactly against the manifest (or `file_experiment_map`) first column; the substring lookup (`grep -F`) gave `A1.mzML` the experiment of `XA1.mzML`. - `FRAGPIPE_HEADLESS`: the task fails loudly when a staged file has no row, a row names an unstaged file, a file is listed twice, a TMT file's experiment is not in `annotation_content`, or both `manifest_content` and `file_experiment_map` are empty (TMT files were silently dropped before). - `FRAGPIPE_HEADLESS`: `versions.yml` no longer carries a stray `END_VERSIONS` line when a multi-line value was pasted into the script (inputs are now passed base64-encoded, so no value can break indentation or expand in bash). +- `nf-core pipelines lint`: `params.diann_additional_analysis_args` defaults to `null` (schema has no default); nf-core reads a config `''` as `null`, so `''` could never match the schema. All consumers use `?: ''`, so behaviour is unchanged. +- `nf-core pipelines lint`: removed the `max_cpus` / `max_memory` / `max_time` schema params and the `test` profile's `params.max_*`; resource caps are set by `process.resourceLimits`, and nothing read the params. +- `nf-core pipelines lint`: removed `params.proteomes = null` from `conf/reference_proteomes_ignored.config`; no code reads `params.proteomes`. +- `utils_nfcore_pipeline`: tests match the installed nf-core/modules commit (`tests/main.nf.test` restored; stale `tests/main.workflow.nf.test` and its snapshot removed). ### Changed diff --git a/conf/reference_proteomes_ignored.config b/conf/reference_proteomes_ignored.config index e25459e1..d90874ee 100644 --- a/conf/reference_proteomes_ignored.config +++ b/conf/reference_proteomes_ignored.config @@ -8,5 +8,4 @@ params { proteomes_base = null - proteomes = null } diff --git a/nextflow.config b/nextflow.config index 33528f8f..e1061076 100644 --- a/nextflow.config +++ b/nextflow.config @@ -100,7 +100,7 @@ params { // DIA-NN workflow control diann_skip_preliminary_analysis = false - diann_additional_analysis_args = '' + diann_additional_analysis_args = null // DIA-NN workflow metadata (used for SDRF generation) acquisition_method = 'dia' @@ -326,9 +326,6 @@ profiles { } test { params.test_mode = true - params.max_cpus = 2 - params.max_memory = '6.GB' - params.max_time = '1.h' process { resourceLimits = [ cpus: 2, memory: 6.GB, time: 1.h ] diff --git a/nextflow_schema.json b/nextflow_schema.json index 47e950bd..7018a8b6 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -318,7 +318,6 @@ }, "diann_additional_analysis_args": { "type": "string", - "default": "", "description": "Additional DIA-NN command-line arguments for the main analysis step.", "help_text": "Any additional DIA-NN flags to pass during the main analysis. Appended to the command after all other arguments.", "fa_icon": "fas fa-plus" @@ -981,32 +980,6 @@ "show_hidden": { "type": "boolean", "description": "Display hidden parameters in the help message (only works when --help or --help_full are provided)." - }, - "max_cpus": { - "type": "integer", - "description": "Maximum number of CPUs that can be requested for any single job.", - "default": 96, - "fa_icon": "fas fa-microchip", - "hidden": true, - "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. --max_cpus 16" - }, - "max_memory": { - "type": "string", - "description": "Maximum amount of memory that can be requested for any single job.", - "default": "760.GB", - "fa_icon": "fas fa-memory", - "hidden": true, - "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. --max_memory 128.GB", - "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$" - }, - "max_time": { - "type": "string", - "description": "Maximum amount of time that can be requested for any single job.", - "default": "72.h", - "fa_icon": "far fa-clock", - "hidden": true, - "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. --max_time 240.h", - "pattern": "^(\\d+\\.?\\s*(s|m|h|d|day)\\s*)+$" } } } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test index 9c8b09b5..8940d32d 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test @@ -22,7 +22,7 @@ nextflow_workflow { then { assertAll( { assert workflow.success }, - { assert snapshot(workflow.out.valid_config).match() } + { assert snapshot(workflow.out).match() } ) } } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test deleted file mode 100644 index 8940d32d..00000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test +++ /dev/null @@ -1,29 +0,0 @@ -nextflow_workflow { - - name "Test Workflow UTILS_NFCORE_PIPELINE" - script "../main.nf" - config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config" - workflow "UTILS_NFCORE_PIPELINE" - tag "subworkflows" - tag "subworkflows_nfcore" - tag "utils_nfcore_pipeline" - tag "subworkflows/utils_nfcore_pipeline" - - test("Should run without failures") { - - when { - workflow { - """ - input[0] = [] - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert snapshot(workflow.out).match() } - ) - } - } -} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap deleted file mode 100644 index 859d1030..00000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Should run without failures": { - "content": [ - { - "0": [ - true - ], - "valid_config": [ - true - ] - } - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-28T12:03:25.726491" - } -} \ No newline at end of file From ff2b7e37b5024b9d1493d79b065ab9c25afb1465 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 16:43:21 +0000 Subject: [PATCH 06/13] chore: record utils_nfcore_pipeline local edit as an nf-core patch main.nf re-adds imNotification (removed upstream in nf-core/modules f0b535b), which the hook_url feature needs; nf-core lint check_local_copy failed without a recorded patch. --- modules.json | 3 +- .../utils_nfcore_pipeline.diff | 70 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff diff --git a/modules.json b/modules.json index 24ec9588..d3ed0efb 100644 --- a/modules.json +++ b/modules.json @@ -79,7 +79,8 @@ "git_sha": "f0b535b3ae20080f8db03dd5388876ad1ec29d70", "installed_by": [ "subworkflows" - ] + ], + "patch": "subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff" }, "utils_nfschema_plugin": { "branch": "master", diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff b/subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff new file mode 100644 index 00000000..8470b135 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff @@ -0,0 +1,70 @@ +Changes in component 'nf-core/utils_nfcore_pipeline' +'subworkflows/nf-core/utils_nfcore_pipeline/meta.yml' is unchanged +Changes in 'utils_nfcore_pipeline/main.nf': +--- subworkflows/nf-core/utils_nfcore_pipeline/main.nf ++++ subworkflows/nf-core/utils_nfcore_pipeline/main.nf +@@ -353,3 +353,57 @@ + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") + } + } ++ ++// ++// Construct and send a notification to a web server as JSON (e.g. Microsoft Teams and Slack) ++// ++def imNotification(summary_params, hook_url) { ++ def summary = [:] ++ summary_params ++ .keySet() ++ .sort() ++ .each { group -> ++ summary << summary_params[group] ++ } ++ ++ def misc_fields = [:] ++ misc_fields['start'] = workflow.start ++ misc_fields['complete'] = workflow.complete ++ misc_fields['scriptfile'] = workflow.scriptFile ++ misc_fields['scriptid'] = workflow.scriptId ++ if (workflow.repository) misc_fields['repository'] = workflow.repository ++ if (workflow.commitId) misc_fields['commitid'] = workflow.commitId ++ if (workflow.revision) misc_fields['revision'] = workflow.revision ++ misc_fields['nxf_version'] = workflow.nextflow.version ++ misc_fields['nxf_build'] = workflow.nextflow.build ++ misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp ++ ++ def msg_fields = [:] ++ msg_fields['version'] = getWorkflowVersion() ++ msg_fields['runName'] = workflow.runName ++ msg_fields['success'] = workflow.success ++ msg_fields['dateComplete'] = workflow.complete ++ msg_fields['duration'] = workflow.duration ++ msg_fields['exitStatus'] = workflow.exitStatus ++ msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') ++ msg_fields['errorReport'] = (workflow.errorReport ?: 'None') ++ msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") ++ msg_fields['projectDir'] = workflow.projectDir ++ msg_fields['summary'] = summary << misc_fields ++ ++ def engine = new groovy.text.GStringTemplateEngine() ++ def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" ++ def hf = new File("${workflow.projectDir}/assets/${json_path}") ++ def json_template = engine.createTemplate(hf).make(msg_fields) ++ def json_message = json_template.toString() ++ ++ def post = new URL(hook_url).openConnection() ++ post.setRequestMethod("POST") ++ post.setDoOutput(true) ++ post.setRequestProperty("Content-Type", "application/json") ++ post.getOutputStream().write(json_message.getBytes("UTF-8")) ++ def postRC = post.getResponseCode() ++ if (!postRC.equals(200)) { ++ log.warn(post.getErrorStream().getText()) ++ } ++} + +'subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test' is unchanged +'subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap' is unchanged +'subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test' is unchanged +'subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap' is unchanged +'subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config' is unchanged +************************************************************ From 5322de0eba0067a85ffbeee50fd1c7bb9245f401 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 16:43:21 +0000 Subject: [PATCH 07/13] chore: remove unused duplicate local utils subworkflows subworkflows/local/{utils_nfcore_pipeline,utils_nextflow_pipeline,utils_pipeline} were only included by each other; the pipeline uses the nf-core copies and utils_nfcore_msproteomics_pipeline (flagged by nf-core pipelines lint). --- .../local/utils_nextflow_pipeline/main.nf | 111 ----- .../local/utils_nextflow_pipeline/meta.yml | 28 -- .../local/utils_nfcore_pipeline/main.nf | 420 ------------------ .../local/utils_nfcore_pipeline/meta.yml | 19 - subworkflows/local/utils_pipeline/main.nf | 151 ------- subworkflows/local/utils_pipeline/meta.yml | 41 -- 6 files changed, 770 deletions(-) delete mode 100644 subworkflows/local/utils_nextflow_pipeline/main.nf delete mode 100644 subworkflows/local/utils_nextflow_pipeline/meta.yml delete mode 100644 subworkflows/local/utils_nfcore_pipeline/main.nf delete mode 100644 subworkflows/local/utils_nfcore_pipeline/meta.yml delete mode 100644 subworkflows/local/utils_pipeline/main.nf delete mode 100644 subworkflows/local/utils_pipeline/meta.yml diff --git a/subworkflows/local/utils_nextflow_pipeline/main.nf b/subworkflows/local/utils_nextflow_pipeline/main.nf deleted file mode 100644 index a453cb3a..00000000 --- a/subworkflows/local/utils_nextflow_pipeline/main.nf +++ /dev/null @@ -1,111 +0,0 @@ -// -// Subworkflow with functionality that may be useful for any Nextflow pipeline -// - -include { getWorkflowVersion } from '../utils_nfcore_pipeline/main' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow UTILS_NEXTFLOW_PIPELINE { - take: - print_version // boolean: print version - dump_parameters // boolean: dump parameters - outdir // path: base directory used to publish pipeline results - check_conda_channels // boolean: check conda channels - - main: - - // - // Print workflow version and exit on --version - // - if (print_version) { - log.info("${workflow.manifest.name} ${getWorkflowVersion()}") - error("Version: ${workflow.manifest.name} ${getWorkflowVersion()}") - } - - // - // Dump pipeline parameters to a JSON file - // - if (dump_parameters && outdir) { - dumpParametersToJSON(outdir) - } - - // - // When running with Conda, warn if channels have not been set-up appropriately - // - if (check_conda_channels) { - checkCondaChannels() - } - - emit: - dummy_emit = true - versions = Channel.empty() -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// Dump pipeline parameters to a JSON file -// -def dumpParametersToJSON(outdir) { - def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') - def filename = "params_${timestamp}.json" - def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") - def jsonStr = groovy.json.JsonOutput.toJson(params) - temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - - nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") - temp_pf.delete() -} - -// -// When running with -profile conda, warn if channels have not been set-up appropriately -// -def checkCondaChannels() { - def parser = new org.yaml.snakeyaml.Yaml() - def channels = [] - try { - def config = parser.load("conda config --show channels".execute().text) - channels = config.channels - } - catch (NullPointerException e) { - log.debug(e) - log.warn("Could not verify conda channel configuration.") - return null - } - catch (IOException e) { - log.debug(e) - log.warn("Could not verify conda channel configuration.") - return null - } - - // Check that all channels are present - // This channel list is ordered by required channel priority. - def required_channels_in_order = ['conda-forge', 'bioconda'] - def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean - - // Check that they are in the right order - def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order } - - if (channels_missing | channel_priority_violation) { - log.warn """\ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - There is a problem with your Conda configuration! - You will need to set-up the conda-forge and bioconda channels correctly. - Please refer to https://bioconda.github.io/ - The observed channel order is - ${channels} - but the following channel order is required: - ${required_channels_in_order} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - """.stripIndent(true) - } -} diff --git a/subworkflows/local/utils_nextflow_pipeline/meta.yml b/subworkflows/local/utils_nextflow_pipeline/meta.yml deleted file mode 100644 index 4080a8b6..00000000 --- a/subworkflows/local/utils_nextflow_pipeline/meta.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: utils_nextflow_pipeline -description: General Nextflow pipeline utilities for version printing, parameter dumping, and conda channel validation. -keywords: - - utilities - - Nextflow - - parameters - - conda -components: - - getworkflowversion -input: - - print_version: - type: value - description: Boolean to print workflow version and exit - - dump_parameters: - type: value - description: Boolean to dump parameters to JSON file - - outdir: - type: path - description: Output directory for dumped parameters - - check_conda_channels: - type: value - description: Boolean to verify conda channel configuration -output: - - dummy_emit: - type: value - description: Dummy boolean emit for workflow chaining -authors: - - "@nf-core" diff --git a/subworkflows/local/utils_nfcore_pipeline/main.nf b/subworkflows/local/utils_nfcore_pipeline/main.nf deleted file mode 100644 index 830691f8..00000000 --- a/subworkflows/local/utils_nfcore_pipeline/main.nf +++ /dev/null @@ -1,420 +0,0 @@ -// -// Subworkflow with utility functions specific to the nf-core pipeline template -// - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow UTILS_NFCORE_PIPELINE { - take: - nextflow_cli_args - - main: - valid_config = checkConfigProvided() - checkProfileProvided(nextflow_cli_args) - - emit: - valid_config - versions = Channel.empty() -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// Warn if a -profile or Nextflow config has not been provided to run the pipeline -// -def checkConfigProvided() { - def valid_config = true as Boolean - if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { - log.warn( - "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n " - ) - valid_config = false - } - return valid_config -} - -// -// Exit pipeline if --profile contains spaces -// -def checkProfileProvided(nextflow_cli_args) { - if (workflow.profile.endsWith(',')) { - error( - "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" - ) - } - if (nextflow_cli_args[0]) { - log.warn( - "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" - ) - } -} - -// -// Generate workflow version string -// -def getWorkflowVersion() { - def version_string = "" as String - if (workflow.manifest.version) { - def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' - version_string += "${prefix_v}${workflow.manifest.version}" - } - - if (workflow.commitId) { - def git_shortsha = workflow.commitId.substring(0, 7) - version_string += "-g${git_shortsha}" - } - - return version_string -} - -// -// Get software versions for pipeline -// -def processVersionsFromYAML(yaml_file) { - def yaml = new org.yaml.snakeyaml.Yaml() - def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] } - return yaml.dumpAsMap(versions).trim() -} - -// -// Get workflow version for pipeline -// -def workflowVersionToYAML() { - return """ - Workflow: - ${workflow.manifest.name}: ${getWorkflowVersion()} - Nextflow: ${workflow.nextflow.version} - """.stripIndent().trim() -} - -// -// Get channel of software versions used in pipeline in YAML format -// -def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) -} - -// -// Get workflow summary for MultiQC -// -def paramsSummaryMultiqc(summary_params) { - def summary_section = '' - summary_params - .keySet() - .each { group -> - def group_params = summary_params.get(group) - // This gets the parameters of that particular group - if (group_params) { - summary_section += "

${group}

\n" - summary_section += "
\n" - group_params - .keySet() - .sort() - .each { param -> - summary_section += "
${param}
${group_params.get(param) ?: 'N/A'}
\n" - } - summary_section += "
\n" - } - } - - def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String - yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" - yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" - yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" - yaml_file_text += "plot_type: 'html'\n" - yaml_file_text += "data: |\n" - yaml_file_text += "${summary_section}" - - return yaml_file_text -} - -// -// ANSII colours used for terminal logging -// -def logColours(monochrome_logs=true) { - def colorcodes = [:] as Map - - // Reset / Meta - colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" - colorcodes['bold'] = monochrome_logs ? '' : "\033[1m" - colorcodes['dim'] = monochrome_logs ? '' : "\033[2m" - colorcodes['underlined'] = monochrome_logs ? '' : "\033[4m" - colorcodes['blink'] = monochrome_logs ? '' : "\033[5m" - colorcodes['reverse'] = monochrome_logs ? '' : "\033[7m" - colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m" - - // Regular Colors - colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" - colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" - colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" - colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" - colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" - colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" - colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" - colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" - - // Bold - colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" - colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" - colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" - colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" - colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" - colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" - colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" - colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" - - // Underline - colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" - colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" - colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" - colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" - colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" - colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" - colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" - colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" - - // High Intensity - colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" - colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" - colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" - colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" - colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" - colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" - colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" - colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" - - // Bold High Intensity - colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" - colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" - colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" - colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" - colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" - colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" - colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" - colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" - - return colorcodes -} - -// Return a single report from an object that may be a Path or List -// -def getSingleReport(multiqc_reports) { - if (multiqc_reports instanceof Path) { - return multiqc_reports - } else if (multiqc_reports instanceof List) { - if (multiqc_reports.size() == 0) { - log.warn("[${workflow.manifest.name}] No reports found from process 'MULTIQC'") - return null - } else if (multiqc_reports.size() == 1) { - return multiqc_reports.first() - } else { - log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one") - return multiqc_reports.first() - } - } else { - return null - } -} - -// -// Construct and send completion email -// -def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) { - - // Set up the e-mail variables - def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}" - if (!workflow.success) { - subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}" - } - - def summary = [:] - summary_params - .keySet() - .sort() - .each { group -> - summary << summary_params[group] - } - - def misc_fields = [:] - misc_fields['Date Started'] = workflow.start - misc_fields['Date Completed'] = workflow.complete - misc_fields['Pipeline script file path'] = workflow.scriptFile - misc_fields['Pipeline script hash ID'] = workflow.scriptId - if (workflow.repository) { - misc_fields['Pipeline repository Git URL'] = workflow.repository - } - if (workflow.commitId) { - misc_fields['Pipeline repository Git Commit'] = workflow.commitId - } - if (workflow.revision) { - misc_fields['Pipeline Git branch/tag'] = workflow.revision - } - misc_fields['Nextflow Version'] = workflow.nextflow.version - misc_fields['Nextflow Build'] = workflow.nextflow.build - misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp - - def email_fields = [:] - email_fields['version'] = getWorkflowVersion() - email_fields['runName'] = workflow.runName - email_fields['success'] = workflow.success - email_fields['dateComplete'] = workflow.complete - email_fields['duration'] = workflow.duration - email_fields['exitStatus'] = workflow.exitStatus - email_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - email_fields['errorReport'] = (workflow.errorReport ?: 'None') - email_fields['commandLine'] = workflow.commandLine - email_fields['projectDir'] = workflow.projectDir - email_fields['summary'] = summary << misc_fields - - // On success try attach the multiqc report - def mqc_report = getSingleReport(multiqc_report) - - // Check if we are only sending emails on failure - def email_address = email - if (!email && email_on_fail && !workflow.success) { - email_address = email_on_fail - } - - // Render the TXT template - def engine = new groovy.text.GStringTemplateEngine() - def tf = new File("${workflow.projectDir}/assets/email_template.txt") - def txt_template = engine.createTemplate(tf).make(email_fields) - def email_txt = txt_template.toString() - - // Render the HTML template - def hf = new File("${workflow.projectDir}/assets/email_template.html") - def html_template = engine.createTemplate(hf).make(email_fields) - def email_html = html_template.toString() - - // Render the sendmail template - def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as MemoryUnit - def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()] - def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt") - def sendmail_template = engine.createTemplate(sf).make(smail_fields) - def sendmail_html = sendmail_template.toString() - - // Send the HTML e-mail - def colors = logColours(monochrome_logs) as Map - if (email_address) { - try { - if (plaintext_email) { - new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') - } - // Try to send HTML e-mail using sendmail - def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") - sendmail_tf.withWriter { w -> w << sendmail_html } - ['sendmail', '-t'].execute() << sendmail_html - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-") - } - catch (Exception msg) { - log.debug(msg.toString()) - log.debug("Trying with mail instead of sendmail") - // Catch failures and try with plaintext - def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] - mail_cmd.execute() << email_html - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-") - } - } - - // Write summary e-mail HTML to a file - def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") - output_hf.withWriter { w -> w << email_html } - nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html") - output_hf.delete() - - // Write summary e-mail TXT to a file - def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") - output_tf.withWriter { w -> w << email_txt } - nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt") - output_tf.delete() -} - -// -// Print pipeline summary on completion -// -def completionSummary(monochrome_logs=true) { - def colors = logColours(monochrome_logs) as Map - if (workflow.success) { - if (workflow.stats.ignoredCount == 0) { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-") - } - else { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-") - } - } - else { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") - } -} - -// -// Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack -// -def imNotification(summary_params, hook_url) { - def summary = [:] - summary_params - .keySet() - .sort() - .each { group -> - summary << summary_params[group] - } - - def misc_fields = [:] - misc_fields['start'] = workflow.start - misc_fields['complete'] = workflow.complete - misc_fields['scriptfile'] = workflow.scriptFile - misc_fields['scriptid'] = workflow.scriptId - if (workflow.repository) { - misc_fields['repository'] = workflow.repository - } - if (workflow.commitId) { - misc_fields['commitid'] = workflow.commitId - } - if (workflow.revision) { - misc_fields['revision'] = workflow.revision - } - misc_fields['nxf_version'] = workflow.nextflow.version - misc_fields['nxf_build'] = workflow.nextflow.build - misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp - - def msg_fields = [:] - msg_fields['version'] = getWorkflowVersion() - msg_fields['runName'] = workflow.runName - msg_fields['success'] = workflow.success - msg_fields['dateComplete'] = workflow.complete - msg_fields['duration'] = workflow.duration - msg_fields['exitStatus'] = workflow.exitStatus - msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - msg_fields['errorReport'] = (workflow.errorReport ?: 'None') - msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") - msg_fields['projectDir'] = workflow.projectDir - msg_fields['summary'] = summary << misc_fields - - // Render the JSON template - def engine = new groovy.text.GStringTemplateEngine() - // Different JSON depending on the service provider - // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format - def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" - def hf = new File("${workflow.projectDir}/assets/${json_path}") - def json_template = engine.createTemplate(hf).make(msg_fields) - def json_message = json_template.toString() - - // POST - def post = new URL(hook_url).openConnection() - post.setRequestMethod("POST") - post.setDoOutput(true) - post.setRequestProperty("Content-Type", "application/json") - post.getOutputStream().write(json_message.getBytes("UTF-8")) - def postRC = post.getResponseCode() - if (!postRC.equals(200)) { - log.warn(post.getErrorStream().getText()) - } -} diff --git a/subworkflows/local/utils_nfcore_pipeline/meta.yml b/subworkflows/local/utils_nfcore_pipeline/meta.yml deleted file mode 100644 index 1e994cfb..00000000 --- a/subworkflows/local/utils_nfcore_pipeline/meta.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: utils_nfcore_pipeline -description: Utility functions for nf-core pipeline template including config validation, version reporting, MultiQC integration, email notifications, and completion handling. -keywords: - - utilities - - nf-core - - MultiQC - - email - - notifications -components: [] -input: - - nextflow_cli_args: - type: value - description: Nextflow CLI positional arguments for validation -output: - - valid_config: - type: value - description: Boolean indicating whether a valid configuration was provided -authors: - - "@nf-core" diff --git a/subworkflows/local/utils_pipeline/main.nf b/subworkflows/local/utils_pipeline/main.nf deleted file mode 100644 index c25c60d9..00000000 --- a/subworkflows/local/utils_pipeline/main.nf +++ /dev/null @@ -1,151 +0,0 @@ -// -// Subworkflow with functionality specific to the nf-preprocess-proteomics pipeline -// - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// Plugin function from nf-schema@2.5.1 (version specified in nextflow.config) -include { paramsSummaryMap } from 'plugin/nf-schema' -include { completionEmail } from '../utils_nfcore_pipeline/main' -include { completionSummary } from '../utils_nfcore_pipeline/main' -include { imNotification } from '../utils_nfcore_pipeline/main' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW TO INITIALISE PIPELINE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW FOR PIPELINE COMPLETION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow PIPELINE_COMPLETION { - - take: - email // string: email address - email_on_fail // string: email address sent on pipeline failure - plaintext_email // boolean: Send plain-text email instead of HTML - outdir // path: Path to output directory where results will be published - monochrome_logs // boolean: Disable ANSI colour codes in log output - hook_url // string: hook URL for notifications - multiqc_report // string: Path to MultiQC report - - main: - summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") - def multiqc_reports = multiqc_report.toList() - // - // Completion email and summary - // - workflow.onComplete { - if (email || email_on_fail) { - completionEmail( - summary_params, - email, - email_on_fail, - plaintext_email, - outdir, - monochrome_logs, - multiqc_reports.getVal(), - ) - } - - completionSummary(monochrome_logs) - if (hook_url) { - imNotification(summary_params, hook_url) - } - } - - workflow.onError { - log.error "Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting" - } - - emit: - versions = Channel.empty() -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ -// -// Generate methods description for MultiQC -// -def toolCitationText() { - def citation_text = [ - "Tools used in the workflow included:", - "OpenMS (Röst et al. 2016),", - "DIA-NN (Demichev et al. 2020),", - "MSstats (Choi et al. 2014),", - "Comet (Eng et al. 2013),", - "MS-GF+ (Kim & Pevzner 2014),", - "ThermoRawFileParser (Hulstaert et al. 2020),", - "Percolator (Käll et al. 2007),", - "Luciphor (Fermin et al. 2017),", - "pMultiQC (Perez-Riverol et al. 2024)", - "." - ].join(' ').trim() - - return citation_text -} - -def toolBibliographyText() { - def reference_text = [ - "
  • Röst HL, Sachsenberg T, Aiche S, Bielow C, Weisser H, Aicheler F, Andreotti S, Ehrlich HC, Gutenbrunner P, Kenar E, Liang X, Nahnsen S, Nilse L, Pfeuffer J, Rosenberger G, Rurik M, Schmitt U, Veit J, Walzer M, Wojnar D, Wolski WE, Schilling O, Choudhary JS, Malmström L, Aebersold R, Reinert K, Kohlbacher O. (2016). OpenMS: a flexible open-source software platform for mass spectrometry data analysis. Nature Methods, 13(9), 741–748. doi: 10.1038/nmeth.3959
  • ", - "
  • Demichev V, Messner CB, Vernardis SI, Lilley KS, Ralser M. (2020). DIA-NN: neural networks and interference correction enable deep proteome coverage in high throughput. Nature Methods, 17(1), 41-44. doi: 10.1038/s41592-019-0638-x
  • ", - "
  • Choi M, Chang CY, Clough T, Broudy D, Killeen T, MacLean B, Vitek O. (2014). MSstats: an R package for statistical analysis of quantitative mass spectrometry-based proteomic experiments. Bioinformatics, 30(17), 2524–2526. doi: 10.1093/bioinformatics/btu305
  • ", - "
  • Eng JK, Jahan TA, Hoopmann MR. (2013). Comet: an open-source MS/MS sequence database search tool. Proteomics, 13(1), 22–24. doi: 10.1002/pmic.201200439
  • ", - "
  • Kim S, Pevzner PA. (2014). MS-GF+ makes progress towards a universal database search tool for proteomics. Nature Communications, 5, 5277. doi: 10.1038/ncomms6277
  • ", - "
  • Hulstaert N, Shofstahl J, Sachsenberg T, Walzer M, Barsnes H, Martens L, Perez-Riverol Y. (2020). ThermoRawFileParser: Modular, Scalable, and Cross-Platform RAW File Conversion. Journal of Proteome Research, 19(1), 537-542. doi: 10.1021/acs.jproteome.9b00328
  • ", - "
  • Käll L, Canterbury JD, Weston J, Noble WS, MacCoss MJ. (2007). Semi-supervised learning for peptide identification from shotgun proteomics datasets. Nature Methods, 4(11), 923-925. doi: 10.1038/nmeth1113
  • ", - "
  • Fermin D, Walmsley SJ, Gingras AC, Choi H, Nesvizhskii AI. (2017). LuciPHOr2: site prediction of generic post-translational modifications from tandem mass spectrometry data. Bioinformatics, 33(19), 2926-2933. doi: 10.1093/bioinformatics/btx401
  • ", - "
  • Perez-Riverol Y, Moreno P, da Veiga Leprevost F, Csordas A, Bai J, Carver J, Hewapathirana S, Kundu DJ, Inuganti A, Griss J, Mayer G, Eisenacher M, Pérez E, Uszkoreit J, Pfeuffer J, Sachsenberg T, Yilmaz S, Tiwary S, Cox J, Audain E, Walzer M, Jarnuczak AF, Ternent T, Brazma A, Vizcaíno JA. (2024). pMultiQC: a comprehensive tool for quality control of proteomics data. Nature Methods, 21(1), 1-2. doi: 10.1038/s41592-023-02125-1
  • " - ].join(' ').trim() - - return reference_text -} - -def methodsDescriptionText(mqc_methods_yaml) { - // Convert to a named map so can be used as with familiar NXF ${workflow} variable syntax in the MultiQC YML file - def meta = [:] - meta.workflow = workflow.toMap() - meta["manifest_map"] = workflow.manifest.toMap() - - // Pipeline DOI - if (meta.manifest_map.doi) { - // Using a loop to handle multiple DOIs - // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers - // Removing ` ` since the manifest.doi is a string and not a proper list - def temp_doi_ref = "" - def manifest_doi = meta.manifest_map.doi.tokenize(",") - manifest_doi.each { doi_ref -> - temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " - } - meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) - } else meta["doi_text"] = "" - meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " - - // Tool references - meta["tool_citations"] = "" - meta["tool_bibliography"] = "" - - // Tool citations and bibliography - meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") - meta["tool_bibliography"] = toolBibliographyText() - - - def methods_text = mqc_methods_yaml.text - - def engine = new groovy.text.SimpleTemplateEngine() - def description_html = engine.createTemplate(methods_text).make(meta) - - return description_html.toString() -} diff --git a/subworkflows/local/utils_pipeline/meta.yml b/subworkflows/local/utils_pipeline/meta.yml deleted file mode 100644 index c15316bc..00000000 --- a/subworkflows/local/utils_pipeline/meta.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: pipeline_completion -description: Pipeline-specific utility subworkflow providing completion handling (email, summary, notifications) and methods description generation for MultiQC. -keywords: - - pipeline completion - - email - - MultiQC - - methods description -components: - - utils_nfcore_pipeline - - paramssummarymap - - completionemail - - completionsummary - - imnotification -input: - - email: - type: value - description: Email address for completion notification - - email_on_fail: - type: value - description: Email address for failure notification - - plaintext_email: - type: value - description: Boolean to send plain-text email instead of HTML - - outdir: - type: path - description: Output directory path - - monochrome_logs: - type: value - description: Boolean to disable ANSI colour codes in log output - - hook_url: - type: value - description: Webhook URL for Slack/Teams notifications - - multiqc_report: - type: file - description: Path to MultiQC report for email attachment -output: - - completion_status: - type: value - description: Pipeline completion status indicator -authors: - - "@daichengxin" From 5b43675efb8ecf058d2efe8d24f362a5edd1e0c3 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 17:25:36 +0000 Subject: [PATCH 08/13] fix(merge_split_search): fail clearly when the MSFragger jar is missing; run integration test in the FragPipe container --- CHANGELOG.md | 2 + modules/local/merge_split_search/main.nf | 5 +++ .../resources/usr/bin/merge_split_search.py | 26 ++++++++++++- .../merge_split_search/tests/main.nf.test | 38 +++++++++++++++++-- .../tests/main.nf.test.snap | 30 ++------------- .../merge_split_search/tests/nextflow.config | 19 +++++++++- .../merge_split_search/tests/no_jar.config | 16 ++++++++ 7 files changed, 104 insertions(+), 32 deletions(-) create mode 100644 modules/local/merge_split_search/tests/no_jar.config diff --git a/CHANGELOG.md b/CHANGELOG.md index 15250349..d9d42640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `MERGE_SPLIT_SEARCH`: the task fails at once with `ERROR: MERGE_SPLIT_SEARCH: no MSFragger*.jar found` (naming the searched `msfragger_dir` and `ext.fragpipe_tools_dir`) when no MSFragger jar is found; before, `java -jar` got an empty jar path and reported a misleading "Invalid or corrupt jarfile .tsv". `merge_split_search.py` also rejects a `--msfragger_cmd` whose `-jar` path is missing. +- `MERGE_SPLIT_SEARCH` tests: the integration test runs in the FragPipe image given by `FRAGPIPE_CONTAINER` (it ran on the host before); a new stub-tagged test covers the missing-jar error; the stub snapshot no longer records the host Python version. - `FRAGPIPE_HEADLESS`: `manifest_content` is used again and is authoritative (file, experiment, bioreplicate, data type), so allinone runs keep one experiment per sample, empty bioreplicates for fractions, and `DDA+`; before, every LFQ file fell back to `experiment1` / `1` / `DDA`. - `FRAGPIPE_HEADLESS`: file names are matched exactly against the manifest (or `file_experiment_map`) first column; the substring lookup (`grep -F`) gave `A1.mzML` the experiment of `XA1.mzML`. - `FRAGPIPE_HEADLESS`: the task fails loudly when a staged file has no row, a row names an unstaged file, a file is listed twice, a TMT file's experiment is not in `annotation_content`, or both `manifest_content` and `file_experiment_map` are empty (TMT files were silently dropped before). diff --git a/modules/local/merge_split_search/main.nf b/modules/local/merge_split_search/main.nf index 5fed8b4b..37fe668f 100644 --- a/modules/local/merge_split_search/main.nf +++ b/modules/local/merge_split_search/main.nf @@ -81,6 +81,11 @@ process MERGE_SPLIT_SEARCH { BRUKER_DIR="${tools_dir}/../ext/bruker" THERMO_DIR="${tools_dir}/../ext/thermo" fi + if [ -z "\$MSFRAGGER_JAR" ] || [ ! -f "\$MSFRAGGER_JAR" ]; then + echo "ERROR: MERGE_SPLIT_SEARCH: no MSFragger*.jar found (searched msfragger_dir='${msfragger_dir}' and ext.fragpipe_tools_dir='\$TOOLS_DIR')." >&2 + echo "Run in the licensed FragPipe container (--fragpipe_container), pass an unzipped MSFragger directory as msfragger_dir, or set ext.fragpipe_tools_dir." >&2 + exit 1 + fi NATIVE_FLAGS="" [ -d "\$BRUKER_DIR" ] && NATIVE_FLAGS="\$NATIVE_FLAGS -Dlibs.bruker.dir=\$BRUKER_DIR" [ -d "\$THERMO_DIR" ] && NATIVE_FLAGS="\$NATIVE_FLAGS -Dlibs.thermo.dir=\$THERMO_DIR" diff --git a/modules/local/merge_split_search/resources/usr/bin/merge_split_search.py b/modules/local/merge_split_search/resources/usr/bin/merge_split_search.py index c0c7a744..3da8eaf8 100755 --- a/modules/local/merge_split_search/resources/usr/bin/merge_split_search.py +++ b/modules/local/merge_split_search/resources/usr/bin/merge_split_search.py @@ -842,6 +842,28 @@ def cpu_count() -> int: return os.cpu_count() or 1 +def require_msfragger_jar(msfragger_cmd: list) -> None: + """ + Exit non-zero if a `java ... -jar ` command has no jar or a missing jar. + + Without this, an empty jar path lets java read the next argument (the + histogram TSV) as the jar and fail with a misleading "corrupt jarfile". + + Args: + msfragger_cmd: Tokenised --msfragger_cmd + """ + if "-jar" not in msfragger_cmd: + return + jar_index = msfragger_cmd.index("-jar") + 1 + jar = msfragger_cmd[jar_index] if jar_index < len(msfragger_cmd) else "" + if not jar or not pathlib.Path(jar).is_file(): + sys.exit( + f"ERROR: merge_split_search: MSFragger jar missing in --msfragger_cmd " + f"({' '.join(msfragger_cmd)!r}); got {jar!r}. Pass an existing " + f"MSFragger*.jar after -jar (run in the FragPipe container)." + ) + + def parse_args() -> argparse.Namespace: """ Parse command-line arguments. @@ -961,8 +983,10 @@ def main() -> None: print("Step 2: Generating expect functions...", flush=True) import shlex + msfragger_cmd = shlex.split(args.msfragger_cmd) + require_msfragger_jar(msfragger_cmd) generate_expect_cmd = [ - *shlex.split(args.msfragger_cmd), + *msfragger_cmd, "--generate_expect_functions", str(combined_histo.name), ] diff --git a/modules/local/merge_split_search/tests/main.nf.test b/modules/local/merge_split_search/tests/main.nf.test index 6f177323..dbe9331b 100644 --- a/modules/local/merge_split_search/tests/main.nf.test +++ b/modules/local/merge_split_search/tests/main.nf.test @@ -56,13 +56,44 @@ nextflow_process { process.out.pin, process.out.license_agreement, process.out.versions_msfragger, - process.out.versions_fragpipe, - process.out.versions_python + process.out.versions_fragpipe ).match() } ) } } + test("merge_split_search - missing MSFragger jar fails with a clear error") { + tag "stub" + config "./no_jar.config" + + when { + process { + """ + def pepxml_0 = file("\${workDir}/chunk_0_test_sample.pepXML") + def pin_0 = file("\${workDir}/chunk_0_test_sample.pin") + def histo_0 = file("\${workDir}/chunk_0_test_sample_scores_histogram.tsv") + def msf_params = file("\${workDir}/msfragger.params") + pepxml_0.text = "mock pepxml chunk 0" + pin_0.text = "mock pin chunk 0" + histo_0.text = "mock histo chunk 0" + msf_params.text = "output_report_topN = 1" + + input[0] = channel.of([ [ id: 'test_sample' ], [ pepxml_0 ], [ pin_0 ], [ histo_0 ] ]) + input[1] = 1 + input[2] = msf_params + input[3] = [] // msfragger_dir (use auto-discovery -> nothing found) + """ + } + } + + then { + assertAll ( + { assert process.failed }, + { assert process.errorReport.contains('ERROR: MERGE_SPLIT_SEARCH: no MSFragger*.jar found') : process.errorReport } + ) + } + } + test("merge_split_search - integration with mock data") { tag "integration" config "./nextflow.config" @@ -189,8 +220,7 @@ nextflow_process { process.out.pepxml.collect { meta, f -> file(f).name }, process.out.pin.collect { meta, f -> file(f).name }, process.out.versions_msfragger, - process.out.versions_fragpipe, - process.out.versions_python + process.out.versions_fragpipe ).match() } ) } diff --git a/modules/local/merge_split_search/tests/main.nf.test.snap b/modules/local/merge_split_search/tests/main.nf.test.snap index a11d3669..5f9ba767 100644 --- a/modules/local/merge_split_search/tests/main.nf.test.snap +++ b/modules/local/merge_split_search/tests/main.nf.test.snap @@ -33,34 +33,12 @@ "fragpipe", "24.0" ] - ], - [ - [ - "MERGE_SPLIT_SEARCH", - "python", - "3.14.3" - ] - ] - ], - "timestamp": "2026-03-31T19:40:18.291806691", - "meta": { - "nf-test": "0.9.5", - "nextflow": "25.10.2" - } - }, - "merge_split_search - integration with mock data": { - "content": [ - [ - "test_sample.pepXML" - ], - [ - "test_sample.pin" ] ], - "timestamp": "2026-03-28T02:00:27.846057288", "meta": { - "nf-test": "0.9.5", - "nextflow": "25.10.2" - } + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-09-29T17:21:41.154969394" } } \ No newline at end of file diff --git a/modules/local/merge_split_search/tests/nextflow.config b/modules/local/merge_split_search/tests/nextflow.config index c2243c8a..68ac5a33 100644 --- a/modules/local/merge_split_search/tests/nextflow.config +++ b/modules/local/merge_split_search/tests/nextflow.config @@ -1,3 +1,20 @@ /* - * Test configuration for MERGE_SPLIT_SEARCH module. + * Config for the MERGE_SPLIT_SEARCH integration test. + * + * The module has no container of its own (MSFragger is licensed and must be + * user-supplied), so the test needs the FragPipe image. Pass it with the + * FRAGPIPE_CONTAINER environment variable, e.g. + * FRAGPIPE_CONTAINER=docker.io/altoslabscom/fragpipe:24.0-academic \ + * nf-test test modules/local/merge_split_search/tests/main.nf.test --tag integration --profile +docker */ + +params.fragpipe_container = System.getenv('FRAGPIPE_CONTAINER') ?: params.fragpipe_container +if (!params.fragpipe_container) { + throw new IllegalArgumentException('MERGE_SPLIT_SEARCH integration test needs a FragPipe image: set FRAGPIPE_CONTAINER (or params.fragpipe_container)') +} + +process { + withName: 'MERGE_SPLIT_SEARCH' { + container = { params.fragpipe_container } + } +} diff --git a/modules/local/merge_split_search/tests/no_jar.config b/modules/local/merge_split_search/tests/no_jar.config new file mode 100644 index 00000000..a9971a4f --- /dev/null +++ b/modules/local/merge_split_search/tests/no_jar.config @@ -0,0 +1,16 @@ +/* + * Config for the MERGE_SPLIT_SEARCH "no MSFragger jar" test. + * + * Runs the real script: block on the host with no container and a tools dir + * that does not exist, so no MSFragger jar can be found. + */ + +docker.enabled = false +singularity.enabled = false +conda.enabled = false + +process { + withName: 'MERGE_SPLIT_SEARCH' { + ext.fragpipe_tools_dir = '/nonexistent/fragpipe-24.0/tools' + } +} From e07ea32681c6ff2193b239c0ed20016c7dfe89b3 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 17:26:46 +0000 Subject: [PATCH 09/13] test(merge_split_search): add integration snapshot from a real FragPipe container run --- .../tests/main.nf.test.snap | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/modules/local/merge_split_search/tests/main.nf.test.snap b/modules/local/merge_split_search/tests/main.nf.test.snap index 5f9ba767..932a4590 100644 --- a/modules/local/merge_split_search/tests/main.nf.test.snap +++ b/modules/local/merge_split_search/tests/main.nf.test.snap @@ -40,5 +40,34 @@ "nextflow": "25.10.4" }, "timestamp": "2026-09-29T17:21:41.154969394" + }, + "merge_split_search - integration with mock data": { + "content": [ + [ + "test_sample.pepXML" + ], + [ + "test_sample.pin" + ], + [ + [ + "MERGE_SPLIT_SEARCH", + "msfragger", + "4.4.1" + ] + ], + [ + [ + "MERGE_SPLIT_SEARCH", + "fragpipe", + "24.0" + ] + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-09-29T17:26:24.352887732" } } \ No newline at end of file From e5ce83c101a6f40aa0e2e1b4eaad1aca042a4c4c Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 17:40:02 +0000 Subject: [PATCH 10/13] fix: wire up the documented UniProt reference-proteome download (params.databases) The docs promised that --organism without --database downloads the UniProt reference proteome, but the workflows read params.databases[organism].database while conf/reference_proteomes.config defined an unused params.proteomes map (snake_case keys, `fasta` field) and params.proteomes_ignore defaulted to true. Every run without --database therefore failed. - Mirror the nf-core igenomes pattern: proteomes_ignore defaults to false, proteomes_base holds the UniProt REST prefix (schema default matches), conf/reference_proteomes.config defines params.databases keyed by the standard organism name ('Homo sapiens', ...) with a `database` URL, conf/reference_proteomes_ignored.config sets params.databases = [:], and `databases` is in validation.defaultIgnoreParams. - getProteinDatabase() (utils_nfcore_msproteomics_pipeline): --database is authoritative, else the organism's reference proteome, else fail with a message naming --database and the available organisms. Used by DIA-NN; WorkflowUtils.resolveFragPipeDatabase raises the same message. - Channel.fromPath(..., glob: false) for the database: with globbing the `?` in the UniProt URL dropped the whole query string. - Function tests for the three resolution cases; docs and CHANGELOG updated. --- CHANGELOG.md | 2 + conf/reference_proteomes.config | 45 ++++++------ conf/reference_proteomes_ignored.config | 8 +-- docs/database_guide.md | 24 +++++-- docs/quickstart.md | 4 +- docs/usage.md | 22 +++--- lib/WorkflowUtils.groovy | 10 +-- nextflow.config | 9 ++- nextflow_schema.json | 9 +-- .../main.nf | 21 ++++++ .../tests/main.function.nf.test | 68 +++++++++++++++++++ workflows/diann.nf | 15 ++-- 12 files changed, 168 insertions(+), 69 deletions(-) create mode 100644 subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test diff --git a/CHANGELOG.md b/CHANGELOG.md index d9d42640..4fede6b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `nf-core pipelines lint`: removed the `max_cpus` / `max_memory` / `max_time` schema params and the `test` profile's `params.max_*`; resource caps are set by `process.resourceLimits`, and nothing read the params. - `nf-core pipelines lint`: removed `params.proteomes = null` from `conf/reference_proteomes_ignored.config`; no code reads `params.proteomes`. - `utils_nfcore_pipeline`: tests match the installed nf-core/modules commit (`tests/main.nf.test` restored; stale `tests/main.workflow.nf.test` and its snapshot removed). +- Reference proteomes: the documented UniProt download now works. `conf/reference_proteomes.config` defines `params.databases` (keyed by organism, e.g. `'Homo sapiens'`, with a `database` URL), which is what the workflows read; before it defined an unused `params.proteomes` and `params.proteomes_ignore` defaulted to `true`, so without `--database` every run failed. Mirrors nf-core iGenomes: `proteomes_ignore` defaults to `false`, `proteomes_base` holds the UniProt URL prefix, `conf/reference_proteomes_ignored.config` sets `params.databases = [:]`, and `databases` is in `validation.defaultIgnoreParams`. `--database` stays authoritative; an organism with no proteome and no `--database` fails with `No protein database for organism '': ...` listing the available organisms (`getProteinDatabase`, new function tests). +- Database channels use `Channel.fromPath(..., glob: false)`; with globbing, the `?` in a UniProt REST URL dropped the query string. ### Changed diff --git a/conf/reference_proteomes.config b/conf/reference_proteomes.config index 806c9288..e2a04166 100644 --- a/conf/reference_proteomes.config +++ b/conf/reference_proteomes.config @@ -2,58 +2,61 @@ ======================================================================================== Reference Proteomes Configuration ======================================================================================== - UniProt reference proteomes (Swiss-Prot reviewed + isoforms). + UniProt reference proteomes (Swiss-Prot reviewed + isoforms), keyed by the + organism name that --organism resolves to (see + WorkflowUtils.convertOrganismToStandardName). Loaded unless + --proteomes_ignore is set; the FASTA is downloaded from the UniProt REST API + at runtime when --database is not given. Mirrors the nf-core igenomes pattern + (params.genomes / conf/igenomes.config). These do NOT include contaminant sequences. For FragPipe workflows, contaminants are added automatically by Philosopher's database command. For DIA-NN workflows, append contaminants to your FASTA manually or use --database with a pre-prepared database that includes contaminants. - Override with --database to provide your own FASTA file. + --database always takes precedence over this map. ======================================================================================== */ params { - proteomes_base = 'https://rest.uniprot.org/uniprotkb/stream?format=fasta&includeIsoform=true&query=(reviewed:true)+AND+(proteome:' - - proteomes { - 'homo_sapiens' { + databases { + 'Homo sapiens' { proteome_id = 'UP000005640' taxon_id = 9606 - fasta = "${params.proteomes_base}UP000005640)" + database = "${params.proteomes_base}UP000005640)" } - 'mus_musculus' { + 'Mus musculus' { proteome_id = 'UP000000589' taxon_id = 10090 - fasta = "${params.proteomes_base}UP000000589)" + database = "${params.proteomes_base}UP000000589)" } - 'rattus_norvegicus' { + 'Rattus norvegicus' { proteome_id = 'UP000002494' taxon_id = 10116 - fasta = "${params.proteomes_base}UP000002494)" + database = "${params.proteomes_base}UP000002494)" } - 'saccharomyces_cerevisiae' { + 'Saccharomyces cerevisiae' { proteome_id = 'UP000002311' taxon_id = 559292 - fasta = "${params.proteomes_base}UP000002311)" + database = "${params.proteomes_base}UP000002311)" } - 'danio_rerio' { + 'Danio rerio' { proteome_id = 'UP000000437' taxon_id = 7955 - fasta = "${params.proteomes_base}UP000000437)" + database = "${params.proteomes_base}UP000000437)" } - 'drosophila_melanogaster' { + 'Drosophila melanogaster' { proteome_id = 'UP000000803' taxon_id = 7227 - fasta = "${params.proteomes_base}UP000000803)" + database = "${params.proteomes_base}UP000000803)" } - 'caenorhabditis_elegans' { + 'Caenorhabditis elegans' { proteome_id = 'UP000001940' taxon_id = 6239 - fasta = "${params.proteomes_base}UP000001940)" + database = "${params.proteomes_base}UP000001940)" } - 'escherichia_coli' { + 'Escherichia coli' { proteome_id = 'UP000000625' taxon_id = 83333 - fasta = "${params.proteomes_base}UP000000625)" + database = "${params.proteomes_base}UP000000625)" } } } diff --git a/conf/reference_proteomes_ignored.config b/conf/reference_proteomes_ignored.config index d90874ee..1fc49618 100644 --- a/conf/reference_proteomes_ignored.config +++ b/conf/reference_proteomes_ignored.config @@ -1,11 +1,9 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for iProteomes paths + Nextflow config file for UniProt reference proteomes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Empty proteomes dictionary to use when iproteomes is ignored. + Empty databases dictionary to use when --proteomes_ignore is set. ---------------------------------------------------------------------------------------- */ -params { - proteomes_base = null -} +params.databases = [:] diff --git a/docs/database_guide.md b/docs/database_guide.md index cbff64b8..80e8be8e 100644 --- a/docs/database_guide.md +++ b/docs/database_guide.md @@ -4,7 +4,7 @@ Protein identification in mass spectrometry proteomics requires a FASTA database of protein sequences to search spectra against. The nf-core/msproteomics pipeline supports both pre-built reference proteomes and custom user-provided databases. -Pre-built databases are fetched automatically from UniProt based on organism metadata in the samplesheet, while custom databases can be supplied via the `--database` parameter. +When `--database` is not given, the UniProt reference proteome for `--organism` is downloaded automatically at runtime; a custom database supplied via `--database` always takes precedence. ## Pre-Built Reference Proteomes @@ -24,16 +24,26 @@ These databases contain Swiss-Prot reviewed proteins with isoforms, fetched from ### How pre-built databases are selected -The pipeline auto-selects the correct reference proteome based on the organism metadata in your samplesheet SDRF. -No additional parameters are needed when working with one of the eight supported organisms. -If the organism in your samplesheet matches a pre-built proteome, the pipeline downloads the FASTA automatically at runtime. +The reference proteome is selected by the `--organism` parameter (default `Homo sapiens`), not by the samplesheet. +The aliases `human`/`hs`, `mouse`/`mm` and `yeast`/`sc` map to _Homo sapiens_, _Mus musculus_ and _Saccharomyces cerevisiae_. +Any other organism must be given exactly as in the table above (e.g. `--organism 'Danio rerio'`). +When `--database` is not given, the pipeline downloads the FASTA for that organism from UniProt at runtime. -You can override the automatic selection by providing `--database /path/to/custom.fasta`. +Resolution order: + +| Priority | Source | +| -------- | ------------------------------------------------------------------------------ | +| 1 | `--philosopher_database` (FragPipe mode only) | +| 2 | `--database` | +| 3 | `params.databases[].database` from `conf/reference_proteomes.config` | + +If none applies (an organism outside the table and no `--database`), the pipeline stops before any task runs with `No protein database for organism '': pass --database ...`, listing the available organisms. ### Configuration -Pre-built proteome URLs are defined in `conf/reference_proteomes.config`. -Each entry uses the UniProt REST API endpoint: +Pre-built proteome URLs are defined in `conf/reference_proteomes.config` as the `params.databases` map, following the nf-core iGenomes pattern (`params.genomes` / `conf/igenomes.config`). +It is loaded unless `--proteomes_ignore` is set; with `--proteomes_ignore`, `params.databases` is empty and `--database` is required. +Each entry is `--proteomes_base` followed by the proteome ID and `)`, which gives the UniProt REST API endpoint: ``` https://rest.uniprot.org/uniprotkb/stream?format=fasta&includeIsoform=true&query=(reviewed:true)+AND+(proteome:) diff --git a/docs/quickstart.md b/docs/quickstart.md index 9645093d..6d5cf903 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -56,8 +56,8 @@ nextflow run nf-core/msproteomics \ -profile docker ``` -Reference proteomes auto-resolve for common organisms (human, mouse, yeast) based on sample metadata. -For other organisms, supply a FASTA database explicitly with `--database /path/to/database.fasta`. +Without `--database`, the UniProt reference proteome for `--organism` (default `Homo sapiens`) is downloaded at runtime; see [Database Preparation](database_guide.md) for the eight supported organisms. +For any other organism, supply a FASTA database explicitly with `--database /path/to/database.fasta`; otherwise the pipeline stops with an error. ## Step 4: Run a DDA LFQ Analysis diff --git a/docs/usage.md b/docs/usage.md index 76dce706..47fed984 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -74,8 +74,8 @@ nextflow run nf-core/msproteomics \ -profile docker ``` -Reference proteomes can be automatically fetched from UniProt for supported organisms when configured via `conf/reference_proteomes.config`. -To use a custom database, provide `--database /path/to/database.fasta`. +If `--database` is omitted, the UniProt reference proteome for `--organism` (default `Homo sapiens`) is downloaded at runtime from `conf/reference_proteomes.config`; see [Database Preparation](database_guide.md). +`--database /path/to/database.fasta` always takes precedence. ### FragPipe Mode (`--mode fragpipe`) @@ -170,15 +170,15 @@ The `--fragpipe_mode` parameter controls execution mode: ## Key Parameters -| Parameter | Description | Default | -| --------------------- | ---------------------------------------------------------- | ------------------------------------------------------ | -| `--input` | Path to CSV samplesheet | Required | -| `--mode` | Analysis mode: `diann` or `fragpipe` | Required | -| `--outdir` | Output directory | Required | -| `--database` | FASTA protein database | Auto-selected for DIA; required for FragPipe workflows | -| `--fragpipe_workflow` | FragPipe `.workflow` file or workflow name (FragPipe mode) | None | -| `--tmt_mode` | TMT analysis mode: `labelcheck` or `quant` (FragPipe mode) | None | -| `--fragpipe_mode` | FragPipe execution mode: `pipeline` or `headless` | `pipeline` | +| Parameter | Description | Default | +| --------------------- | ---------------------------------------------------------- | ------------------------------------------- | +| `--input` | Path to CSV samplesheet | Required | +| `--mode` | Analysis mode: `diann` or `fragpipe` | Required | +| `--outdir` | Output directory | Required | +| `--database` | FASTA protein database | UniProt reference proteome for `--organism` | +| `--fragpipe_workflow` | FragPipe `.workflow` file or workflow name (FragPipe mode) | None | +| `--tmt_mode` | TMT analysis mode: `labelcheck` or `quant` (FragPipe mode) | None | +| `--fragpipe_mode` | FragPipe execution mode: `pipeline` or `headless` | `pipeline` | ## Container Requirements diff --git a/lib/WorkflowUtils.groovy b/lib/WorkflowUtils.groovy index 6bd68f04..5cc24a0a 100644 --- a/lib/WorkflowUtils.groovy +++ b/lib/WorkflowUtils.groovy @@ -81,9 +81,11 @@ class WorkflowUtils { if (organism && params.databases && params.databases[organism]?.database) { return [path: params.databases[organism].database, is_philosopher: false] } + def available = params.databases ? params.databases.keySet().join(', ') : 'none (--proteomes_ignore is set)' throw new RuntimeException( - "No database provided. Use --philosopher_database, --database, " + - "or ensure organism '${organism}' has a configured database." + "No protein database for organism '${organism}': pass --database (or --philosopher_database), " + + "or set --organism to one with a UniProt reference proteome in conf/reference_proteomes.config. " + + "Available: ${available}" ) } @@ -102,11 +104,11 @@ class WorkflowUtils { if (resolved_db.is_philosopher) { ch_fasta = nextflow.Channel.empty() ch_prebuilt_db = nextflow.Channel - .fromPath(resolved_db.path, checkIfExists: true) + .fromPath(resolved_db.path, glob: false, checkIfExists: true) .map { db -> [[id: "${organism}_philosopher_database"], db] } } else { ch_fasta = nextflow.Channel - .fromPath(resolved_db.path, checkIfExists: true) + .fromPath(resolved_db.path, glob: false, checkIfExists: true) .map { db -> [[id: 'database'], db] } ch_prebuilt_db = nextflow.Channel.empty() } diff --git a/nextflow.config b/nextflow.config index e1061076..97b0c4d9 100644 --- a/nextflow.config +++ b/nextflow.config @@ -175,10 +175,10 @@ params { msstatslfq_feature_subset_protein = 'top3' msstatslfq_quant_summary_method = 'TMP' - // References (iproteomes - UniProt reference proteomes) + // References (UniProt reference proteomes, mirrors the nf-core igenomes pattern) genome = null - proteomes_base = null - proteomes_ignore = true + proteomes_base = 'https://rest.uniprot.org/uniprotkb/stream?format=fasta&includeIsoform=true&query=(reviewed:true)+AND+(proteome:' + proteomes_ignore = false // MultiQC options multiqc_config = null @@ -446,7 +446,7 @@ manifest { } validation { - defaultIgnoreParams = ["genomes"] + defaultIgnoreParams = ["genomes", "databases"] monochromeLogs = params.monochrome_logs } @@ -456,4 +456,3 @@ validation { // Load modules.config for DSL2 module specific options includeConfig 'conf/modules.config' - diff --git a/nextflow_schema.json b/nextflow_schema.json index 7018a8b6..54243d57 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -26,7 +26,7 @@ "organism": { "type": "string", "default": "Homo sapiens", - "description": "Organism name for SDRF generation (e.g., Homo sapiens, Mus musculus, Saccharomyces cerevisiae).", + "description": "Organism name for SDRF generation and, when --database is not given, for selecting the UniProt reference proteome (e.g., Homo sapiens, Mus musculus, Saccharomyces cerevisiae).", "fa_icon": "fas fa-dna" }, "dissociation_method": { @@ -122,7 +122,7 @@ "pattern": "^\\S+\\.(?:fasta|fa)$", "description": "Path to a protein database FASTA file.", "fa_icon": "fas fa-file", - "help_text": "A protein FASTA file for database search. For DIA workflows, if not provided, the pipeline uses a reference proteome based on the organism parameter (human, mouse, or yeast). For FragPipe-based workflows (DDA LFQ, TMT), the pipeline auto-resolves the database from the organism parameter." + "help_text": "A protein FASTA file for database search. Takes precedence over the reference proteome. If not provided, the pipeline downloads the UniProt reference proteome (Swiss-Prot reviewed + isoforms) for `--organism` from `conf/reference_proteomes.config`, and fails if the organism has no configured proteome." }, "diann_speclib": { "type": "string", @@ -800,7 +800,7 @@ "proteomes_base": { "type": "string", "description": "Base URL for UniProt reference proteome FASTA downloads.", - "default": null, + "default": "https://rest.uniprot.org/uniprotkb/stream?format=fasta&includeIsoform=true&query=(reviewed:true)+AND+(proteome:", "fa_icon": "fas fa-cloud-download-alt", "hidden": true }, @@ -808,7 +808,8 @@ "type": "boolean", "description": "Do not load the reference proteomes config.", "fa_icon": "fas fa-ban", - "hidden": true + "hidden": true, + "help_text": "Do not load `conf/reference_proteomes.config`. No UniProt reference proteome is then available, so `--database` (or `--philosopher_database` for FragPipe modes) must be given." } } }, diff --git a/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf b/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf index 3b96aae5..3daa03b5 100644 --- a/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_msproteomics_pipeline/main.nf @@ -224,6 +224,27 @@ def genomeExistsError() { error(error_string) } } +/** + * Resolve the protein FASTA for a search. + * --database is authoritative; otherwise the reference proteome configured for + * the organism in params.databases (conf/reference_proteomes.config, downloaded + * from UniProt at runtime) is used. Fails if neither is available. + * + * @param organism Organism name as returned by WorkflowUtils.convertOrganismToStandardName (e.g. 'Homo sapiens') + * @return FASTA path or URL + */ +def getProteinDatabase(String organism) { + if (params.database) { + return params.database + } + def entry = params.databases ? params.databases[organism] : null + if (entry?.database) { + return entry.database + } + def available = params.databases ? params.databases.keySet().join(', ') : 'none (--proteomes_ignore is set)' + error("No protein database for organism '${organism}': pass --database , or set --organism to one with a UniProt reference proteome in conf/reference_proteomes.config. Available: ${available}") +} + // // Generate methods description for MultiQC // diff --git a/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test b/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test new file mode 100644 index 00000000..996a0765 --- /dev/null +++ b/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test @@ -0,0 +1,68 @@ +nextflow_function { + + name "Test Functions" + script "../main.nf" + function "getProteinDatabase" + tag "subworkflows" + tag "subworkflows_local" + tag "utils_nfcore_msproteomics_pipeline" + tag "stub" + + test("getProteinDatabase - organism without --database resolves to the UniProt reference proteome") { + + when { + function { + """ + input[0] = 'Homo sapiens' + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert function.result == 'https://rest.uniprot.org/uniprotkb/stream?format=fasta&includeIsoform=true&query=(reviewed:true)+AND+(proteome:UP000005640)' } + ) + } + } + + test("getProteinDatabase - unknown organism without --database fails with a clear message") { + + when { + function { + """ + input[0] = 'Xenopus laevis' + """ + } + } + + then { + assertAll( + { assert function.failed }, + { assert function.stdout.any { it.contains("No protein database for organism 'Xenopus laevis': pass --database ") } }, + { assert function.stdout.any { it.contains('Available: Homo sapiens, Mus musculus') } } + ) + } + } + + test("getProteinDatabase - --database overrides the reference proteome") { + + when { + params { + database = 'custom_database.fasta' + } + function { + """ + input[0] = 'Homo sapiens' + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert function.result == 'custom_database.fasta' } + ) + } + } +} diff --git a/workflows/diann.nf b/workflows/diann.nf index f33eebb7..6074892e 100644 --- a/workflows/diann.nf +++ b/workflows/diann.nf @@ -8,6 +8,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_msproteomics_pipeline' +include { getProteinDatabase } from '../subworkflows/local/utils_nfcore_msproteomics_pipeline' // SDRF generation (bookkeeping only) include { GENERATE_SDRF_FROM_SAMPLESHEET } from '../modules/local/generate_sdrf_from_samplesheet/main' @@ -68,15 +69,8 @@ workflow MSPROTEOMICS_DIANN { // Convert raw files if needed FILE_PREPARATION(ch_input) - // Resolve database - def database - if (params.database) { - database = params.database - } else if (params.databases && params.databases[organism]?.database) { - database = params.databases[organism].database - } else { - error "Neither --database is set nor a default database is found for ${organism}" - } + // Resolve database: --database, else the UniProt reference proteome for the organism + def database = getProteinDatabase(organism) // Build DIA input channel with params from nextflow.config ch_dia_input = FILE_PREPARATION.out.results.map { meta, ms_file -> @@ -93,7 +87,8 @@ workflow MSPROTEOMICS_DIANN { ] } - Channel.fromPath(database).map { fasta -> + // glob: false keeps the query string of a UniProt REST URL (fromPath treats '?' as a glob) + Channel.fromPath(database, glob: false, checkIfExists: true).map { fasta -> [[id: fasta.baseName], fasta] }.set { ch_searchdb } From dd11dddaa796c14239f54347c23e3d451b483ffc Mon Sep 17 00:00:00 2001 From: an-altosian Date: Tue, 29 Sep 2026 22:10:30 +0000 Subject: [PATCH 11/13] fix: make every test profile run; DIANNR and IQ handle no rows passing protein-group FDR conf/test.config was the untouched nf-core template (viralrecon samplesheet, genome R64-1-1); -profile test is now a minimal DIA-NN test. test_tmtq searched the Erwinia TMT6 data against the human FASTA and had no FragPipe workflow; it now uses erwinia_carotovora.fasta and workflows/TMT6.workflow. test_tmt sets tmt_type TMT6; test_dda_lfq sets fragpipe_workflow explicitly. DIANNR and IQ no longer crash (subscript out of bounds / MissingFileException) when DIA-NN reports PG.Q.Value = 1 for every row on a small search space: they write header-only tables with a WARNING and fail loudly on an empty report. All test_* profiles and test verified end to end against the test data in nf-core/test-datasets#1953 (updated). --- CHANGELOG.md | 2 + conf/test.config | 33 +++++++-- conf/tests/test_dda_lfq.config | 1 + conf/tests/test_tmt.config | 1 + conf/tests/test_tmtq.config | 8 ++- modules/local/diannr/templates/diannr.r | 67 +++++++++++++++---- .../local/diannr/tests/diann_report_pgq1.tsv | 11 +++ modules/local/diannr/tests/main.nf.test | 65 ++++++++++++++++++ modules/local/diannr/tests/main.nf.test.snap | 31 ++++++++- modules/local/iq/templates/iq.r | 60 +++++++++++++---- modules/local/iq/tests/main.nf.test | 55 +++++++++++++++ modules/local/iq/tests/main.nf.test.snap | 19 +++++- nextflow.config | 11 +-- 13 files changed, 314 insertions(+), 50 deletions(-) create mode 100644 modules/local/diannr/tests/diann_report_pgq1.tsv diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fede6b3..ac6c6c5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `IQ`: no longer fails with "Missing output file(s) `maxlfq.tsv`" when no report row passes the FDR filter (`Q.Value`, `PG.Q.Value`, `Lib.Q.Value`, `Lib.PG.Q.Value`; e.g. `PG.Q.Value = 1` for every row on a 500-protein FASTA): `process_long_format()` wrote no file and R exited 0. A header-only `maxlfq.tsv` (`Protein.Group`, `Protein.Names`, `Genes`, the samples) is now written with a `WARNING: IQ: maxlfq.tsv: no report row passes ...` line giving the filter and the minimum q-values. A report with no rows, or with only contaminant rows, fails with `ERROR: IQ: ...`, and so does a run where rows pass but no `maxlfq.tsv` is written. New integration tests reuse the `DIANNR` 10-row report fixture; the `DIANNR` test now reads the task's `.command.err` (not the Nextflow console) for the warning. +- `DIANNR`: no longer fails with `subscript out of bounds` in `diann_maxlfq` when no report row passes the FDR filter (e.g. DIA-NN reports `PG.Q.Value = 1` for every row on a small search space such as a 500-protein FASTA). `diann_maxlfq` is only called when rows pass; otherwise, and for the `diann_matrix` outputs that were silently written as 0-byte files, a header-only table (the sample columns) is written with a `WARNING: DIANNR: : no report row passes ...` line. A report with no rows, or with only contaminant rows, fails with `ERROR: DIANNR: ...`; an empty table from rows that did pass fails too. New integration tests with a 10-row report fixture. - `MERGE_SPLIT_SEARCH`: the task fails at once with `ERROR: MERGE_SPLIT_SEARCH: no MSFragger*.jar found` (naming the searched `msfragger_dir` and `ext.fragpipe_tools_dir`) when no MSFragger jar is found; before, `java -jar` got an empty jar path and reported a misleading "Invalid or corrupt jarfile .tsv". `merge_split_search.py` also rejects a `--msfragger_cmd` whose `-jar` path is missing. - `MERGE_SPLIT_SEARCH` tests: the integration test runs in the FragPipe image given by `FRAGPIPE_CONTAINER` (it ran on the host before); a new stub-tagged test covers the missing-jar error; the stub snapshot no longer records the host Python version. - `FRAGPIPE_HEADLESS`: `manifest_content` is used again and is authoritative (file, experiment, bioreplicate, data type), so allinone runs keep one experiment per sample, empty bioreplicates for fractions, and `DDA+`; before, every LFQ file fell back to `experiment1` / `1` / `DDA`. diff --git a/conf/test.config b/conf/test.config index e3ab1d47..86760e48 100644 --- a/conf/test.config +++ b/conf/test.config @@ -2,7 +2,10 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nextflow config file for running minimal tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a fast and simple pipeline test. + Defines input files and everything required to run a fast and simple pipeline test: + a DIA-NN library-free search of one CPTAC DIA subset (spectra/dia_cptac_subset.mzML) + against a 1,000-entry human SwissProt subset, with fast search params + (charge 2-3, no missed cleavages, no variable mods). Use as follows: nextflow run nf-core/msproteomics -profile test, --outdir @@ -16,15 +19,33 @@ process { memory: '15.GB', time: '1.h' ] + cpus = 2 + memory = '6.GB' + time = '1.h' } params { config_profile_name = 'Test profile' config_profile_description = 'Minimal test dataset to check pipeline function' - // Input data - // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets - // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv'// Genome references - genome = 'R64-1-1' + test_mode = true + + // Input data (absolute URLs: tests/nextflow.config redefines pipelines_testdata_base_path) + mode = 'diann' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/samplesheets/test_dia.csv' + database = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/databases/human_sp_subset.fasta' + organism = 'homo_sapiens' + + // Fast DIA-NN search for a 5-min FAIMS gradient + diann_min_pr_mz = 350 + diann_max_pr_mz = 950 + min_peptide_length = 7 + max_peptide_length = 25 + min_precursor_charge = 2 + max_precursor_charge = 3 + allowed_missed_cleavages = 0 + max_mods = 0 + diann_performance_mode = true + diann_quick_mass_acc = true + skip_post_msstats = true } diff --git a/conf/tests/test_dda_lfq.config b/conf/tests/test_dda_lfq.config index 841bd774..8bb3f08a 100644 --- a/conf/tests/test_dda_lfq.config +++ b/conf/tests/test_dda_lfq.config @@ -18,5 +18,6 @@ params { input = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/samplesheets/test_dda_lfq.csv' database = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/databases/human_sp_subset.fasta' organism = 'homo_sapiens' + fragpipe_workflow = "${projectDir}/assets/LFQ-MBR.workflow" outdir = 'results' } diff --git a/conf/tests/test_tmt.config b/conf/tests/test_tmt.config index b590e2e7..3644109b 100644 --- a/conf/tests/test_tmt.config +++ b/conf/tests/test_tmt.config @@ -16,6 +16,7 @@ params { mode = 'fragpipe' tmt_mode = 'labelcheck' + tmt_type = 'TMT6' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/samplesheets/test_tmt.csv' database = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/databases/erwinia_carotovora.fasta' organism = 'erwinia_carotovora' diff --git a/conf/tests/test_tmtq.config b/conf/tests/test_tmtq.config index e71bf1d1..c32ed594 100644 --- a/conf/tests/test_tmtq.config +++ b/conf/tests/test_tmtq.config @@ -2,7 +2,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nextflow config file for TMT quantification workflow tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Uses FragPipe TMT quantification with small dataset. + Uses FragPipe TMT quantification on two TMT6 Erwinia plexes (PRIDE PXD000001). + Requires --fragpipe_container (licensed FragPipe image). Use as follows: nextflow run nf-core/msproteomics -profile test_tmtq,docker --outdir @@ -17,7 +18,8 @@ params { mode = 'fragpipe' tmt_mode = 'quant' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/samplesheets/test_tmtq.csv' - database = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/databases/human_sp_subset.fasta' - organism = 'homo_sapiens' + database = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/databases/erwinia_carotovora.fasta' + organism = 'erwinia_carotovora' + fragpipe_workflow = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/msproteomics/workflows/TMT6.workflow' outdir = 'results' } diff --git a/modules/local/diannr/templates/diannr.r b/modules/local/diannr/templates/diannr.r index 73a12199..e25450ce 100644 --- a/modules/local/diannr/templates/diannr.r +++ b/modules/local/diannr/templates/diannr.r @@ -15,39 +15,78 @@ q <- as.numeric("${q}") pg.q <- as.numeric("${pgq}") contaminant_pattern <- "${contaminant_pattern}" +# diann_matrix() filters at 1% precursor FDR unless q is given (see the calls below) +DIANN_MATRIX_DEFAULT_Q <- 0.01 +SAMPLE_HEADER <- "File.Name" + df <- diann_load(report) +if (nrow(df) == 0) { + stop(paste0("ERROR: DIANNR: DIA-NN report '", report, "' has no rows; DIA-NN identified nothing")) +} if (contaminant_pattern != "" && !is.null(contaminant_pattern)) { # Remove contaminant proteins df <- df[!grepl(contaminant_pattern, df\$Genes),] report <- paste0("contaminants_removed_", report) write_tsv(df, report) + if (nrow(df) == 0) { + stop(paste0("ERROR: DIANNR: every row of the DIA-NN report matches contaminant_pattern '", contaminant_pattern, "'")) + } +} +samples <- unique(df[[SAMPLE_HEADER]]) + +# Write a quantity matrix. When no report row passes the FDR filter (e.g. DIA-NN +# reports PG.Q.Value = 1 for every row because a small search space gives too few +# protein groups to estimate protein-group FDR), write a header-only table (the sample +# columns) and say so. An empty result from rows that did pass is a bug: fail. +write_quant_table <- function(quant, path, n_passing, filter_desc) { + if (n_passing == 0) { + message(paste0("WARNING: DIANNR: ", path, ": no report row passes ", filter_desc, + " (", nrow(df), " rows; min Q.Value = ", min(df\$Q.Value), + ", min PG.Q.Value = ", min(df\$PG.Q.Value), "); writing a header-only table")) + writeLines(paste(samples, collapse = "\t"), path) + return(invisible(NULL)) + } + if (is.null(quant) || nrow(quant) == 0) { + stop(paste0("ERROR: DIANNR: ", path, ": ", n_passing, " report rows pass ", filter_desc, + " but the quantity table is empty")) + } + write.table(quant, file.path(path), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") } +pass_matrix <- df\$Q.Value <= DIANN_MATRIX_DEFAULT_Q & df\$PG.Q.Value <= pg.q +matrix_filter_desc <- paste0("Q.Value <= ", DIANN_MATRIX_DEFAULT_Q, " & PG.Q.Value <= ", pg.q) # Precursors x samples matrix filtered at 1% precursor and protein group FDR precursors <- diann_matrix(df, pg.q = pg.q) - -write.table(precursors , file.path("precursors.tsv"), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") +write_quant_table(precursors, "precursors.tsv", sum(pass_matrix), matrix_filter_desc) # Peptides without modifications - taking the maximum of the respective precursor quantities peptides <- diann_matrix(df, id.header="Stripped.Sequence", pg.q = pg.q) - -write.table(peptides , file.path("peptides.tsv"), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") - -# Peptides without modifications - using the MaxLFQ algorithm -peptides.maxlfq <- diann_maxlfq(df[df\$Q.Value <= q,], id.header = "Stripped.Sequence", quantity.header = "Precursor.Normalised") -write.table(peptides.maxlfq , file.path("peptides_maxlfq.tsv"), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") +write_quant_table(peptides, "peptides.tsv", sum(pass_matrix), matrix_filter_desc) + +# Peptides without modifications - using the MaxLFQ algorithm. +# diann_maxlfq() cannot take an empty table: its loop runs over 1:length(groups) = 1:0 +# and fails with "subscript out of bounds", so it is only called when rows pass. +pass_peptide_lfq <- df\$Q.Value <= q +peptides.maxlfq <- NULL +if (any(pass_peptide_lfq)) { + peptides.maxlfq <- diann_maxlfq(df[pass_peptide_lfq,], id.header = "Stripped.Sequence", quantity.header = "Precursor.Normalised") +} +write_quant_table(peptides.maxlfq, "peptides_maxlfq.tsv", sum(pass_peptide_lfq), paste0("Q.Value <= ", q)) # Genes identified and quantified using proteotypic peptides unique.genes <- diann_matrix(df, id.header="Genes", quantity.header="Genes.MaxLFQ.Unique", proteotypic.only = T, pg.q = pg.q) - -write.table(unique.genes , file.path("unique_genes.tsv"), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") - +write_quant_table(unique.genes, "unique_genes.tsv", sum(pass_matrix & df\$Proteotypic != 0), + paste0(matrix_filter_desc, " & Proteotypic")) # Protein group quantities using MaxLFQ algorithm -protein.groups <- diann_maxlfq(df[df\$Q.Value <= pg.q & df\$PG.Q.Value <= pg.q,], group.header="Protein.Group", id.header = "Precursor.Id", quantity.header = "Precursor.Normalised") - -write.table(protein.groups , file.path("protein_groups_maxlfq.tsv"), row.names = TRUE, col.names = TRUE, quote = FALSE, sep = "\t") +pass_pg_lfq <- df\$Q.Value <= pg.q & df\$PG.Q.Value <= pg.q +protein.groups <- NULL +if (any(pass_pg_lfq)) { + protein.groups <- diann_maxlfq(df[pass_pg_lfq,], group.header="Protein.Group", id.header = "Precursor.Id", quantity.header = "Precursor.Normalised") +} +write_quant_table(protein.groups, "protein_groups_maxlfq.tsv", sum(pass_pg_lfq), + paste0("Q.Value <= ", pg.q, " & PG.Q.Value <= ", pg.q)) # # save versions file diff --git a/modules/local/diannr/tests/diann_report_pgq1.tsv b/modules/local/diannr/tests/diann_report_pgq1.tsv new file mode 100644 index 00000000..2c5c7d4c --- /dev/null +++ b/modules/local/diannr/tests/diann_report_pgq1.tsv @@ -0,0 +1,11 @@ +File.Name Run Protein.Group Protein.Ids Protein.Names Genes PG.Quantity PG.Normalised PG.MaxLFQ Genes.Quantity Genes.Normalised Genes.MaxLFQ Genes.MaxLFQ.Unique Modified.Sequence Stripped.Sequence Precursor.Id Precursor.Charge Q.Value PEP Global.Q.Value Protein.Q.Value PG.Q.Value Global.PG.Q.Value GG.Q.Value Translated.Q.Value Proteotypic Precursor.Quantity Precursor.Normalised Precursor.Translated Translated.Quality Ms1.Translated Quantity.Quality RT RT.Start RT.Stop iRT Predicted.RT Predicted.iRT First.Protein.Description Lib.Q.Value Lib.PG.Q.Value Ms1.Profile.Corr Ms1.Area Evidence Spectrum.Similarity Averagine Mass.Evidence CScore Decoy.Evidence Decoy.CScore Fragment.Quant.Raw Fragment.Quant.Corrected Fragment.Correlations MS2.Scan IM iIM Predicted.IM Predicted.iIM +dia_cptac_subset.mzML dia_cptac_subset Q12904 Q12904 AIMP1_HUMAN AIMP1 1.08449e+06 1.08449e+06 1.08449e+06 1.08449e+06 1.08449e+06 1.08449e+06 1.08449e+06 AILQATLREEK AILQATLREEK AILQATLREEK2 2 1.23943e-06 1.23943e-06 1 1 1 1 1 0 1 1.08449e+06 1.08449e+06 1.08449e+06 3.02103e+06 0.982506 29.0286 28.9016 29.2468 4.59774 28.9858 5.2277 Aminoacyl tRNA synthase complex-interacting multifunctional protein 1 0.00980392 0.0322581 0.989323 3.02103e+06 5.82007 0.484153 0.276592 0 0.999999 2.05399 1.93528e-06 468291;186630;345525;270672;263496;85200.9;0;4655.82;0;0;23117.7; 468291;186630;345525;270672;263496;85200.9;0;4655.82;0;0;23117.7; 0.979263;0.956056;0.991425;0.976729;0.888213;0.715127;0;0.10662;0;0;0.764923; 937 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P20700 P20700 LMNB1_HUMAN LMNB1 1.17941e+07 1.17941e+07 1.17941e+07 1.17941e+07 1.17941e+07 1.17941e+07 1.17941e+07 ALYETELADAR ALYETELADAR ALYETELADAR2 2 1.18041e-07 1.18041e-07 1 1 1 1 1 0 1 1.17941e+07 1.17941e+07 1.17941e+07 4.59606e+07 0.998878 41.5893 41.3809 41.9213 28.5426 41.8504 28.6924 Lamin-B1 0.00896003 0.0263158 0.979889 4.59606e+07 6.88294 0.604352 1 2.24785 1 1.21583 9.49356e-07 5.88907e+06;3.9812e+06;3.49487e+06;2.38879e+06;1.92384e+06;1.20605e+06;635013;685279;153086;172297;113963;3661.1; 5.88907e+06;3.9812e+06;3.49487e+06;2.38879e+06;1.92384e+06;1.20605e+06;635013;685279;153086;172297;113963;3661.1; 0.99892;0.998979;0.99629;0.997561;0.99854;0.998008;0.99444;0.99638;0.317428;0.832887;0.93133;0.316889; 1526 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P12270 P12270 TPR_HUMAN TPR 844551 844551 844551 844551 844551 844551 844551 ASTALSNEQQAR ASTALSNEQQAR ASTALSNEQQAR2 2 0.00990099 0.149015 1 1 1 1 1 0 1 58715.4 58715.4 58715.4 72196.4 0.814766 13.6175 13.4825 13.7531 -30.7209 13.6483 -30.4317 Nucleoprotein TPR 0.00980392 0.0263158 0.864066 72196.4 3.02392 0.237918 0.273345 0.440128 0.869194 2.57962 0.000296664 36868.1;13039.2;8808.13;66895;26354.2;5641.81;18213.3;4824.99;0;32825;31576.6; 36868.1;13039.2;8808.13;66895;26354.2;5641.81;18213.3;4824.99;0;32825;31576.6; 0.814766;0.814766;0.814766;0.701087;0.554041;0.0650778;0.809334;0.812575;0;0.703342;0.937897; 367 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset O00429 O00429 DNM1L_HUMAN DNM1L 246956 246956 246956 246956 246956 246956 246956 AVMHFLVNHVK AVMHFLVNHVK AVMHFLVNHVK2 2 8.73577e-05 8.73577e-05 1 1 1 1 1 0 1 246956 246956 246956 952611 0.816496 30.858 30.7753 30.9403 9.15999 29.9654 8.44587 Dynamin-1-like protein 0.00980392 0.0441176 0.993703 952611 3.5992 0.559053 0.26558 2.39833 0.999912 1.82423 5.09619e-05 67394;85039.3;14383.9;35340.8;44797.9;0;41066.8;47477.9;0;19935.3;34719.4;0; 67394;85039.3;14383.9;35340.8;44797.9;0;41066.8;47477.9;0;19935.3;34719.4;0; 0.816497;0.816497;0.816497;0.816497;0.816497;0;0.816497;0.816497;0;0.816497;0.816497;0; 1023 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P05026 P05026 AT1B1_HUMAN ATP1B1 1.10452e+06 1.10452e+06 1.10452e+06 1.10452e+06 1.10452e+06 1.10452e+06 1.10452e+06 AYGENIGYSEK AYGENIGYSEK AYGENIGYSEK2 2 0.00221769 0.00221769 1 1 1 1 1 0 1 1.10452e+06 1.10452e+06 1.10452e+06 4.96857e+06 0.856477 23.4632 23.3808 23.6901 -4.63724 23.1945 -4.98438 Sodium/potassium-transporting ATPase subunit beta-1 0.00980392 0.0263158 0.928355 4.96857e+06 4.18409 0.407502 0.284433 0 0.997765 1.93535 2.87181e-05 662495;678974;326403;316892;115618;95776.5;91375.2;0;0;0;0; 662495;678974;326403;316892;115618;95776.5;91375.2;0;0;0;0; 0.850059;0.83813;0.869134;0.835588;0.857523;0.735455;0.735455;0;0;0;0; 700 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P30101 P30101 PDIA3_HUMAN PDIA3 2.72292e+06 2.72292e+06 2.72292e+06 2.72292e+06 2.72292e+06 2.72292e+06 2.72292e+06 DGEEAGAYDGPR DGEEAGAYDGPR DGEEAGAYDGPR2 2 1e-09 0 1 1 1 1 1 0 1 2.72292e+06 2.72292e+06 2.72292e+06 7.68395e+06 0.995532 19.3077 18.8758 19.5547 -13.0619 19.5783 -12.9422 Protein disulfide-isomerase A3 0.00508263 0.0322581 0.993845 7.68395e+06 6.75546 0.601398 1 3.04152 1 1.77596 0.000412012 1.32175e+06;992041;1.1207e+06;506258;445512;409127;219789;96016.6;169007;5359.82;1988.07;56742.4; 1.32175e+06;992041;1.1207e+06;506258;445512;409127;219789;96016.6;169007;5359.82;1988.07;56742.4; 0.995043;0.996217;0.99292;0.979637;0.98994;0.995453;0.995534;0.986819;0.986647;0.666942;0.536807;0.739942; 538 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset O43707 O43707 ACTN4_HUMAN ACTN4 5.56933e+06 5.56933e+06 5.56934e+06 5.56933e+06 5.56933e+06 5.56934e+06 5.56934e+06 DHGGALGPEEFK DHGGALGPEEFK DHGGALGPEEFK2 2 1e-09 0 0.18719 1 1 1 1 0 1 5.56933e+06 5.56933e+06 5.56933e+06 2.90359e+07 0.997293 29.5896 29.2455 29.7975 5.62192 29.4962 6.15524 Alpha-actinin-4 0.0045512 0.0441176 0.989962 2.90359e+07 6.28609 0.472671 1 5.86799 1 1.8197 3.70504e-06 3.09059e+06;1.48684e+06;1.50216e+06;515944;976588;799713;742468;866374;533276;895344;880526;503299; 3.09059e+06;1.48684e+06;1.50216e+06;515944;976588;799713;742468;866374;533276;895344;880526;503299; 0.99708;0.97254;0.997045;0.943626;0.99835;0.986137;0.989269;0.990101;0.981273;0.99288;0.993401;0.989203; 962 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset O95721 O95721 SNP29_HUMAN SNAP29 1.0465e+06 1.0465e+06 1.0465e+06 1.0465e+06 1.0465e+06 1.0465e+06 1.0465e+06 DLPDGPDAPADR DLPDGPDAPADR DLPDGPDAPADR2 2 2.03034e-05 2.03034e-05 1 1 1 1 1 0 1 1.0465e+06 1.0465e+06 1.0465e+06 2.91749e+06 0.988082 27.7511 27.5561 27.9357 2.98717 27.9161 3.18197 Synaptosomal-associated protein 29 0.00980392 0.0322581 0.986866 2.91749e+06 6.21014 0.541613 0.992442 0.283409 0.999979 1.95017 3.97777e-05 345170;568678;121838;362287;479595;339046;164228;6466.22;55419.8;39233.4;5295.85;198107; 345170;568678;121838;362287;479595;339046;164228;6466.22;55419.8;39233.4;5295.85;198107; 0.99129;0.861991;0.958602;0.994203;0.972293;0.978276;0.986491;0.604167;0.845494;0.0178814;0.604167;0.470105; 878 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P08238 P08238 HS90B_HUMAN HSP90AB1 6.40531e+07 6.40531e+07 6.4053e+07 6.40531e+07 6.40531e+07 6.4053e+07 6.4053e+07 DNSTM(UniMod:35)GYM(UniMod:35)MAK DNSTMGYMMAK DNSTM(UniMod:35)GYM(UniMod:35)MAK2 2 0.000593214 0.000593214 1 1 1 1 1 0 1 38957.3 38957.3 38957.3 226712 0.930992 18.8777 18.6863 19.0686 -14.007 19.1293 -13.9944 Heat shock protein HSP 90-beta 0.00980392 0.0263158 0.97415 226712 3.39392 0.61721 1 0.538723 0.999401 1.05815 3.81807e-07 24133.5;8238.56;65571.7;6585.27;1633.12;13994.2;8249.25;10461.6;3026.56;0;1633.39;0; 24133.5;8238.56;65571.7;6585.27;1633.12;13994.2;8249.25;10461.6;3026.56;0;1633.39;0; 0.97765;0.880891;0.483135;0.822681;0.700811;0.378902;0.827234;0.808306;0.429689;0;0.700811;0; 525 0 0 0 0 +dia_cptac_subset.mzML dia_cptac_subset P08238 P08238 HS90B_HUMAN HSP90AB1 6.40531e+07 6.40531e+07 6.4053e+07 6.40531e+07 6.40531e+07 6.4053e+07 6.4053e+07 DNSTM(UniMod:35)GYMMAK DNSTMGYMMAK DNSTM(UniMod:35)GYMMAK2 2 0.0025635 0.0025635 1 1 1 1 1 0 1 364633 364633 364633 2.13005e+06 0.979461 26.4297 26.1883 26.8548 1.60761 26.8526 0.968816 Heat shock protein HSP 90-beta 0.00980392 0.0263158 0.925876 2.13005e+06 4.34645 0.435168 0.270721 0.61674 0.997418 2.10783 8.62879e-06 169999;57037.1;35107;0;88554.8;106079;28615.1;37450.4;0;23406.3;13163.7;0; 169999;57037.1;35107;0;88554.8;106079;28615.1;37450.4;0;23406.3;13163.7;0; 0.98429;0.940495;0.817597;0;0.987187;0.965274;0.581596;0.889413;0;0.670633;0.0700612;0; 827 0 0 0 0 diff --git a/modules/local/diannr/tests/main.nf.test b/modules/local/diannr/tests/main.nf.test index 565a2393..979cc653 100644 --- a/modules/local/diannr/tests/main.nf.test +++ b/modules/local/diannr/tests/main.nf.test @@ -40,4 +40,69 @@ nextflow_process { ) } } + + // Regression: DIA-NN on a small search space (500-protein human FASTA) reports + // PG.Q.Value = 1 for every row, so no row passes the protein-group FDR filter. + // diann_maxlfq() failed on the empty table with "subscript out of bounds". + test("diannr - no row passes protein-group FDR writes header-only tables") { + tag "integration" + + when { + process { + """ + input[0] = file("\${projectDir}/modules/local/diannr/tests/diann_report_pgq1.tsv", checkIfExists: true) + input[1] = 0.01 + input[2] = 0.05 + input[3] = "contaminant_" + """ + } + } + + then { + def header_only = ['precursors', 'peptides', 'unique_genes', 'protein_groups_maxlfq'] + assertAll ( + { assert process.success }, + { header_only.each { ch -> + assert path(process.out[ch][0]).readLines() == ['dia_cptac_subset.mzML'] : ch + } }, + { assert path(process.out.peptides_maxlfq[0]).readLines().size() > 1 }, + // process.stderr is the Nextflow console, not the task's; read the task's .command.err + { def task_err = new File(new File(process.out.protein_groups_maxlfq[0].toString()).parentFile, '.command.err').text + assert task_err.contains('WARNING: DIANNR: protein_groups_maxlfq.tsv: no report row passes') : task_err }, + { assert snapshot( + process.out.contaminants_removed_report, + process.out.precursors, + process.out.peptides, + process.out.peptides_maxlfq, + process.out.unique_genes, + process.out.protein_groups_maxlfq + ).match() } + ) + } + } + + test("diannr - report with no rows fails") { + tag "integration" + + when { + process { + """ + def report_file = file("\${workDir}/diann_report.tsv") + report_file.text = file("\${projectDir}/modules/local/diannr/tests/diann_report_pgq1.tsv", checkIfExists: true).readLines()[0] + "\\n" + + input[0] = report_file + input[1] = 0.01 + input[2] = 0.05 + input[3] = "contaminant_" + """ + } + } + + then { + assertAll ( + { assert process.failed }, + { assert process.errorReport.contains('ERROR: DIANNR: DIA-NN report') : process.errorReport } + ) + } + } } diff --git a/modules/local/diannr/tests/main.nf.test.snap b/modules/local/diannr/tests/main.nf.test.snap index 064b59f8..b3e36551 100644 --- a/modules/local/diannr/tests/main.nf.test.snap +++ b/modules/local/diannr/tests/main.nf.test.snap @@ -20,10 +20,37 @@ "protein_groups_maxlfq.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "timestamp": "2026-03-25T03:48:08.484524001", "meta": { "nf-test": "0.9.5", "nextflow": "25.10.2" - } + }, + "timestamp": "2026-03-25T03:48:08.484524001" + }, + "diannr - no row passes protein-group FDR writes header-only tables": { + "content": [ + [ + "contaminants_removed_diann_report_pgq1.tsv:md5,3489113b40c13a6cbecc0784afa29dc9" + ], + [ + "precursors.tsv:md5,db82e1b1bf4e7d9b11aad2e562d1c926" + ], + [ + "peptides.tsv:md5,db82e1b1bf4e7d9b11aad2e562d1c926" + ], + [ + "peptides_maxlfq.tsv:md5,9b8334ab7a8184f51e23fa6900dfd1a6" + ], + [ + "unique_genes.tsv:md5,db82e1b1bf4e7d9b11aad2e562d1c926" + ], + [ + "protein_groups_maxlfq.tsv:md5,db82e1b1bf4e7d9b11aad2e562d1c926" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-09-29T20:52:26.0106975" } } \ No newline at end of file diff --git a/modules/local/iq/templates/iq.r b/modules/local/iq/templates/iq.r index 54f975cd..f45b912b 100644 --- a/modules/local/iq/templates/iq.r +++ b/modules/local/iq/templates/iq.r @@ -15,28 +15,62 @@ q <- as.numeric("${q}") pg.q <- as.numeric("${pgq}") contaminant_pattern <- "${contaminant_pattern}" +SAMPLE_ID <- "Run" +PRIMARY_ID <- "Protein.Group" +ANNOTATION_COLS <- c("Protein.Names", "Genes") +OUTPUT_FILENAME <- "maxlfq.tsv" + df <- read_tsv(report) +if (nrow(df) == 0) { + stop(paste0("ERROR: IQ: DIA-NN report '", report, "' has no rows; DIA-NN identified nothing")) +} if (contaminant_pattern != "" && !is.null(contaminant_pattern)) { # Remove contaminant proteins df <- df[!grepl(contaminant_pattern, df\$Genes),] report <- paste0("contaminants_removed_", report) write_tsv(df, report) + if (nrow(df) == 0) { + stop(paste0("ERROR: IQ: every row of the DIA-NN report matches contaminant_pattern '", contaminant_pattern, "'")) + } } +# The same thresholds as filter_double_less below; iq keeps a row when value < threshold +fdr_filter <- c( + "Q.Value" = q, + "PG.Q.Value" = pg.q, + "Lib.Q.Value" = q, + "Lib.PG.Q.Value" = pg.q) +passing <- Reduce(`&`, lapply(names(fdr_filter), function(col) df[[col]] < fdr_filter[[col]])) +filter_desc <- paste(paste0(names(fdr_filter), " < ", fdr_filter), collapse = " & ") -# Precursors x samples matrix filtered at 1% precursor and protein group FDR -process_long_format( - report, - sample_id = "Run", - intensity_col = "Fragment.Quant.Raw", - output_filename = "maxlfq.tsv", - annotation_col = c("Protein.Names", "Genes"), - filter_double_less = c( - "Q.Value" = q, - "PG.Q.Value" = pg.q, - "Lib.Q.Value" = q, - "Lib.PG.Q.Value" = pg.q) -) + +# Protein x samples MaxLFQ matrix filtered at precursor and protein-group FDR. +# When no row passes (e.g. DIA-NN reports PG.Q.Value = 1 for every row because a small +# search space gives too few protein groups to estimate protein-group FDR), +# process_long_format() reports "# quantitative values after filtering = 0", returns +# without writing the output file, and R exits 0. Write a header-only table instead. +if (!any(passing)) { + message(paste0("WARNING: IQ: ", OUTPUT_FILENAME, ": no report row passes ", filter_desc, + " (", nrow(df), " rows; min Q.Value = ", min(df\$Q.Value), + ", min PG.Q.Value = ", min(df\$PG.Q.Value), + ", min Lib.Q.Value = ", min(df\$Lib.Q.Value), + ", min Lib.PG.Q.Value = ", min(df\$Lib.PG.Q.Value), "); writing a header-only table")) + writeLines(paste(c(PRIMARY_ID, ANNOTATION_COLS, unique(df[[SAMPLE_ID]])), collapse = "\\t"), OUTPUT_FILENAME) +} else { + process_long_format( + report, + sample_id = SAMPLE_ID, + primary_id = PRIMARY_ID, + intensity_col = "Fragment.Quant.Raw", + output_filename = OUTPUT_FILENAME, + annotation_col = ANNOTATION_COLS, + filter_double_less = fdr_filter + ) + if (!file.exists(OUTPUT_FILENAME)) { + stop(paste0("ERROR: IQ: ", sum(passing), " report rows pass ", filter_desc, + " but process_long_format() wrote no ", OUTPUT_FILENAME)) + } +} # # save versions file diff --git a/modules/local/iq/tests/main.nf.test b/modules/local/iq/tests/main.nf.test index 8cea2cc1..665c3786 100644 --- a/modules/local/iq/tests/main.nf.test +++ b/modules/local/iq/tests/main.nf.test @@ -33,4 +33,59 @@ nextflow_process { ) } } + + // Regression: DIA-NN on a small search space (500-protein human FASTA) reports + // PG.Q.Value = 1 for every row, so no row passes the protein-group FDR filter. + // process_long_format() then wrote no maxlfq.tsv and R exited 0, so the task + // failed with "Missing output file(s) `maxlfq.tsv`". + test("iq - no row passes protein-group FDR writes header-only maxlfq table") { + tag "integration" + + when { + process { + """ + input[0] = file("\${projectDir}/modules/local/diannr/tests/diann_report_pgq1.tsv", checkIfExists: true) + input[1] = 0.01 + input[2] = 0.05 + input[3] = "contaminant_" + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert path(process.out.maxlfq[0]).readLines() == ['Protein.Group\tProtein.Names\tGenes\tdia_cptac_subset'] }, + // process.stderr is the Nextflow console, not the task's; read the task's .command.err + { def task_err = new File(new File(process.out.maxlfq[0].toString()).parentFile, '.command.err').text + assert task_err.contains('WARNING: IQ: maxlfq.tsv: no report row passes Q.Value < 0.01 & PG.Q.Value < 0.05') : task_err }, + { assert snapshot(process.out.contaminants_removed_report, process.out.maxlfq).match() } + ) + } + } + + test("iq - report with no rows fails") { + tag "integration" + + when { + process { + """ + def report_file = file("\${workDir}/diann_report.tsv") + report_file.text = file("\${projectDir}/modules/local/diannr/tests/diann_report_pgq1.tsv", checkIfExists: true).readLines()[0] + "\\n" + + input[0] = report_file + input[1] = 0.01 + input[2] = 0.05 + input[3] = "contaminant_" + """ + } + } + + then { + assertAll ( + { assert process.failed }, + { assert process.errorReport.contains('ERROR: IQ: DIA-NN report') : process.errorReport } + ) + } + } } diff --git a/modules/local/iq/tests/main.nf.test.snap b/modules/local/iq/tests/main.nf.test.snap index 8ee7591b..98066108 100644 --- a/modules/local/iq/tests/main.nf.test.snap +++ b/modules/local/iq/tests/main.nf.test.snap @@ -1,4 +1,19 @@ { + "iq - no row passes protein-group FDR writes header-only maxlfq table": { + "content": [ + [ + "contaminants_removed_diann_report_pgq1.tsv:md5,3489113b40c13a6cbecc0784afa29dc9" + ], + [ + "maxlfq.tsv:md5,0d94e8b1397d40a736a4d634a532efa8" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-09-29T21:16:05.534390404" + }, "iq - stub": { "content": [ [ @@ -8,10 +23,10 @@ "maxlfq.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "timestamp": "2026-03-25T03:49:14.235592864", "meta": { "nf-test": "0.9.5", "nextflow": "25.10.2" - } + }, + "timestamp": "2026-03-25T03:49:14.235592864" } } \ No newline at end of file diff --git a/nextflow.config b/nextflow.config index 97b0c4d9..65a01b9b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -324,16 +324,7 @@ profiles { aws { docker.runOptions = '-u $(id -u):$(id -g)' } - test { - params.test_mode = true - - process { - resourceLimits = [ cpus: 2, memory: 6.GB, time: 1.h ] - cpus = 2 - memory = '6.GB' - time = '1.h' - } - } + test { includeConfig 'conf/test.config' } test_dia { includeConfig 'conf/tests/test_dia.config' } test_dda_lfq { includeConfig 'conf/tests/test_dda_lfq.config' } test_tmt { includeConfig 'conf/tests/test_tmt.config' } From c3db13cbe2f90b65ac9031348e7fe5cc2cdf4fdf Mon Sep 17 00:00:00 2001 From: an-altosian Date: Wed, 30 Sep 2026 04:36:31 +0000 Subject: [PATCH 12/13] style: apply pinned pre-commit hooks (prettier 3.6.2, trailing whitespace) The linting workflow's pre-commit job has failed on dev since 2026-03-25. Formatting only: modules.json content is unchanged, and the 19 .nf files differ only in trailing whitespace on blank lines (git diff -w is empty). --- README.md | 12 +- docs/fragpipe-docker/README.md | 33 ++--- docs/modules/README.md | 136 ++++++++++----------- docs/modules/crystalc.md | 36 +++--- docs/modules/decompress.md | 22 ++-- docs/modules/diannr.md | 40 +++--- docs/modules/diatracer.md | 38 +++--- docs/modules/diaumpire.md | 38 +++--- docs/modules/fpop.md | 36 +++--- docs/modules/fragpipe.md | 42 +++---- docs/modules/fragpipe_headless.md | 28 ++--- docs/modules/freequant.md | 34 +++--- docs/modules/generate_sdrf.md | 22 ++-- docs/modules/ionquant.md | 54 ++++---- docs/modules/iq.md | 26 ++-- docs/modules/mbg.md | 40 +++--- docs/modules/merge_split_search.md | 52 ++++---- docs/modules/metaproteomics.md | 42 +++---- docs/modules/msbooster.md | 36 +++--- docs/modules/msfragger.md | 54 ++++---- docs/modules/msfragger_calibrate.md | 36 +++--- docs/modules/msfragger_index.md | 36 +++--- docs/modules/msstats_lfq.md | 34 +++--- docs/modules/mzml_indexing.md | 24 ++-- docs/modules/mzml_statistics.md | 32 ++--- docs/modules/opair.md | 36 +++--- docs/modules/openms_peak_picker.md | 30 ++--- docs/modules/parse_fragpipe_workflow.md | 42 +++---- docs/modules/percolator.md | 42 +++---- docs/modules/philosopher_database.md | 32 ++--- docs/modules/philosopher_filter.md | 48 ++++---- docs/modules/philosopher_labelquant.md | 34 +++--- docs/modules/philosopher_peptideprophet.md | 38 +++--- docs/modules/philosopher_pipeline.md | 46 +++---- docs/modules/philosopher_proteinprophet.md | 34 +++--- docs/modules/philosopher_report.md | 42 +++---- docs/modules/pmultiqc.md | 36 +++--- docs/modules/preprocess_expdesign.md | 14 +-- docs/modules/ptmprophet.md | 32 ++--- docs/modules/ptmshepherd.md | 44 +++---- docs/modules/saintexpress.md | 38 +++--- docs/modules/samplesheet_check.md | 30 ++--- docs/modules/sdrf_parsing.md | 26 ++-- docs/modules/skyline.md | 40 +++--- docs/modules/speclibgen.md | 44 +++---- docs/modules/split_fasta.md | 26 ++-- docs/modules/tdf2mzml.md | 26 ++-- docs/modules/thermorawfileparser.md | 26 ++-- docs/modules/tmtintegrator.md | 40 +++--- docs/modules/tmtlabelcheck.md | 38 +++--- modules.json | 46 ++----- modules/local/crystalc/main.nf | 2 +- modules/local/diatracer/main.nf | 2 +- modules/local/diaumpire/main.nf | 2 +- modules/local/fpop/main.nf | 2 +- modules/local/fragpipe/main.nf | 2 +- modules/local/freequant/main.nf | 2 +- modules/local/ionquant/main.nf | 2 +- modules/local/mbg/main.nf | 2 +- modules/local/msbooster/main.nf | 2 +- modules/local/msfragger/main.nf | 2 +- modules/local/msfragger_calibrate/main.nf | 2 +- modules/local/opair/main.nf | 2 +- modules/local/percolator/main.nf | 2 +- modules/local/ptmprophet/main.nf | 2 +- modules/local/ptmshepherd/main.nf | 2 +- modules/local/saintexpress/main.nf | 2 +- modules/local/skyline/main.nf | 2 +- modules/local/speclibgen/main.nf | 2 +- modules/local/tmtintegrator/main.nf | 2 +- 70 files changed, 965 insertions(+), 986 deletions(-) diff --git a/README.md b/README.md index bd552c9e..d0a87b29 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ Instrument-specific settings are applied via optional config files (`-c conf/ins The `--mode` parameter selects the analysis engine. FragPipe sub-modes are controlled with `--tmt_mode` for TMT workflows. -| Mode | Sub-mode | Description | Engine | -| --- | --- | --- | --- | -| `diann` | -- | DIA quantitative proteomics (standard, phospho) | [DIA-NN](https://github.com/vdemichev/DiaNN) | -| `fragpipe` | *(none)* | Generic FragPipe workflows, configured by [workflow files](https://github.com/Nesvilab/FragPipe/tree/develop/workflows) | [FragPipe](https://fragpipe.nesvilab.org/) | -| `fragpipe` | `--tmt_mode labelcheck` | TMT labeling efficiency QC | [FragPipe](https://fragpipe.nesvilab.org/) | -| `fragpipe` | `--tmt_mode quant` | TMT isobaric quantification | [FragPipe](https://fragpipe.nesvilab.org/) | +| Mode | Sub-mode | Description | Engine | +| ---------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `diann` | -- | DIA quantitative proteomics (standard, phospho) | [DIA-NN](https://github.com/vdemichev/DiaNN) | +| `fragpipe` | _(none)_ | Generic FragPipe workflows, configured by [workflow files](https://github.com/Nesvilab/FragPipe/tree/develop/workflows) | [FragPipe](https://fragpipe.nesvilab.org/) | +| `fragpipe` | `--tmt_mode labelcheck` | TMT labeling efficiency QC | [FragPipe](https://fragpipe.nesvilab.org/) | +| `fragpipe` | `--tmt_mode quant` | TMT isobaric quantification | [FragPipe](https://fragpipe.nesvilab.org/) | DIA method variants (e.g., phospho) and instrument-specific settings are applied via `-c` config files. See [docs/usage.md](docs/usage.md) for full details. diff --git a/docs/fragpipe-docker/README.md b/docs/fragpipe-docker/README.md index 71ece1ae..11a7db56 100644 --- a/docs/fragpipe-docker/README.md +++ b/docs/fragpipe-docker/README.md @@ -7,6 +7,7 @@ # **FragPipe tools are licensed software. Uploading built images to Docker Hub, GitHub Container Registry, Quay.io, or any other public registry is a violation of the FragPipe license agreement.** **After building, store your image in:** + - A **local Docker daemon** (default after `docker build`) - A **private container registry** (e.g., AWS ECR, private Docker Hub repo, Artifactory) @@ -151,22 +152,22 @@ All FragPipe-based workflows (DDA LFQ, TMT Label Check, generic FragPipe) use th ## Tool Versions -| Tool | Version | License | -|------|---------|---------| -| Java | 17 (openjdk-17, from base image) | GPL-2.0 | -| MSFragger | 4.4.1 | Academic/Commercial | -| IonQuant | 1.11.20 | Academic/Commercial | -| DiaTracer | 2.2.1 | Academic/Commercial | -| Philosopher | 5.1.3-RC9 | GPL-3.0 | -| Percolator | 3.7.1 | Apache-2.0 | -| MSBooster | 1.4.14 (academic) / 1.4.17 (commercial) | LGPL-3.0 | -| PTMShepherd | 3.0.11 | Open Source | -| TMT-Integrator | 6.1.3 | Open Source | -| Crystal-C | 1.5.10 | Open Source | -| DIA-Umpire | 2.3.3 | Open Source | -| MBG | 0.3.6 | Open Source | -| batmass-io | 1.36.5 (academic) / 1.36.6 (commercial) | Open Source | -| DIA-NN | 1.8.1 | Free (bundled in FragPipe container) | +| Tool | Version | License | +| -------------- | --------------------------------------- | ------------------------------------ | +| Java | 17 (openjdk-17, from base image) | GPL-2.0 | +| MSFragger | 4.4.1 | Academic/Commercial | +| IonQuant | 1.11.20 | Academic/Commercial | +| DiaTracer | 2.2.1 | Academic/Commercial | +| Philosopher | 5.1.3-RC9 | GPL-3.0 | +| Percolator | 3.7.1 | Apache-2.0 | +| MSBooster | 1.4.14 (academic) / 1.4.17 (commercial) | LGPL-3.0 | +| PTMShepherd | 3.0.11 | Open Source | +| TMT-Integrator | 6.1.3 | Open Source | +| Crystal-C | 1.5.10 | Open Source | +| DIA-Umpire | 2.3.3 | Open Source | +| MBG | 0.3.6 | Open Source | +| batmass-io | 1.36.5 (academic) / 1.36.6 (commercial) | Open Source | +| DIA-NN | 1.8.1 | Free (bundled in FragPipe container) | ## Architecture diff --git a/docs/modules/README.md b/docs/modules/README.md index ed918f3f..df2bdfff 100644 --- a/docs/modules/README.md +++ b/docs/modules/README.md @@ -4,107 +4,107 @@ Index of all local module documentation for the nf-core/msproteomics pipeline. ## Data Format Conversion -| Module | Description | -|--------|-------------| -| [thermorawfileparser](thermorawfileparser.md) | Convert Thermo `.raw` files to open mass spectrometry formats | -| [tdf2mzml](tdf2mzml.md) | Convert Bruker `.d` (TDF) files to mzML format | -| [diatracer](diatracer.md) | Convert Bruker `.d` files to mzML for DIA analysis | -| [diaumpire](diaumpire.md) | Generate pseudo-spectra from DIA mass spectrometry data | -| [decompress](decompress.md) | Extract compressed archive files into Bruker `.d` directories | -| [mzml_indexing](mzml_indexing.md) | Index mzML files using OpenMS FileConverter for efficient random access | -| [openms_peak_picker](openms_peak_picker.md) | Centroid peak picking using OpenMS PeakPickerHiRes | +| Module | Description | +| --------------------------------------------- | ----------------------------------------------------------------------- | +| [thermorawfileparser](thermorawfileparser.md) | Convert Thermo `.raw` files to open mass spectrometry formats | +| [tdf2mzml](tdf2mzml.md) | Convert Bruker `.d` (TDF) files to mzML format | +| [diatracer](diatracer.md) | Convert Bruker `.d` files to mzML for DIA analysis | +| [diaumpire](diaumpire.md) | Generate pseudo-spectra from DIA mass spectrometry data | +| [decompress](decompress.md) | Extract compressed archive files into Bruker `.d` directories | +| [mzml_indexing](mzml_indexing.md) | Index mzML files using OpenMS FileConverter for efficient random access | +| [openms_peak_picker](openms_peak_picker.md) | Centroid peak picking using OpenMS PeakPickerHiRes | ## Database Preparation -| Module | Description | -|--------|-------------| +| Module | Description | +| ----------------------------------------------- | -------------------------------------------------------------------------------- | | [philosopher_database](philosopher_database.md) | Prepare protein database with decoy sequences and contaminants using Philosopher | -| [split_fasta](split_fasta.md) | Split a FASTA database into chunks for parallel MSFragger search | +| [split_fasta](split_fasta.md) | Split a FASTA database into chunks for parallel MSFragger search | ## Database Search -| Module | Description | -|--------|-------------| -| [msfragger](msfragger.md) | Ultrafast peptide identification using MSFragger database search engine | -| [msfragger_calibrate](msfragger_calibrate.md) | Mass calibration and parameter optimization for split-database search | -| [msfragger_index](msfragger_index.md) | Prebuild MSFragger pepindex files from FASTA and params | -| [merge_split_search](merge_split_search.md) | Merge MSFragger split-database search results per sample | -| [crystalc](crystalc.md) | Remove chimeric artifact PSMs from pepXML search results | +| Module | Description | +| --------------------------------------------- | ----------------------------------------------------------------------- | +| [msfragger](msfragger.md) | Ultrafast peptide identification using MSFragger database search engine | +| [msfragger_calibrate](msfragger_calibrate.md) | Mass calibration and parameter optimization for split-database search | +| [msfragger_index](msfragger_index.md) | Prebuild MSFragger pepindex files from FASTA and params | +| [merge_split_search](merge_split_search.md) | Merge MSFragger split-database search results per sample | +| [crystalc](crystalc.md) | Remove chimeric artifact PSMs from pepXML search results | ## PSM Validation -| Module | Description | -|--------|-------------| -| [msbooster](msbooster.md) | Deep learning-based PSM rescoring using predicted retention time and spectra | -| [percolator](percolator.md) | Semi-supervised PSM validation and FDR control using Percolator | -| [philosopher_peptideprophet](philosopher_peptideprophet.md) | Statistical validation of peptide assignments using PeptideProphet | -| [ptmprophet](ptmprophet.md) | PTM site localization using PTMProphet | +| Module | Description | +| ----------------------------------------------------------- | ---------------------------------------------------------------------------- | +| [msbooster](msbooster.md) | Deep learning-based PSM rescoring using predicted retention time and spectra | +| [percolator](percolator.md) | Semi-supervised PSM validation and FDR control using Percolator | +| [philosopher_peptideprophet](philosopher_peptideprophet.md) | Statistical validation of peptide assignments using PeptideProphet | +| [ptmprophet](ptmprophet.md) | PTM site localization using PTMProphet | ## Protein Inference -| Module | Description | -|--------|-------------| -| [philosopher_proteinprophet](philosopher_proteinprophet.md) | Statistical protein inference using ProteinProphet | -| [philosopher_filter](philosopher_filter.md) | FDR filtering and report generation using Philosopher | -| [philosopher_pipeline](philosopher_pipeline.md) | Combined Philosopher filter and report pipeline in a single process | -| [philosopher_report](philosopher_report.md) | Generate TSV reports from Philosopher workspace binaries | +| Module | Description | +| ----------------------------------------------------------- | ------------------------------------------------------------------- | +| [philosopher_proteinprophet](philosopher_proteinprophet.md) | Statistical protein inference using ProteinProphet | +| [philosopher_filter](philosopher_filter.md) | FDR filtering and report generation using Philosopher | +| [philosopher_pipeline](philosopher_pipeline.md) | Combined Philosopher filter and report pipeline in a single process | +| [philosopher_report](philosopher_report.md) | Generate TSV reports from Philosopher workspace binaries | ## Quantification -| Module | Description | -|--------|-------------| -| [ionquant](ionquant.md) | Label-free and isobaric quantification with match-between-runs and MaxLFQ | -| [freequant](freequant.md) | Label-free quantification using Philosopher's `freequant` command | -| [philosopher_labelquant](philosopher_labelquant.md) | Extract TMT/isobaric reporter ion intensities using Philosopher labelquant | -| [tmtintegrator](tmtintegrator.md) | TMT-Integrator for isobaric labeling quantification | -| [iq](iq.md) | Protein quantification using the iq R package with MaxLFQ algorithm | -| [msstats_lfq](msstats_lfq.md) | Statistical analysis of label-free quantification data using MSstats | -| [diannr](diannr.md) | R-based post-processing of DIA-NN output for contaminant removal and MaxLFQ quantification | +| Module | Description | +| --------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [ionquant](ionquant.md) | Label-free and isobaric quantification with match-between-runs and MaxLFQ | +| [freequant](freequant.md) | Label-free quantification using Philosopher's `freequant` command | +| [philosopher_labelquant](philosopher_labelquant.md) | Extract TMT/isobaric reporter ion intensities using Philosopher labelquant | +| [tmtintegrator](tmtintegrator.md) | TMT-Integrator for isobaric labeling quantification | +| [iq](iq.md) | Protein quantification using the iq R package with MaxLFQ algorithm | +| [msstats_lfq](msstats_lfq.md) | Statistical analysis of label-free quantification data using MSstats | +| [diannr](diannr.md) | R-based post-processing of DIA-NN output for contaminant removal and MaxLFQ quantification | ## PTM Analysis -| Module | Description | -|--------|-------------| +| Module | Description | +| ----------------------------- | ------------------------------------------------------------------------ | | [ptmshepherd](ptmshepherd.md) | Post-translational modification analysis and mass shift characterization | ## Glycoproteomics -| Module | Description | -|--------|-------------| -| [mbg](mbg.md) | Mass-based glycoproteomics matching for glycan identification | +| Module | Description | +| ----------------- | ---------------------------------------------------------------------------- | +| [mbg](mbg.md) | Mass-based glycoproteomics matching for glycan identification | | [opair](opair.md) | O-glycoproteomics analysis for O-glycan identification and site localization | ## QC and Reporting -| Module | Description | -|--------|-------------| -| [tmtlabelcheck](tmtlabelcheck.md) | Analyze TMT labeling efficiency from PSM data | -| [pmultiqc](pmultiqc.md) | Proteomics-specific QC report generation using the pmultiqc MultiQC plugin | -| [mzml_statistics](mzml_statistics.md) | Compute statistics from mzML files using quantms-utils | +| Module | Description | +| ------------------------------------- | -------------------------------------------------------------------------- | +| [tmtlabelcheck](tmtlabelcheck.md) | Analyze TMT labeling efficiency from PSM data | +| [pmultiqc](pmultiqc.md) | Proteomics-specific QC report generation using the pmultiqc MultiQC plugin | +| [mzml_statistics](mzml_statistics.md) | Compute statistics from mzML files using quantms-utils | ## Export -| Module | Description | -|--------|-------------| -| [skyline](skyline.md) | Create Skyline documents from FragPipe results for targeted quantification | -| [saintexpress](saintexpress.md) | Score protein-protein interactions from AP-MS data using SAINTexpress | -| [fpop](fpop.md) | Fast Photochemical Oxidation of Proteins (FPOP) analysis | -| [metaproteomics](metaproteomics.md) | Metaproteomics database optimization and taxonomy analysis | -| [speclibgen](speclibgen.md) | Generate spectral libraries using EasyPQP via FragPipe-SpecLib | +| Module | Description | +| ----------------------------------- | -------------------------------------------------------------------------- | +| [skyline](skyline.md) | Create Skyline documents from FragPipe results for targeted quantification | +| [saintexpress](saintexpress.md) | Score protein-protein interactions from AP-MS data using SAINTexpress | +| [fpop](fpop.md) | Fast Photochemical Oxidation of Proteins (FPOP) analysis | +| [metaproteomics](metaproteomics.md) | Metaproteomics database optimization and taxonomy analysis | +| [speclibgen](speclibgen.md) | Generate spectral libraries using EasyPQP via FragPipe-SpecLib | ## Workflow Orchestration -| Module | Description | -|--------|-------------| -| [fragpipe](fragpipe.md) | Run complete FragPipe proteomics workflow as an all-in-one process | -| [fragpipe_headless](fragpipe_headless.md) | Run FragPipe in headless mode as a single all-in-one process | -| [parse_fragpipe_workflow](parse_fragpipe_workflow.md) | Parse FragPipe workflow files into per-tool configuration files | +| Module | Description | +| ----------------------------------------------------- | ------------------------------------------------------------------ | +| [fragpipe](fragpipe.md) | Run complete FragPipe proteomics workflow as an all-in-one process | +| [fragpipe_headless](fragpipe_headless.md) | Run FragPipe in headless mode as a single all-in-one process | +| [parse_fragpipe_workflow](parse_fragpipe_workflow.md) | Parse FragPipe workflow files into per-tool configuration files | ## Utility -| Module | Description | -|--------|-------------| -| [generate_sdrf](generate_sdrf.md) | Convert a samplesheet CSV to SDRF format | -| [samplesheet_check](samplesheet_check.md) | Validate experimental design files (SDRF or samplesheet) using quantms-utils | -| [sdrf_parsing](sdrf_parsing.md) | Convert SDRF proteomics files into OpenMS experimental design format | -| [preprocess_expdesign](preprocess_expdesign.md) | Preprocess experimental design files for OpenMS compatibility | +| Module | Description | +| ----------------------------------------------- | ---------------------------------------------------------------------------- | +| [generate_sdrf](generate_sdrf.md) | Convert a samplesheet CSV to SDRF format | +| [samplesheet_check](samplesheet_check.md) | Validate experimental design files (SDRF or samplesheet) using quantms-utils | +| [sdrf_parsing](sdrf_parsing.md) | Convert SDRF proteomics files into OpenMS experimental design format | +| [preprocess_expdesign](preprocess_expdesign.md) | Preprocess experimental design files for OpenMS compatibility | diff --git a/docs/modules/crystalc.md b/docs/modules/crystalc.md index 0bd3faa0..35d2b13b 100644 --- a/docs/modules/crystalc.md +++ b/docs/modules/crystalc.md @@ -10,30 +10,30 @@ Used within the FRAGPIPE_SEARCH subworkflow after MSFragger database search. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| pepxml_file | path | Search results in pepXML format from MSFragger (`*.pepXML`) | -| mzml_file | path | Mass spectrometry data file for spectrum access (`*.mzML`, `*.mzXML`) | -| config_file | path | Crystal-C parameters file with paths configured (`*.params`) | -| fasta | path | Protein sequence database FASTA (shared resource) | +| Channel | Type | Description | +| ----------- | -------- | --------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| pepxml_file | path | Search results in pepXML format from MSFragger (`*.pepXML`) | +| mzml_file | path | Mass spectrometry data file for spectrum access (`*.mzML`, `*.mzXML`) | +| config_file | path | Crystal-C parameters file with paths configured (`*.params`) | +| fasta | path | Protein sequence database FASTA (shared resource) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing Crystal-C results and log | -| pepxml_filtered | tuple(meta, path) | Filtered pepXML files with chimeric artifacts removed (`*_c.pepXML`) | -| versions_crystalc | tuple | Crystal-C software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ----------------- | ----------------- | -------------------------------------------------------------------- | +| results_dir | tuple(meta, path) | Directory containing Crystal-C results and log | +| pepxml_filtered | tuple(meta, path) | Filtered pepXML files with chimeric artifacts removed (`*_c.pepXML`) | +| versions_crystalc | tuple | Crystal-C software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the `crystalc.Run` Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | -------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the `crystalc.Run` Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/decompress.md b/docs/modules/decompress.md index 130c4482..52b166e4 100644 --- a/docs/modules/decompress.md +++ b/docs/modules/decompress.md @@ -10,23 +10,23 @@ Used within the FILE_PREPARATION subworkflow for handling compressed Bruker raw ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | -| compressed_file | path | Compressed archive file (`.tar.gz`, `.gz`, `.tar`, `.zip`) | +| Channel | Type | Description | +| --------------- | -------- | ---------------------------------------------------------- | +| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | +| compressed_file | path | Compressed archive file (`.tar.gz`, `.gz`, `.tar`, `.zip`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| decompressed_files | tuple(meta, path) | Decompressed `.d` directory | -| versions | path | Software versions (`versions.yml`) for gunzip, tar, unzip | -| log | path | Decompression log file | +| Channel | Type | Description | +| ------------------ | ----------------- | --------------------------------------------------------- | +| decompressed_files | tuple(meta, path) | Decompressed `.d` directory | +| versions | path | Software versions (`versions.yml`) for gunzip, tar, unzip | +| log | path | Decompression log file | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| +| Parameter | Default | Description | +| ---------- | ------------ | -------------------------------- | | ext.prefix | meta.mzml_id | Override for the log file prefix | ## Container diff --git a/docs/modules/diannr.md b/docs/modules/diannr.md index ecf4221d..68399e12 100644 --- a/docs/modules/diannr.md +++ b/docs/modules/diannr.md @@ -10,32 +10,32 @@ The module uses an R template script (`diannr.r`) that receives parameters via N ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| report_path | path | DIA-NN main report TSV file | -| q | val | Precursor-level FDR threshold (q-value cutoff) | -| pgq | val | Protein group-level FDR threshold (q-value cutoff) | -| contaminant_pattern | val | Regex pattern to identify contaminant proteins (e.g., `"Cont_"`) | +| Channel | Type | Description | +| ------------------- | ---- | ---------------------------------------------------------------- | +| report_path | path | DIA-NN main report TSV file | +| q | val | Precursor-level FDR threshold (q-value cutoff) | +| pgq | val | Protein group-level FDR threshold (q-value cutoff) | +| contaminant_pattern | val | Regex pattern to identify contaminant proteins (e.g., `"Cont_"`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| contaminants_removed_report | path | `contaminants_removed_*.tsv` DIA-NN report with contaminants removed | -| precursors | path | `precursors.tsv` precursor-level quantification matrix | -| peptides | path | `peptides.tsv` peptide-level quantification matrix | -| peptides_maxlfq | path | `peptides_maxlfq.tsv` peptide-level MaxLFQ quantification matrix | -| unique_genes | path | `unique_genes.tsv` gene-level unique peptide quantification matrix | -| protein_groups_maxlfq | path | `protein_groups_maxlfq.tsv` protein group-level MaxLFQ quantification matrix | -| versions | path | `versions.yml` with R-base and diann-rpackage versions | +| Channel | Type | Description | +| --------------------------- | ---- | ---------------------------------------------------------------------------- | +| contaminants_removed_report | path | `contaminants_removed_*.tsv` DIA-NN report with contaminants removed | +| precursors | path | `precursors.tsv` precursor-level quantification matrix | +| peptides | path | `peptides.tsv` peptide-level quantification matrix | +| peptides_maxlfq | path | `peptides_maxlfq.tsv` peptide-level MaxLFQ quantification matrix | +| unique_genes | path | `unique_genes.tsv` gene-level unique peptide quantification matrix | +| protein_groups_maxlfq | path | `protein_groups_maxlfq.tsv` protein group-level MaxLFQ quantification matrix | +| versions | path | `versions.yml` with R-base and diann-rpackage versions | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| params.diann_maxlfq_q | - | Q-value threshold passed as the `q` input | -| params.diann_maxlfq_pgq | - | Protein group q-value threshold passed as the `pgq` input | -| params.contaminant_pattern | - | Contaminant pattern passed as the `contaminant_pattern` input | +| Parameter | Default | Description | +| -------------------------- | ------- | ------------------------------------------------------------- | +| params.diann_maxlfq_q | - | Q-value threshold passed as the `q` input | +| params.diann_maxlfq_pgq | - | Protein group q-value threshold passed as the `pgq` input | +| params.contaminant_pattern | - | Contaminant pattern passed as the `contaminant_pattern` input | ## Container diff --git a/docs/modules/diatracer.md b/docs/modules/diatracer.md index ccc072a4..0211da56 100644 --- a/docs/modules/diatracer.md +++ b/docs/modules/diatracer.md @@ -10,31 +10,31 @@ Used within the FRAGPIPE_CONVERT subworkflow for Bruker DIA file conversion. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| d_file | path | Bruker `.d` directory containing raw mass spectrometry data | -| config_cli | val(string) | diaTracer parameters as CLI string | -| diatracer_dir | path | Unzipped diaTracer tool directory (optional, pass `[]` when not using) | +| Channel | Type | Description | +| ------------- | ----------- | ---------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| d_file | path | Bruker `.d` directory containing raw mass spectrometry data | +| config_cli | val(string) | diaTracer parameters as CLI string | +| diatracer_dir | path | Unzipped diaTracer tool directory (optional, pass `[]` when not using) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing diaTracer results and log | -| mzml | tuple(meta, path) | Converted mzML file (`*_diatracer.mzML`) | -| license_agreement | path | License agreement marker file | -| versions_diatracer | tuple | diaTracer software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ------------------ | ----------------- | ---------------------------------------------- | +| results_dir | tuple(meta, path) | Directory containing diaTracer results and log | +| mzml | tuple(meta, path) | Converted mzML file (`*_diatracer.mzML`) | +| license_agreement | path | License agreement marker file | +| versions_diatracer | tuple | diaTracer software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the diaTracer Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | +| Parameter | Default | Description | +| ------------------------------------ | --------------- | --------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the diaTracer Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | ## Container diff --git a/docs/modules/diaumpire.md b/docs/modules/diaumpire.md index 7bf222f3..8228c31d 100644 --- a/docs/modules/diaumpire.md +++ b/docs/modules/diaumpire.md @@ -10,31 +10,31 @@ Used within the FRAGPIPE_CONVERT subworkflow for DIA data preprocessing. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| dia_file | path | DIA mass spectrometry data file (`*.mzML`, `*.mzXML`, or `*.raw`) | -| config_file | path | DIA-Umpire parameters file (`*.params`) | +| Channel | Type | Description | +| ----------- | -------- | ----------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| dia_file | path | DIA mass spectrometry data file (`*.mzML`, `*.mzXML`, or `*.raw`) | +| config_file | path | DIA-Umpire parameters file (`*.params`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing DIA-Umpire results and log | -| q1_spectra | tuple(meta, path) | Highest quality tier pseudo-spectra (`*_Q1.mzML`, optional) | -| q2_spectra | tuple(meta, path) | Medium quality tier pseudo-spectra (`*_Q2.mzML`, optional) | -| q3_spectra | tuple(meta, path) | Lowest quality tier pseudo-spectra (`*_Q3.mzML`, optional) | -| mgf_spectra | tuple(meta, path) | Pseudo-spectra in MGF format (`*_Q*.mgf`, optional) | -| versions_diaumpire | tuple | DIA-Umpire software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ------------------ | ----------------- | ----------------------------------------------------------- | +| results_dir | tuple(meta, path) | Directory containing DIA-Umpire results and log | +| q1_spectra | tuple(meta, path) | Highest quality tier pseudo-spectra (`*_Q1.mzML`, optional) | +| q2_spectra | tuple(meta, path) | Medium quality tier pseudo-spectra (`*_Q2.mzML`, optional) | +| q3_spectra | tuple(meta, path) | Lowest quality tier pseudo-spectra (`*_Q3.mzML`, optional) | +| mgf_spectra | tuple(meta, path) | Pseudo-spectra in MGF format (`*_Q*.mgf`, optional) | +| versions_diaumpire | tuple | DIA-Umpire software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the DIA-Umpire SE Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | ------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the DIA-Umpire SE Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/fpop.md b/docs/modules/fpop.md index 7d9cc866..714be719 100644 --- a/docs/modules/fpop.md +++ b/docs/modules/fpop.md @@ -10,30 +10,30 @@ Used within the FRAGPIPE_EXPORT subworkflow for structural proteomics experiment ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| input_file | path | Peptide quantification file (`combined_modified_peptide.tsv` for LFQ, or TMT abundance file) | -| secondary_file | path | Optional secondary TMT file (use `NO_FILE` placeholder if not applicable) | -| config_cli | val(string) | Bash-sourceable config: REGION_SIZE, CONTROL_LABEL, FPOP_LABEL, SUBTRACT_CONTROL, IS_TMT | +| Channel | Type | Description | +| -------------- | ----------- | -------------------------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| input_file | path | Peptide quantification file (`combined_modified_peptide.tsv` for LFQ, or TMT abundance file) | +| secondary_file | path | Optional secondary TMT file (use `NO_FILE` placeholder if not applicable) | +| config_cli | val(string) | Bash-sourceable config: REGION_SIZE, CONTROL_LABEL, FPOP_LABEL, SUBTRACT_CONTROL, IS_TMT | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing FPOP analysis results and log | -| results | tuple(meta, path) | FPOP analysis results in TSV format (`*_fpop*.tsv`, optional) | -| results_csv | tuple(meta, path) | FPOP analysis results in CSV format (`*_fpop*.csv`, optional) | -| versions_fpop | tuple | FPOP software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ----------------- | ----------------- | ------------------------------------------------------------- | +| results_dir | tuple(meta, path) | Directory containing FPOP analysis results and log | +| results | tuple(meta, path) | FPOP analysis results in TSV format (`*_fpop*.tsv`, optional) | +| results_csv | tuple(meta, path) | FPOP analysis results in CSV format (`*_fpop*.csv`, optional) | +| versions_fpop | tuple | FPOP software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the FPOP Python command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | ------------------------------------------------------------ | +| ext.args | '' | Additional CLI arguments appended to the FPOP Python command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/fragpipe.md b/docs/modules/fragpipe.md index d68b7027..e42ffd42 100644 --- a/docs/modules/fragpipe.md +++ b/docs/modules/fragpipe.md @@ -10,33 +10,33 @@ Used in the main `msproteomics.nf` workflow and the FRAGPIPE_WF subworkflow for ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (e.g., `[ id:'experiment1' ]`) | -| mzml_files | path | Mass spectrometry data files in mzML format | -| fasta | path | Protein sequence database in FASTA format | -| workflow_file | path | FragPipe `.workflow` configuration file | -| data_type | val(string) | Data type: `DDA`, `DIA`, `GPF-DIA`, `DIA-Quant`, `DIA-Lib`, `DDA+` | +| Channel | Type | Description | +| ------------- | ----------- | ------------------------------------------------------------------ | +| meta | val(map) | Sample metadata map (e.g., `[ id:'experiment1' ]`) | +| mzml_files | path | Mass spectrometry data files in mzML format | +| fasta | path | Protein sequence database in FASTA format | +| workflow_file | path | FragPipe `.workflow` configuration file | +| data_type | val(string) | Data type: `DDA`, `DIA`, `GPF-DIA`, `DIA-Quant`, `DIA-Lib`, `DDA+` | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Complete FragPipe output directory | -| proteins | tuple(meta, path) | Protein-level quantification results (`*/protein.tsv`) | -| peptides | tuple(meta, path) | Peptide-level quantification results (`*/peptide.tsv`) | -| psms | tuple(meta, path) | Peptide-spectrum match results (`*/psm.tsv`) | -| ions | tuple(meta, path) | Ion reports (`*/ion.tsv`, optional) | -| pepxml | tuple(meta, path) | pepXML search results (`*/*.pepXML`, optional) | -| protxml | tuple(meta, path) | Combined ProtXML (`combined.prot.xml`, optional) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ----------------- | ----------------- | ------------------------------------------------------ | +| results_dir | tuple(meta, path) | Complete FragPipe output directory | +| proteins | tuple(meta, path) | Protein-level quantification results (`*/protein.tsv`) | +| peptides | tuple(meta, path) | Peptide-level quantification results (`*/peptide.tsv`) | +| psms | tuple(meta, path) | Peptide-spectrum match results (`*/psm.tsv`) | +| ions | tuple(meta, path) | Ion reports (`*/ion.tsv`, optional) | +| pepxml | tuple(meta, path) | pepXML search results (`*/*.pepXML`, optional) | +| protxml | tuple(meta, path) | Combined ProtXML (`combined.prot.xml`, optional) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the `fragpipe --headless` command | -| ext.prefix | meta.id | Override for the output directory name | +| Parameter | Default | Description | +| ---------- | ------- | ---------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the `fragpipe --headless` command | +| ext.prefix | meta.id | Override for the output directory name | ## Container diff --git a/docs/modules/fragpipe_headless.md b/docs/modules/fragpipe_headless.md index d03d3c53..b3781dab 100644 --- a/docs/modules/fragpipe_headless.md +++ b/docs/modules/fragpipe_headless.md @@ -10,28 +10,28 @@ Used in the main `msproteomics.nf` workflow as an alternative to the modular FRA ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| raw_files | path | All raw data files (`.d`, `.raw`, `.mzML`) staged into `raw_files/` subdirectory | -| database | path | FASTA database file for protein identification | -| workflow_file | path | FragPipe `.workflow` configuration file | -| manifest_content | val(string) | Tab-separated manifest content (filename, experiment, bioreplicate, data_type) | +| Channel | Type | Description | +| ---------------- | ----------- | -------------------------------------------------------------------------------- | +| raw_files | path | All raw data files (`.d`, `.raw`, `.mzML`) staged into `raw_files/` subdirectory | +| database | path | FASTA database file for protein identification | +| workflow_file | path | FragPipe `.workflow` configuration file | +| manifest_content | val(string) | Tab-separated manifest content (filename, experiment, bioreplicate, data_type) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| all_results | path | All FragPipe output files (`results/**`) | +| Channel | Type | Description | +| ---------------- | ---- | --------------------------------------------------------------------------------- | +| all_results | path | All FragPipe output files (`results/**`) | | combined_protein | path | Combined protein report across all experiments (`combined_protein.tsv`, optional) | | combined_peptide | path | Combined peptide report across all experiments (`combined_peptide.tsv`, optional) | -| combined_ion | path | Combined ion report across all experiments (`combined_ion.tsv`, optional) | -| versions | path | Software versions (`versions.yml`) | +| combined_ion | path | Combined ion report across all experiments (`combined_ion.tsv`, optional) | +| versions | path | Software versions (`versions.yml`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| (memory) | 90% of task.memory | Java heap size computed automatically from allocated task memory | +| Parameter | Default | Description | +| --------- | ------------------ | ---------------------------------------------------------------- | +| (memory) | 90% of task.memory | Java heap size computed automatically from allocated task memory | ## Container diff --git a/docs/modules/freequant.md b/docs/modules/freequant.md index 11766bce..c2c3bd22 100644 --- a/docs/modules/freequant.md +++ b/docs/modules/freequant.md @@ -10,29 +10,29 @@ Used within the FRAGPIPE_QUANT subworkflow as an alternative to IonQuant for lab ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| results_dir | path | Directory containing `psm.tsv` from PHILOSOPHER_FILTER | -| mzml_dir | path | Directory containing mass spectrometry files (mzML or RAW) | -| config_cli | val(string) | FreeQuant parameters as CLI string (e.g., `--ptw 0.4 --tol 10`) | +| Channel | Type | Description | +| ----------- | ----------- | --------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| results_dir | path | Directory containing `psm.tsv` from PHILOSOPHER_FILTER | +| mzml_dir | path | Directory containing mass spectrometry files (mzML or RAW) | +| config_cli | val(string) | FreeQuant parameters as CLI string (e.g., `--ptw 0.4 --tol 10`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Output directory with results and `.meta/` workspace | -| ions | tuple(meta, path) | Ion-level quantification results (`ion.tsv`, optional) | -| versions_philosopher | tuple | Philosopher software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| -------------------- | ----------------- | ------------------------------------------------------ | +| results_dir | tuple(meta, path) | Output directory with results and `.meta/` workspace | +| ions | tuple(meta, path) | Ion-level quantification results (`ion.tsv`, optional) | +| versions_philosopher | tuple | Philosopher software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the `philosopher freequant` command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | ------------------------------------------------------------------------ | +| ext.args | '' | Additional CLI arguments appended to the `philosopher freequant` command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/generate_sdrf.md b/docs/modules/generate_sdrf.md index 0a50e2a6..d51dbcae 100644 --- a/docs/modules/generate_sdrf.md +++ b/docs/modules/generate_sdrf.md @@ -10,23 +10,23 @@ Used at the entry point of the main workflow when the user provides a sampleshee ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| samplesheet | path | Input samplesheet CSV with columns: sample, spectra, condition (and optional label, fraction, replicate) | -| params_json | val(string) | Pipeline parameters as JSON string containing experiment-level parameters | +| Channel | Type | Description | +| ----------- | ----------- | -------------------------------------------------------------------------------------------------------- | +| samplesheet | path | Input samplesheet CSV with columns: sample, spectra, condition (and optional label, fraction, replicate) | +| params_json | val(string) | Pipeline parameters as JSON string containing experiment-level parameters | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| sdrf | path | Generated SDRF-proteomics file (`*.sdrf.tsv`) | -| versions | path | Software versions (`versions.yml`) | +| Channel | Type | Description | +| -------- | ---- | --------------------------------------------- | +| sdrf | path | Generated SDRF-proteomics file (`*.sdrf.tsv`) | +| versions | path | Software versions (`versions.yml`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the `generate_sdrf.py` command | +| Parameter | Default | Description | +| --------- | ------- | ------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the `generate_sdrf.py` command | ## Container diff --git a/docs/modules/ionquant.md b/docs/modules/ionquant.md index d1d36c78..fc9360d6 100644 --- a/docs/modules/ionquant.md +++ b/docs/modules/ionquant.md @@ -10,40 +10,40 @@ Used within the FRAGPIPE_QUANT subworkflow and the TMT Label Check workflow for ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| psm_dirs | path | PHILOSOPHER_FILTER output directories (named by sample, containing `psm.tsv`) | -| spec_files | path | Spectral files (`*.mzML` or `*.raw`) staged in `spectra/` subdirectory | -| annotation_file | path | TMT annotation file (2-column or 6-column TSV; pass `[]` if not applicable) | -| config_cli | val(string) | IonQuant parameters as CLI string (e.g., `--mbr 1 --maxlfq 1`) | -| modmasses | val(string) | Comma-separated modification masses for `--modlist` (empty = skip) | -| ionquant_dir | path | Unzipped IonQuant tool directory (optional, pass `[]` when not using) | +| Channel | Type | Description | +| --------------- | ----------- | ----------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| psm_dirs | path | PHILOSOPHER_FILTER output directories (named by sample, containing `psm.tsv`) | +| spec_files | path | Spectral files (`*.mzML` or `*.raw`) staged in `spectra/` subdirectory | +| annotation_file | path | TMT annotation file (2-column or 6-column TSV; pass `[]` if not applicable) | +| config_cli | val(string) | IonQuant parameters as CLI string (e.g., `--mbr 1 --maxlfq 1`) | +| modmasses | val(string) | Comma-separated modification masses for `--modlist` (empty = skip) | +| ionquant_dir | path | Unzipped IonQuant tool directory (optional, pass `[]` when not using) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing all IonQuant output files | -| ions | tuple(meta, path) | Ion-level quantification (`ion.tsv`, optional) | -| combined_ions | tuple(meta, path) | Combined ion-level quantification across samples (`combined_ion.tsv`, optional) | -| combined_protein | tuple(meta, path) | Combined protein-level quantification (`combined_protein.tsv`, optional) | -| combined_peptide | tuple(meta, path) | Combined peptide-level quantification (`combined_peptide.tsv`, optional) | +| Channel | Type | Description | +| ------------------------- | ----------------- | ------------------------------------------------------------------------------------------ | +| results_dir | tuple(meta, path) | Directory containing all IonQuant output files | +| ions | tuple(meta, path) | Ion-level quantification (`ion.tsv`, optional) | +| combined_ions | tuple(meta, path) | Combined ion-level quantification across samples (`combined_ion.tsv`, optional) | +| combined_protein | tuple(meta, path) | Combined protein-level quantification (`combined_protein.tsv`, optional) | +| combined_peptide | tuple(meta, path) | Combined peptide-level quantification (`combined_peptide.tsv`, optional) | | combined_modified_peptide | tuple(meta, path) | Combined modified-peptide-level quantification (`combined_modified_peptide.tsv`, optional) | -| combined_site | tuple(meta, path) | Combined site-level quantification (`combined_site_*.tsv`, optional) | -| all_tsv | tuple(meta, path) | All TSV output files | -| license_agreement | path | License agreement marker file | -| versions_ionquant | tuple | IonQuant software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| combined_site | tuple(meta, path) | Combined site-level quantification (`combined_site_*.tsv`, optional) | +| all_tsv | tuple(meta, path) | All TSV output files | +| license_agreement | path | License agreement marker file | +| versions_ionquant | tuple | IonQuant software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the IonQuant Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | +| Parameter | Default | Description | +| ------------------------------------ | --------------- | -------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the IonQuant Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | ## Container diff --git a/docs/modules/iq.md b/docs/modules/iq.md index 8dcdb207..3698ea3d 100644 --- a/docs/modules/iq.md +++ b/docs/modules/iq.md @@ -10,26 +10,26 @@ Used in the main DIA workflow for protein-level quantification after DIA-NN anal ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| report_path | path | DIA-NN main report TSV file (`report.tsv`) | -| q | val | Precursor-level FDR threshold (q-value cutoff) | -| pgq | val | Protein group-level FDR threshold (q-value cutoff) | -| contaminant_pattern | val | Regex pattern to identify contaminant proteins (e.g., `Cont_`) | +| Channel | Type | Description | +| ------------------- | ---- | -------------------------------------------------------------- | +| report_path | path | DIA-NN main report TSV file (`report.tsv`) | +| q | val | Precursor-level FDR threshold (q-value cutoff) | +| pgq | val | Protein group-level FDR threshold (q-value cutoff) | +| contaminant_pattern | val | Regex pattern to identify contaminant proteins (e.g., `Cont_`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| +| Channel | Type | Description | +| --------------------------- | ---- | ----------------------------------------------------------------------------- | | contaminants_removed_report | path | DIA-NN report with contaminant entries removed (`contaminants_removed_*.tsv`) | -| maxlfq | path | MaxLFQ protein quantification matrix (`maxlfq.tsv`) | -| versions | path | Software versions (`versions.yml`) for r-base and iq | +| maxlfq | path | MaxLFQ protein quantification matrix (`maxlfq.tsv`) | +| versions | path | Software versions (`versions.yml`) for r-base and iq | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| (none) | - | Logic is in the R template `iq.r`; no ext.args used | +| Parameter | Default | Description | +| --------- | ------- | --------------------------------------------------- | +| (none) | - | Logic is in the R template `iq.r`; no ext.args used | ## Container diff --git a/docs/modules/mbg.md b/docs/modules/mbg.md index f42f6895..7d70659d 100644 --- a/docs/modules/mbg.md +++ b/docs/modules/mbg.md @@ -10,32 +10,32 @@ Used within the FRAGPIPE_GLYCO subworkflow for glycoproteomics analysis. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| psm_file | path | PSM file from PHILOSOPHER_FILTER (`psm.tsv`) | -| manifest_file | path | FragPipe manifest file listing input files (`*.fp-manifest`) | -| config_cli | val(string) | MBG parameters as CLI string (e.g., `--maxq 0.01 --mztol 10`) | -| residue_db | path | Glycan residues database file (shared resource) | -| glycan_mod_db | path | Glycan modifications database file (shared resource) | +| Channel | Type | Description | +| ------------- | ----------- | ------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| psm_file | path | PSM file from PHILOSOPHER_FILTER (`psm.tsv`) | +| manifest_file | path | FragPipe manifest file listing input files (`*.fp-manifest`) | +| config_cli | val(string) | MBG parameters as CLI string (e.g., `--maxq 0.01 --mztol 10`) | +| residue_db | path | Glycan residues database file (shared resource) | +| glycan_mod_db | path | Glycan modifications database file (shared resource) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing MBG results and log | -| results | tuple(meta, path) | MBG matching results (`*_mbg*.tsv`, optional) | -| glycan_results | tuple(meta, path) | Glycan-level results (`*_glycan*.tsv`, optional) | -| versions_mbg | tuple | MBG software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ----------------- | ----------------- | ------------------------------------------------ | +| results_dir | tuple(meta, path) | Directory containing MBG results and log | +| results | tuple(meta, path) | MBG matching results (`*_mbg*.tsv`, optional) | +| glycan_results | tuple(meta, path) | Glycan-level results (`*_glycan*.tsv`, optional) | +| versions_mbg | tuple | MBG software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the MBG Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | --------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the MBG Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/merge_split_search.md b/docs/modules/merge_split_search.md index eb9be75c..b7569c33 100644 --- a/docs/modules/merge_split_search.md +++ b/docs/modules/merge_split_search.md @@ -10,38 +10,38 @@ Used within the FRAGPIPE_SEARCH subworkflow when MSFragger runs with split-datab ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (e.g., `[ id:'sample1' ]`) | -| chunk_pepxmls | path | pepXML files from all database chunks for this sample (chunk-prefixed) | -| chunk_pins | path | PIN (Percolator input) files from all database chunks (chunk-prefixed) | -| chunk_histograms | path | Score histogram TSV files from all database chunks (chunk-prefixed) | -| num_chunks | val(int) | Number of database chunks used in the split search | -| params_file | path | MSFragger params file (for `output_report_topN`, `output_max_expect` settings) | -| msfragger_dir | path | Unzipped MSFragger tool directory (optional, pass `[]` when not using) | +| Channel | Type | Description | +| ---------------- | -------- | ------------------------------------------------------------------------------ | +| meta | val(map) | Sample metadata map (e.g., `[ id:'sample1' ]`) | +| chunk_pepxmls | path | pepXML files from all database chunks for this sample (chunk-prefixed) | +| chunk_pins | path | PIN (Percolator input) files from all database chunks (chunk-prefixed) | +| chunk_histograms | path | Score histogram TSV files from all database chunks (chunk-prefixed) | +| num_chunks | val(int) | Number of database chunks used in the split search | +| params_file | path | MSFragger params file (for `output_report_topN`, `output_max_expect` settings) | +| msfragger_dir | path | Unzipped MSFragger tool directory (optional, pass `[]` when not using) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| pepxml | tuple(meta, path) | Merged pepXML file with re-ranked search hits (`merged/*.pepXML`) | -| pin | tuple(meta, path) | Merged PIN file with re-ranked and reconciled protein lists (`merged/*.pin`) | -| license_agreement | path | License agreement marker file | -| versions_python | tuple | Python software version (topic channel) | -| versions_msfragger | tuple | MSFragger software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ------------------ | ----------------- | ---------------------------------------------------------------------------- | +| pepxml | tuple(meta, path) | Merged pepXML file with re-ranked search hits (`merged/*.pepXML`) | +| pin | tuple(meta, path) | Merged PIN file with re-ranked and reconciled protein lists (`merged/*.pin`) | +| license_agreement | path | License agreement marker file | +| versions_python | tuple | Python software version (topic channel) | +| versions_msfragger | tuple | MSFragger software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.prefix | meta.id | Override for the sample name | -| ext.output_report_topN | 1 | Number of top hits to keep per spectrum | -| ext.output_max_expect | 50.0 | Maximum expect value threshold for merged results | -| ext.fasta_path | (none) | FASTA path for MSFragger expect function generation | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | -| ext.java_xmx | (auto) | Override for Java heap size | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | +| Parameter | Default | Description | +| ------------------------------------ | --------------- | --------------------------------------------------- | +| ext.prefix | meta.id | Override for the sample name | +| ext.output_report_topN | 1 | Number of top hits to keep per spectrum | +| ext.output_max_expect | 50.0 | Maximum expect value threshold for merged results | +| ext.fasta_path | (none) | FASTA path for MSFragger expect function generation | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| ext.java_xmx | (auto) | Override for Java heap size | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` or the process exits with an error | ## Container diff --git a/docs/modules/metaproteomics.md b/docs/modules/metaproteomics.md index b5255aa2..44648025 100644 --- a/docs/modules/metaproteomics.md +++ b/docs/modules/metaproteomics.md @@ -10,33 +10,33 @@ Used within the FRAGPIPE_EXPORT subworkflow for metaproteomics experiments requi ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| project_dir | path | Directory containing FragPipe results for taxonomy analysis | -| config_cli | val(string) | Metaproteomics parameters as CLI string (e.g., `--decoyTag rev_ --qvalue 0.01 --iterations 2`) | -| fasta | path | Protein sequence database in FASTA format (shared resource) | -| taxon_name_file | path | NCBI taxonomy `names.dmp` file (shared resource) | -| taxon_node_file | path | NCBI taxonomy `nodes.dmp` file (shared resource) | +| Channel | Type | Description | +| --------------- | ----------- | ---------------------------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| project_dir | path | Directory containing FragPipe results for taxonomy analysis | +| config_cli | val(string) | Metaproteomics parameters as CLI string (e.g., `--decoyTag rev_ --qvalue 0.01 --iterations 2`) | +| fasta | path | Protein sequence database in FASTA format (shared resource) | +| taxon_name_file | path | NCBI taxonomy `names.dmp` file (shared resource) | +| taxon_node_file | path | NCBI taxonomy `nodes.dmp` file (shared resource) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(meta, path) | Directory containing metaproteomics results and log | -| optimized_fasta | tuple(meta, path) | Optimized FASTA database filtered by taxonomic analysis (`*_optimized.fasta`, optional) | -| taxonomy_results | tuple(meta, path) | Taxonomy analysis results (`*_taxonomy*.tsv`, optional) | -| results | tuple(meta, path) | Metaproteomics analysis results (`*_metaproteomics*.tsv`, optional) | -| versions_metaproteomics | tuple | Metaproteomics (FP-Meta) software version (topic channel) | -| versions_fragpipe | tuple | FragPipe software version (topic channel) | +| Channel | Type | Description | +| ----------------------- | ----------------- | --------------------------------------------------------------------------------------- | +| results_dir | tuple(meta, path) | Directory containing metaproteomics results and log | +| optimized_fasta | tuple(meta, path) | Optimized FASTA database filtered by taxonomic analysis (`*_optimized.fasta`, optional) | +| taxonomy_results | tuple(meta, path) | Taxonomy analysis results (`*_taxonomy*.tsv`, optional) | +| results | tuple(meta, path) | Metaproteomics analysis results (`*_metaproteomics*.tsv`, optional) | +| versions_metaproteomics | tuple | Metaproteomics (FP-Meta) software version (topic channel) | +| versions_fragpipe | tuple | FragPipe software version (topic channel) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the FP-Meta DbOptimizer Java command | -| ext.prefix | meta.id | Override for the output directory name | -| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | --------------- | ------------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the FP-Meta DbOptimizer Java command | +| ext.prefix | meta.id | Override for the output directory name | +| ext.fragpipe_tools_dir | (auto-detected) | Override for the FragPipe tools directory path | ## Container diff --git a/docs/modules/msbooster.md b/docs/modules/msbooster.md index 539fadff..2146d686 100644 --- a/docs/modules/msbooster.md +++ b/docs/modules/msbooster.md @@ -10,30 +10,30 @@ MSBooster is part of the FragPipe suite and fits in the pipeline between MSFragg ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| pin_files | path | PIN files from MSFragger search (`*.pin`) | -| mzml_files | path | Mass spectrometry data files (`*.mzML`) | -| params_file | path | Full MSBooster params file (key=value format). Pass `[]` when not using | -| fragger_params | path | MSFragger params file for modification definitions. Pass `[]` when not using | -| has_ion_mobility | val(boolean) | Whether input data has ion mobility (e.g., Bruker timsTOF .d files) | +| Channel | Type | Description | +| ---------------- | ------------ | ---------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| pin_files | path | PIN files from MSFragger search (`*.pin`) | +| mzml_files | path | Mass spectrometry data files (`*.mzML`) | +| params_file | path | Full MSBooster params file (key=value format). Pass `[]` when not using | +| fragger_params | path | MSFragger params file for modification definitions. Pass `[]` when not using | +| has_ion_mobility | val(boolean) | Whether input data has ion mobility (e.g., Bruker timsTOF .d files) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Results directory containing rescored PIN files and logs | -| pin_edited | tuple(val, path) | Rescored PIN files with additional features (renamed from `*_edited.pin`) | -| versions_msbooster | tuple (topic: versions) | MSBooster version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------ | ----------------------- | ------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Results directory containing rescored PIN files and logs | +| pin_edited | tuple(val, path) | Rescored PIN files with additional features (renamed from `*_edited.pin`) | +| versions_msbooster | tuple (topic: versions) | MSBooster version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to `java ... MainClass --paramsList` command | -| ext.fragpipe_tools_dir | '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' | Override FragPipe tools directory path | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------ | +| ext.args | '' | Additional CLI arguments appended to `java ... MainClass --paramsList` command | +| ext.fragpipe_tools_dir | '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' | Override FragPipe tools directory path | ## Container diff --git a/docs/modules/msfragger.md b/docs/modules/msfragger.md index 6942319f..c119e762 100644 --- a/docs/modules/msfragger.md +++ b/docs/modules/msfragger.md @@ -10,39 +10,39 @@ This module supports both params-file mode (FragPipe calling convention) and CLI ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (may include `chunk_id` for split mode) | -| mzml_files | path | Mass spectrometry data files (`*.mzML`) | -| fasta | path | Protein sequence database (`*.fasta`) | -| params_file | path | MSFragger params file (native fragger.params format). Pass `[]` for CLI mode | -| pepindex | path | Prebuilt pepindex files from MSFRAGGER_INDEX. Pass `[]` when not using | -| msfragger_dir | path | Unzipped MSFragger tool directory (optional). Pass `[]` when not using | +| Channel | Type | Description | +| ------------- | -------- | ---------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map (may include `chunk_id` for split mode) | +| mzml_files | path | Mass spectrometry data files (`*.mzML`) | +| fasta | path | Protein sequence database (`*.fasta`) | +| params_file | path | MSFragger params file (native fragger.params format). Pass `[]` for CLI mode | +| pepindex | path | Prebuilt pepindex files from MSFRAGGER_INDEX. Pass `[]` when not using | +| msfragger_dir | path | Unzipped MSFragger tool directory (optional). Pass `[]` when not using | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| pepxml | tuple(val, path) | PepXML search results (`*.pepXML`, optional) | -| pin | tuple(val, path) | Percolator input files (`*.pin`, optional) | -| tsv | tuple(val, path) | TSV outputs such as mass calibration results (optional) | -| calibrated_mzml | tuple(val, path) | Calibrated mzML files (when write_calibrated_mzml=true, optional) | -| uncalibrated_mzml | tuple(val, path) | Uncalibrated mzML for .d/.raw inputs (optional) | -| results_dir | tuple(val, path) | Results directory containing all output files | -| log | tuple(val, path) | Log files (optional) | -| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | -| versions_msfragger | tuple (topic: versions) | MSFragger version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------ | ----------------------- | ----------------------------------------------------------------- | +| pepxml | tuple(val, path) | PepXML search results (`*.pepXML`, optional) | +| pin | tuple(val, path) | Percolator input files (`*.pin`, optional) | +| tsv | tuple(val, path) | TSV outputs such as mass calibration results (optional) | +| calibrated_mzml | tuple(val, path) | Calibrated mzML files (when write_calibrated_mzml=true, optional) | +| uncalibrated_mzml | tuple(val, path) | Uncalibrated mzML for .d/.raw inputs (optional) | +| results_dir | tuple(val, path) | Results directory containing all output files | +| log | tuple(val, path) | Log files (optional) | +| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | +| versions_msfragger | tuple (topic: versions) | MSFragger version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the MSFragger Java command | -| ext.calibrate_mass | (not set) | Override calibrate_mass in params file (only when explicitly set) | -| ext.write_calibrated_mzml | (not set) | Override write_calibrated_mzml (only when explicitly set) | -| ext.java_xmx | (auto) | Override Java heap size | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | +| Parameter | Default | Description | +| ------------------------------------ | ---------- | ----------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the MSFragger Java command | +| ext.calibrate_mass | (not set) | Override calibrate_mass in params file (only when explicitly set) | +| ext.write_calibrated_mzml | (not set) | Override write_calibrated_mzml (only when explicitly set) | +| ext.java_xmx | (auto) | Override Java heap size | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | ## Container diff --git a/docs/modules/msfragger_calibrate.md b/docs/modules/msfragger_calibrate.md index 0f94a666..f98e40c8 100644 --- a/docs/modules/msfragger_calibrate.md +++ b/docs/modules/msfragger_calibrate.md @@ -10,31 +10,31 @@ This is an AGGREGATE process that runs once with all samples collected together, ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| fasta | path | Protein sequence database (`*.fasta`) | -| mzml_files | path | ALL mass spectrometry data files collected (`*.mzML`) | -| params_file | path | MSFragger params file (native fragger.params format) | +| Channel | Type | Description | +| ------------- | ---- | ---------------------------------------------------------------------- | +| fasta | path | Protein sequence database (`*.fasta`) | +| mzml_files | path | ALL mass spectrometry data files collected (`*.mzML`) | +| params_file | path | MSFragger params file (native fragger.params format) | | msfragger_dir | path | Unzipped MSFragger tool directory (optional). Pass `[]` when not using | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| calibrated_spectra | path | `.mzBIN_calibrated` files (or original copies if not calibrated) | -| params | path | Updated `calibrated_fragger.params` with optimized tolerances, `check_spectral_files=0`, `calibrate_mass=0` | -| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | -| versions_msfragger | tuple (topic: versions) | MSFragger version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- | +| calibrated_spectra | path | `.mzBIN_calibrated` files (or original copies if not calibrated) | +| params | path | Updated `calibrated_fragger.params` with optimized tolerances, `check_spectral_files=0`, `calibrate_mass=0` | +| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | +| versions_msfragger | tuple (topic: versions) | MSFragger version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the MSFragger `--split1` command | -| ext.java_xmx | (auto) | Override Java heap size | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ------------------------------------ | -------------- | --------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the MSFragger `--split1` command | +| ext.java_xmx | (auto) | Override Java heap size | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/msfragger_index.md b/docs/modules/msfragger_index.md index 47b85a49..126a639e 100644 --- a/docs/modules/msfragger_index.md +++ b/docs/modules/msfragger_index.md @@ -10,30 +10,30 @@ The module sets `calibrate_mass = 0` in the params to prevent calibration during ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata map | -| fasta | path | Protein sequence database (`*.fasta`) | -| params_file | path | MSFragger params file (native fragger.params format) | -| msfragger_dir | path | Unzipped MSFragger tool directory (optional). Pass `[]` when not using | +| Channel | Type | Description | +| ------------- | -------- | ---------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata map | +| fasta | path | Protein sequence database (`*.fasta`) | +| params_file | path | MSFragger params file (native fragger.params format) | +| msfragger_dir | path | Unzipped MSFragger tool directory (optional). Pass `[]` when not using | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| indexed_fasta | tuple(val, path, path) | FASTA + co-located pepindex files (must stay together for MSFragger reuse) | -| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | -| versions_msfragger | tuple (topic: versions) | MSFragger version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------ | ----------------------- | -------------------------------------------------------------------------- | +| indexed_fasta | tuple(val, path, path) | FASTA + co-located pepindex files (must stay together for MSFragger reuse) | +| license_agreement | path | License agreement file (`I_AGREE_FRAGPIPE_LICENSE_AGREEMENT`) | +| versions_msfragger | tuple (topic: versions) | MSFragger version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to the MSFragger digest command | -| ext.java_xmx | (auto) | Override Java heap size | -| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ------------------------------------ | -------------- | ----------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to the MSFragger digest command | +| ext.java_xmx | (auto) | Override Java heap size | +| ext.agree_fragpipe_license_agreement | (required) | Must be `true` to run | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/msstats_lfq.md b/docs/modules/msstats_lfq.md index 6790e39f..455d99be 100644 --- a/docs/modules/msstats_lfq.md +++ b/docs/modules/msstats_lfq.md @@ -10,30 +10,30 @@ This module fits at the end of the DIA pipeline for downstream statistical analy ## Inputs -| Channel | Type | Description | -|---------|------|-------------| +| Channel | Type | Description | +| ----------------- | ---- | ---------------------------------------------------- | | msstats_csv_input | path | MSstats-formatted CSV input file (`out_msstats.csv`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| msstats_csv | path | MSstats result CSV files (`*.csv`) | -| log | path | Log file (`*.log`) | -| versions | path | Software versions file (`versions.yml`) with r-base and bioconductor-msstats versions | +| Channel | Type | Description | +| ----------- | ---- | ------------------------------------------------------------------------------------- | +| msstats_csv | path | MSstats result CSV files (`*.csv`) | +| log | path | Log file (`*.log`) | +| versions | path | Software versions file (`versions.yml`) with r-base and bioconductor-msstats versions | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Passed as last positional argument to `msstats_plfq.R` | -| params.contrasts | - | Contrast definitions for statistical testing | -| params.ref_condition | - | Reference condition for contrasts | -| params.msstats_remove_one_feat_prot | - | Remove single-feature proteins | -| params.msstatslfq_removeFewMeasurements | - | Remove features with few measurements | -| params.msstatslfq_feature_subset_protein | - | Feature subset for protein quantification | -| params.msstatslfq_quant_summary_method | - | Quantification summary method | -| params.msstats_threshold | - | Significance threshold | +| Parameter | Default | Description | +| ---------------------------------------- | ------- | ------------------------------------------------------ | +| ext.args | '' | Passed as last positional argument to `msstats_plfq.R` | +| params.contrasts | - | Contrast definitions for statistical testing | +| params.ref_condition | - | Reference condition for contrasts | +| params.msstats_remove_one_feat_prot | - | Remove single-feature proteins | +| params.msstatslfq_removeFewMeasurements | - | Remove features with few measurements | +| params.msstatslfq_feature_subset_protein | - | Feature subset for protein quantification | +| params.msstatslfq_quant_summary_method | - | Quantification summary method | +| params.msstats_threshold | - | Significance threshold | ## Container diff --git a/docs/modules/mzml_indexing.md b/docs/modules/mzml_indexing.md index bd242443..b4069a00 100644 --- a/docs/modules/mzml_indexing.md +++ b/docs/modules/mzml_indexing.md @@ -10,24 +10,24 @@ This module is part of the file preparation stage in the pipeline. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (uses `meta.mzml_id` for tagging) | -| mzmlfile | path | Input mzML file (`*.mzML`) | +| Channel | Type | Description | +| -------- | -------- | ----------------------------------------------------- | +| meta | val(map) | Sample metadata map (uses `meta.mzml_id` for tagging) | +| mzmlfile | path | Input mzML file (`*.mzML`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| mzmls_indexed | tuple(val, path) | Indexed mzML file in `out/` directory | -| versions | path | FileConverter version (`versions.yml`) | -| log | path | Log file (`*.log`) | +| Channel | Type | Description | +| ------------- | ---------------- | -------------------------------------- | +| mzmls_indexed | tuple(val, path) | Indexed mzML file in `out/` directory | +| versions | path | FileConverter version (`versions.yml`) | +| log | path | Log file (`*.log`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to `FileConverter` command | +| Parameter | Default | Description | +| --------- | ------- | ------------------------------------------------------------ | +| ext.args | '' | Additional CLI arguments appended to `FileConverter` command | ## Container diff --git a/docs/modules/mzml_statistics.md b/docs/modules/mzml_statistics.md index 5fdfa72c..3a6bee1c 100644 --- a/docs/modules/mzml_statistics.md +++ b/docs/modules/mzml_statistics.md @@ -10,28 +10,28 @@ Behavior is controlled by `params.id_only` (skips MS2 stats when true) and `para ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | -| ms_file | path | Mass spectrometry file in mzML format (`*.mzML`) | +| Channel | Type | Description | +| ------- | -------- | ------------------------------------------------ | +| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | +| ms_file | path | Mass spectrometry file in mzML format (`*.mzML`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| ms_statistics | path | MS-level statistics (`*_ms_info.parquet`) | -| ms2_statistics | tuple(val, path) | MS2-level statistics (`*_ms2_info.parquet`, optional) | -| feature_statistics | path | Feature detection results (`*_feature_info.parquet`, optional) | -| versions | path | quantms-utils version (`versions.yml`) | -| log | path | Log file (`*.log`) | +| Channel | Type | Description | +| ------------------ | ---------------- | -------------------------------------------------------------- | +| ms_statistics | path | MS-level statistics (`*_ms_info.parquet`) | +| ms2_statistics | tuple(val, path) | MS2-level statistics (`*_ms2_info.parquet`, optional) | +| feature_statistics | path | Feature detection results (`*_feature_info.parquet`, optional) | +| versions | path | quantms-utils version (`versions.yml`) | +| log | path | Log file (`*.log`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to `quantmsutilsc mzmlstats` command | -| params.id_only | - | When true, skips MS2-level statistics (`--ms2_file` not added) | -| params.mzml_features | - | When true, enables feature detection (`--feature_detection` flag) | +| Parameter | Default | Description | +| -------------------- | ------- | ---------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to `quantmsutilsc mzmlstats` command | +| params.id_only | - | When true, skips MS2-level statistics (`--ms2_file` not added) | +| params.mzml_features | - | When true, enables feature detection (`--feature_detection` flag) | ## Container diff --git a/docs/modules/opair.md b/docs/modules/opair.md index 21c1997f..c25c4ead 100644 --- a/docs/modules/opair.md +++ b/docs/modules/opair.md @@ -10,30 +10,30 @@ O-Pair is part of the FragPipe glycoproteomics suite and runs as a .NET applicat ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| psm_file | path | PSM file from PHILOSOPHER_FILTER (`psm.tsv`) | -| mzml_files | path | Mass spectrometry data files (`*.mzML`, staged in `spectra/` directory) | -| config_cli | val(string) | O-Pair parameters as CLI string (e.g., `-b 20 -c 20 -n 3`) | -| glycan_db | path | Glycan database file for O-glycan matching | +| Channel | Type | Description | +| ---------- | ----------- | ----------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| psm_file | path | PSM file from PHILOSOPHER_FILTER (`psm.tsv`) | +| mzml_files | path | Mass spectrometry data files (`*.mzML`, staged in `spectra/` directory) | +| config_cli | val(string) | O-Pair parameters as CLI string (e.g., `-b 20 -c 20 -n 3`) | +| glycan_db | path | Glycan database file for O-glycan matching | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Results directory containing O-Pair output and logs | -| results | tuple(val, path) | O-Pair glycan identification results (`*_opair_results.tsv`, optional) | -| glycoforms | tuple(val, path) | Glycoform-level results (`*_opair_glycoforms.tsv`, optional) | -| versions_opair | tuple (topic: versions) | O-Pair version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ----------------- | ----------------------- | ---------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Results directory containing O-Pair output and logs | +| results | tuple(val, path) | O-Pair glycan identification results (`*_opair_results.tsv`, optional) | +| glycoforms | tuple(val, path) | Glycoform-level results (`*_opair_glycoforms.tsv`, optional) | +| versions_opair | tuple (topic: versions) | O-Pair version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to `dotnet CMD.dll` after positional arguments | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | -------------- | -------------------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to `dotnet CMD.dll` after positional arguments | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/openms_peak_picker.md b/docs/modules/openms_peak_picker.md index 91e90c9c..1607b420 100644 --- a/docs/modules/openms_peak_picker.md +++ b/docs/modules/openms_peak_picker.md @@ -10,27 +10,27 @@ This module supports in-memory or low-memory processing modes and configurable M ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | -| mzml_file | path | Input mzML file in profile mode (`*.mzML`) | +| Channel | Type | Description | +| --------- | -------- | ------------------------------------------ | +| meta | val(map) | Sample metadata map (uses `meta.mzml_id`) | +| mzml_file | path | Input mzML file in profile mode (`*.mzML`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| mzmls_picked | tuple(val, path) | Centroided mzML file (`*.mzML`) | -| versions | path | PeakPickerHiRes version (`versions.yml`) | -| log | path | Log file (`*.log`) | +| Channel | Type | Description | +| ------------ | ---------------- | ---------------------------------------- | +| mzmls_picked | tuple(val, path) | Centroided mzML file (`*.mzML`) | +| versions | path | PeakPickerHiRes version (`versions.yml`) | +| log | path | Log file (`*.log`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to `PeakPickerHiRes` command | -| params.peakpicking_inmemory | - | Processing mode: `inmemory` or `lowmemory` | -| params.peakpicking_ms_levels | - | MS levels for peak picking (sets `-algorithm:ms_levels`) | -| params.pp_debug | - | Debug level (sets `-debug`) | +| Parameter | Default | Description | +| ---------------------------- | ------- | -------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to `PeakPickerHiRes` command | +| params.peakpicking_inmemory | - | Processing mode: `inmemory` or `lowmemory` | +| params.peakpicking_ms_levels | - | MS levels for peak picking (sets `-algorithm:ms_levels`) | +| params.pp_debug | - | Debug level (sets `-debug`) | ## Container diff --git a/docs/modules/parse_fragpipe_workflow.md b/docs/modules/parse_fragpipe_workflow.md index 14926856..38986539 100644 --- a/docs/modules/parse_fragpipe_workflow.md +++ b/docs/modules/parse_fragpipe_workflow.md @@ -10,33 +10,33 @@ The JSON output includes run flags, args, and config_type for each tool, enablin ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata map | -| workflow_file | path | FragPipe `.workflow` file containing tool parameters | +| Channel | Type | Description | +| ------------- | -------- | ---------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata map | +| workflow_file | path | FragPipe `.workflow` file containing tool parameters | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| tool_configs_json | tuple(val, path) | JSON with all tool configs including run flags and arguments (`tool_configs.json`) | -| msfragger_config | tuple(val, path) | MSFragger params file (`configs/fragger.params`, optional) | -| ionquant_config | tuple(val, path) | IonQuant config (`configs/ionquant.config`, optional) | -| msbooster_config | tuple(val, path) | MSBooster params file (`configs/msbooster.config`, optional) | -| percolator_config | tuple(val, path) | Percolator CLI config (`configs/percolator.config`, optional) | -| phi_report_config | tuple(val, path) | Philosopher filter/report CLI config (`configs/phi-report.config`, optional) | -| peptideprophet_config | tuple(val, path) | PeptideProphet CLI config (`configs/peptide-prophet.config`, optional) | -| proteinprophet_config | tuple(val, path) | ProteinProphet CLI config (`configs/protein-prophet.config`, optional) | -| database_config | tuple(val, path) | Philosopher database CLI config (`configs/database.config`, optional) | -| tmtintegrator_config | tuple(val, path) | TMTIntegrator YAML config (`configs/tmtintegrator.yml`, optional) | -| all_configs | tuple(val, path) | Directory containing all generated config files (`configs/`) | -| versions_python | tuple (topic: versions) | Python version | +| Channel | Type | Description | +| --------------------- | ----------------------- | ---------------------------------------------------------------------------------- | +| tool_configs_json | tuple(val, path) | JSON with all tool configs including run flags and arguments (`tool_configs.json`) | +| msfragger_config | tuple(val, path) | MSFragger params file (`configs/fragger.params`, optional) | +| ionquant_config | tuple(val, path) | IonQuant config (`configs/ionquant.config`, optional) | +| msbooster_config | tuple(val, path) | MSBooster params file (`configs/msbooster.config`, optional) | +| percolator_config | tuple(val, path) | Percolator CLI config (`configs/percolator.config`, optional) | +| phi_report_config | tuple(val, path) | Philosopher filter/report CLI config (`configs/phi-report.config`, optional) | +| peptideprophet_config | tuple(val, path) | PeptideProphet CLI config (`configs/peptide-prophet.config`, optional) | +| proteinprophet_config | tuple(val, path) | ProteinProphet CLI config (`configs/protein-prophet.config`, optional) | +| database_config | tuple(val, path) | Philosopher database CLI config (`configs/database.config`, optional) | +| tmtintegrator_config | tuple(val, path) | TMTIntegrator YAML config (`configs/tmtintegrator.yml`, optional) | +| all_configs | tuple(val, path) | Directory containing all generated config files (`configs/`) | +| versions_python | tuple (topic: versions) | Python version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Passed to the legacy `parse_fragpipe_workflow.py --outdir configs` invocation | +| Parameter | Default | Description | +| --------- | ------- | ----------------------------------------------------------------------------- | +| ext.args | '' | Passed to the legacy `parse_fragpipe_workflow.py --outdir configs` invocation | ## Container diff --git a/docs/modules/percolator.md b/docs/modules/percolator.md index e6fce831..74758d11 100644 --- a/docs/modules/percolator.md +++ b/docs/modules/percolator.md @@ -10,34 +10,34 @@ It supports both PSM-level (`--only-psms`) and peptide-level output modes and au ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| pin_file | path | Percolator input (PIN) file from MSFragger/MSBooster (`*.pin`) | -| pepxml_files | path | PepXML files from MSFragger (for perc2pepxml conversion, `*.pepXML`) | -| mzml_file | path | Mass spectrometry data file (for perc2pepxml path, `*.mzML`) | +| Channel | Type | Description | +| -------------- | ----------- | ----------------------------------------------------------------------------------- | +| meta | val(map) | Sample metadata map | +| pin_file | path | Percolator input (PIN) file from MSFragger/MSBooster (`*.pin`) | +| pepxml_files | path | PepXML files from MSFragger (for perc2pepxml conversion, `*.pepXML`) | +| mzml_file | path | Mass spectrometry data file (for perc2pepxml path, `*.mzML`) | | percolator_cli | val(string) | CLI flags for Percolator (e.g., `--only-psms --no-terminate --post-processing-tdc`) | -| data_type | val(string) | `'DDA'` or `'DIA'` - affects pepXML output format | +| data_type | val(string) | `'DDA'` or `'DIA'` - affects pepXML output format | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Results directory containing all Percolator output files and logs | -| pepxml | tuple(val, path) | Converted pepXML results with probabilities (`interact-*.pep.xml`) | -| target_psms | tuple(val, path) | Target PSM results (`*_target_psms.tsv`) | -| decoy_psms | tuple(val, path) | Decoy PSM results (`*_decoy_psms.tsv`) | -| versions_percolator | tuple (topic: versions) | Percolator version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------- | ----------------------- | ------------------------------------------------------------------ | +| results_dir | tuple(val, path) | Results directory containing all Percolator output files and logs | +| pepxml | tuple(val, path) | Converted pepXML results with probabilities (`interact-*.pep.xml`) | +| target_psms | tuple(val, path) | Target PSM results (`*_target_psms.tsv`) | +| decoy_psms | tuple(val, path) | Decoy PSM results (`*_decoy_psms.tsv`) | +| versions_percolator | tuple (topic: versions) | Percolator version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to both Percolator and pepXML conversion commands | -| ext.min_prob | 0.5 | Minimum probability for pepXML conversion | -| ext.decoy_tag | (default) | Sets `--protein-decoy-pattern` for Percolator | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | -------------- | ----------------------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to both Percolator and pepXML conversion commands | +| ext.min_prob | 0.5 | Minimum probability for pepXML conversion | +| ext.decoy_tag | (default) | Sets `--protein-decoy-pattern` for Percolator | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_database.md b/docs/modules/philosopher_database.md index 01ea7892..6c946f3c 100644 --- a/docs/modules/philosopher_database.md +++ b/docs/modules/philosopher_database.md @@ -10,28 +10,28 @@ Go runtime tuning parameters (GOMEMLIMIT, GOGC, GOMAXPROCS) are set for optimal ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| fasta | path | Protein sequence database in FASTA format | +| Channel | Type | Description | +| ------- | -------- | ----------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| fasta | path | Protein sequence database in FASTA format | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| fasta | tuple(val, path) | `${prefix}_philosopher.fasta` database with decoys/contaminants added | -| log | tuple(val, path) | `philosopher_database.log` command log | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | --------------------------------------------------------------------- | +| fasta | tuple(val, path) | `${prefix}_philosopher.fasta` database with decoys/contaminants added | +| log | tuple(val, path) | `philosopher_database.log` command log | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `philosopher database --custom` (only when decoys not present) | -| ext.prefix | `${meta.id}` | Output file prefix | -| ext.decoy_tag | `rev_` | Decoy protein prefix used for detection and generation | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for Philosopher binary discovery | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for `philosopher database --custom` (only when decoys not present) | +| ext.prefix | `${meta.id}` | Output file prefix | +| ext.decoy_tag | `rev_` | Decoy protein prefix used for detection and generation | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for Philosopher binary discovery | ## Container diff --git a/docs/modules/philosopher_filter.md b/docs/modules/philosopher_filter.md index fe9dff3d..da3c8385 100644 --- a/docs/modules/philosopher_filter.md +++ b/docs/modules/philosopher_filter.md @@ -10,36 +10,36 @@ When `skip_report=true`, the `.meta/` workspace is preserved for downstream tool ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| pepxml_files | path | PepXML files from search/validation (`*.pep.xml`) | -| protxml | path | ProtXML from ProteinProphet (`*.prot.xml`) | -| filter_flags | val(string) | Filter CLI flags (e.g., `--sequential --razor --prot 0.01 --picked`) | -| report_flags | val(string) | Report CLI flags (e.g., `--msstats`) | -| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | +| Channel | Type | Description | +| ------------ | ----------- | ----------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| pepxml_files | path | PepXML files from search/validation (`*.pep.xml`) | +| protxml | path | ProtXML from ProteinProphet (`*.prot.xml`) | +| filter_flags | val(string) | Filter CLI flags (e.g., `--sequential --razor --prot 0.01 --picked`) | +| report_flags | val(string) | Report CLI flags (e.g., `--msstats`) | +| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing all result files | -| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results | -| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | -| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | -| ions | tuple(val, path) | `${prefix}/ion.tsv` ion-level results (optional) | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | -------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing all result files | +| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results | +| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | +| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | +| ions | tuple(val, path) | `${prefix}/ion.tsv` ion-level results (optional) | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `philosopher filter` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.decoy_tag | `rev_` | Decoy protein prefix | -| ext.skip_report | false | When true, preserve `.meta/` workspace for downstream FreeQuant/LabelQuant | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | -------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for `philosopher filter` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.decoy_tag | `rev_` | Decoy protein prefix | +| ext.skip_report | false | When true, preserve `.meta/` workspace for downstream FreeQuant/LabelQuant | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_labelquant.md b/docs/modules/philosopher_labelquant.md index e0f2c1ef..7459a6ed 100644 --- a/docs/modules/philosopher_labelquant.md +++ b/docs/modules/philosopher_labelquant.md @@ -10,29 +10,29 @@ The updated `.meta/` workspace is passed to downstream PHILOSOPHER_REPORT, which ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| results_dir | path | Directory with psm.tsv and `.meta/` workspace from PHILOSOPHER_FILTER or FREEQUANT | -| mzml_dir | path | Directory containing mzML files for the experiment/group | -| annot | path | TMT annotation file mapping channels to samples | -| config_cli | val(string) | Labelquant CLI flags (`--tol`, `--level`, `--plex`, `--brand`, `--minprob`, `--purity`, `--removelow`) | +| Channel | Type | Description | +| ----------- | ----------- | ------------------------------------------------------------------------------------------------------ | +| meta | val(map) | Sample/experiment metadata | +| results_dir | path | Directory with psm.tsv and `.meta/` workspace from PHILOSOPHER_FILTER or FREEQUANT | +| mzml_dir | path | Directory containing mzML files for the experiment/group | +| annot | path | TMT annotation file mapping channels to samples | +| config_cli | val(string) | Labelquant CLI flags (`--tol`, `--level`, `--plex`, `--brand`, `--minprob`, `--purity`, `--removelow`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` with updated `.meta/` containing TMT intensities | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | ----------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` with updated `.meta/` containing TMT intensities | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended after `config_cli` and `--annot`/`--dir` flags | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended after `config_cli` and `--annot`/`--dir` flags | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_peptideprophet.md b/docs/modules/philosopher_peptideprophet.md index 9bcca894..bb8a7339 100644 --- a/docs/modules/philosopher_peptideprophet.md +++ b/docs/modules/philosopher_peptideprophet.md @@ -10,31 +10,31 @@ This module parses a config file for `peptideprophet=` flags, initializes a Phil ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| pepxml | path | PepXML file from search engine (`*.pepXML`) | -| mzml | path | mzML spectral file (used for base_name normalization) | -| config_file | path | Config file with `peptideprophet=flags` line from PARSE_FRAGPIPE_WORKFLOW | -| fasta | path | Protein sequence database | +| Channel | Type | Description | +| ----------- | -------- | ------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| pepxml | path | PepXML file from search engine (`*.pepXML`) | +| mzml | path | mzML spectral file (used for base_name normalization) | +| config_file | path | Config file with `peptideprophet=flags` line from PARSE_FRAGPIPE_WORKFLOW | +| fasta | path | Protein sequence database | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` with PeptideProphet results and logs | -| pepxml | tuple(val, path) | `${prefix}/interact-*.pep.xml` PepXML with probabilities | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | ----------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` with PeptideProphet results and logs | +| pepxml | tuple(val, path) | `${prefix}/interact-*.pep.xml` PepXML with probabilities | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `philosopher peptideprophet` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.decoy_tag | `rev_` | Decoy protein prefix | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ------------------------------------------------------------------ | +| ext.args | '' | Additional command-line arguments for `philosopher peptideprophet` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.decoy_tag | `rev_` | Decoy protein prefix | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_pipeline.md b/docs/modules/philosopher_pipeline.md index 035746a7..f3590024 100644 --- a/docs/modules/philosopher_pipeline.md +++ b/docs/modules/philosopher_pipeline.md @@ -10,35 +10,35 @@ All generated TSV files are moved to the output directory. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| pepxml_files | path | PepXML files from search/validation (`*.pep.xml`) | -| protxml | path | ProtXML from ProteinProphet (`*.prot.xml`) | -| mzml_files | path | mzML spectral files | -| filter_flags | val(string) | Filter CLI flags (e.g., `--sequential --razor --prot 0.01 --picked`) | -| report_flags | val(string) | Report CLI flags (e.g., `--msstats`) | -| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | +| Channel | Type | Description | +| ------------ | ----------- | ----------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| pepxml_files | path | PepXML files from search/validation (`*.pep.xml`) | +| protxml | path | ProtXML from ProteinProphet (`*.prot.xml`) | +| mzml_files | path | mzML spectral files | +| filter_flags | val(string) | Filter CLI flags (e.g., `--sequential --razor --prot 0.01 --picked`) | +| report_flags | val(string) | Report CLI flags (e.g., `--msstats`) | +| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing all result files | -| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | -| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | -| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | -------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing all result files | +| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | +| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | +| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `philosopher filter` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.decoy_tag | `rev_` | Decoy protein prefix | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ---------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for `philosopher filter` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.decoy_tag | `rev_` | Decoy protein prefix | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_proteinprophet.md b/docs/modules/philosopher_proteinprophet.md index 95b6a59e..7145d062 100644 --- a/docs/modules/philosopher_proteinprophet.md +++ b/docs/modules/philosopher_proteinprophet.md @@ -10,29 +10,29 @@ It produces `combined.prot.xml` and passes through the input pepXML files for do ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| pepxml_files | path | PepXML files from Percolator or PeptideProphet (`*.pep.xml`) | -| config_cli | val(string) | ProteinProphet CLI options (e.g., `--maxppmdiff 2000000`) | +| Channel | Type | Description | +| ------------ | ----------- | ------------------------------------------------------------ | +| meta | val(map) | Sample/experiment metadata | +| pepxml_files | path | PepXML files from Percolator or PeptideProphet (`*.pep.xml`) | +| config_cli | val(string) | ProteinProphet CLI options (e.g., `--maxppmdiff 2000000`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` with ProteinProphet results and logs | -| protxml | tuple(val, path) | `${prefix}/combined.prot.xml` protein inference results | -| pepxml | tuple(val, path) | Pass-through of input pepXML files for downstream synchronization | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | ----------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` with ProteinProphet results and logs | +| protxml | tuple(val, path) | `${prefix}/combined.prot.xml` protein inference results | +| pepxml | tuple(val, path) | Pass-through of input pepXML files for downstream synchronization | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended after `config_cli` and `--output combined` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended after `config_cli` and `--output combined` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/philosopher_report.md b/docs/modules/philosopher_report.md index 35822691..f1c08bc9 100644 --- a/docs/modules/philosopher_report.md +++ b/docs/modules/philosopher_report.md @@ -10,33 +10,33 @@ The module re-initializes the workspace and re-annotates the database to ensure ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| results_dir | path | Directory containing `.meta/` workspace binaries from PHILOSOPHER_FILTER/FREEQUANT/LABELQUANT | -| report_cli | val(string) | Report CLI flags (e.g., `--msstats`) | -| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | +| Channel | Type | Description | +| ----------- | ----------- | --------------------------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| results_dir | path | Directory containing `.meta/` workspace binaries from PHILOSOPHER_FILTER/FREEQUANT/LABELQUANT | +| report_cli | val(string) | Report CLI flags (e.g., `--msstats`) | +| fasta | path | Philosopher database with decoys/contaminants from PHILOSOPHER_DATABASE | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing all TSV files | -| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results with quantification intensities | -| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | -| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | -| ions | tuple(val, path) | `${prefix}/ion.tsv` ion-level results (optional) | -| versions_philosopher | topic: versions | Philosopher version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| -------------------- | ---------------- | --------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing all TSV files | +| psms | tuple(val, path) | `${prefix}/psm.tsv` PSM-level results with quantification intensities | +| peptides | tuple(val, path) | `${prefix}/peptide.tsv` peptide-level results | +| proteins | tuple(val, path) | `${prefix}/protein.tsv` protein-level results | +| ions | tuple(val, path) | `${prefix}/ion.tsv` ion-level results (optional) | +| versions_philosopher | topic: versions | Philosopher version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `philosopher report` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.decoy_tag | `rev_` | Decoy protein prefix | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ---------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for `philosopher report` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.decoy_tag | `rev_` | Decoy protein prefix | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory | ## Container diff --git a/docs/modules/pmultiqc.md b/docs/modules/pmultiqc.md index 8d3586a5..2f067e0d 100644 --- a/docs/modules/pmultiqc.md +++ b/docs/modules/pmultiqc.md @@ -10,30 +10,30 @@ This module aggregates results from upstream pipeline stages into a comprehensiv ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| results | path | All result files staged into `results/` directory | -| quantms_log | path | quantms log file | +| Channel | Type | Description | +| ----------- | ---- | ------------------------------------------------- | +| results | path | All result files staged into `results/` directory | +| quantms_log | path | quantms log file | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| ch_pmultiqc_report | path | MultiQC HTML report (`*.html`) | -| ch_pmultiqc_db | path | SQLite3 database with protein, PSM, and quantification data (`*.db`, optional) | -| versions | path | pmultiqc version (`versions.yml`) | -| data | path | MultiQC data directory (`*_data`) | +| Channel | Type | Description | +| ------------------ | ---- | ------------------------------------------------------------------------------ | +| ch_pmultiqc_report | path | MultiQC HTML report (`*.html`) | +| ch_pmultiqc_db | path | SQLite3 database with protein, PSM, and quantification data (`*.db`, optional) | +| versions | path | pmultiqc version (`versions.yml`) | +| data | path | MultiQC data directory (`*_data`) | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments passed to the `multiqc` command | -| params.enable_pmultiqc | - | Combined with `params.export_mztab` to control `--quantms_plugin` | -| params.skip_table_plots | - | Controls `--disable_table` flag | -| params.pmultiqc_idxml_skip | - | Controls `--ignored_idxml` flag | -| params.contaminant_string | - | Sets `--contaminant_affix` for contaminant filtering | -| params.quantification_method | - | Sets `--quantification_method` for report generation | +| Parameter | Default | Description | +| ---------------------------- | ------- | ----------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments passed to the `multiqc` command | +| params.enable_pmultiqc | - | Combined with `params.export_mztab` to control `--quantms_plugin` | +| params.skip_table_plots | - | Controls `--disable_table` flag | +| params.pmultiqc_idxml_skip | - | Controls `--ignored_idxml` flag | +| params.contaminant_string | - | Sets `--contaminant_affix` for contaminant filtering | +| params.quantification_method | - | Sets `--quantification_method` for report generation | ## Container diff --git a/docs/modules/preprocess_expdesign.md b/docs/modules/preprocess_expdesign.md index fe62bd64..149d25e8 100644 --- a/docs/modules/preprocess_expdesign.md +++ b/docs/modules/preprocess_expdesign.md @@ -10,17 +10,17 @@ It uses simple `sed`/`grep` commands with the quantms-utils container for enviro ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| design | path | Experimental design file in TSV format (`*.tsv` or `*.txt`) | +| Channel | Type | Description | +| ------- | ---- | ----------------------------------------------------------- | +| design | path | Experimental design file in TSV format (`*.tsv` or `*.txt`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| +| Channel | Type | Description | +| ------------ | ---- | ------------------------------------------------------------------- | | ch_expdesign | path | Design file with `.raw` replaced by `.mzML` (`*_openms_design.tsv`) | -| ch_config | path | Extracted configuration TSV (`*_config.tsv`) | -| versions | path | sdrf-pipelines version (`versions.yml`) | +| ch_config | path | Extracted configuration TSV (`*_config.tsv`) | +| versions | path | sdrf-pipelines version (`versions.yml`) | ## Parameters diff --git a/docs/modules/ptmprophet.md b/docs/modules/ptmprophet.md index 5393415b..8dd15f73 100644 --- a/docs/modules/ptmprophet.md +++ b/docs/modules/ptmprophet.md @@ -10,28 +10,28 @@ The module always uses `MAXTHREADS=1` (matching FragPipe convention, since Nextf ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| pepxml_file | path | PepXML file containing peptide search results with PTMs (`*.pep.xml`) | -| config_cli | val(string) | PTMProphet parameters as CLI string (UPPERCASE=value format, e.g., `MINPROB=0.5 STATIC KEEPOLD`) | +| Channel | Type | Description | +| ----------- | ----------- | ------------------------------------------------------------------------------------------------ | +| meta | val(map) | Sample metadata map | +| pepxml_file | path | PepXML file containing peptide search results with PTMs (`*.pep.xml`) | +| config_cli | val(string) | PTMProphet parameters as CLI string (UPPERCASE=value format, e.g., `MINPROB=0.5 STATIC KEEPOLD`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Results directory containing PTMProphet output and logs | -| mod_pepxml | tuple(val, path) | Modified pepXML with PTM site localization probabilities (`*.mod.pep.xml`) | -| versions_ptmprophet | tuple (topic: versions) | PTMProphet version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| ------------------- | ----------------------- | -------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Results directory containing PTMProphet output and logs | +| mod_pepxml | tuple(val, path) | Modified pepXML with PTM site localization probabilities (`*.mod.pep.xml`) | +| versions_ptmprophet | tuple (topic: versions) | PTMProphet version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Inserted into PTMProphet command after `config_cli` and before input/output files | -| ext.decoy_tag | 'rev_' | Decoy prefix for decoy protein identification | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | -------------- | --------------------------------------------------------------------------------- | +| ext.args | '' | Inserted into PTMProphet command after `config_cli` and before input/output files | +| ext.decoy_tag | 'rev\_' | Decoy prefix for decoy protein identification | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/ptmshepherd.md b/docs/modules/ptmshepherd.md index 1d563eb1..38365117 100644 --- a/docs/modules/ptmshepherd.md +++ b/docs/modules/ptmshepherd.md @@ -10,34 +10,34 @@ PTM-Shepherd is part of the FragPipe suite and uses multiple JAR dependencies in ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata map | -| psm_dirs | path | Directories containing `psm.tsv` files from PHILOSOPHER_FILTER | -| protxml | path | Combined protein inference file from PROTEINPROPHET (`*.prot.xml`) | -| mzml_files | path | Mass spectrometry files (`*.mzML`, staged in `spectra/` directory) | -| config_file | path | PTM-Shepherd configuration file (`shepherd.config`) | -| fasta | path | Protein database FASTA (shared resource) | +| Channel | Type | Description | +| ----------- | -------- | ------------------------------------------------------------------ | +| meta | val(map) | Sample metadata map | +| psm_dirs | path | Directories containing `psm.tsv` files from PHILOSOPHER_FILTER | +| protxml | path | Combined protein inference file from PROTEINPROPHET (`*.prot.xml`) | +| mzml_files | path | Mass spectrometry files (`*.mzML`, staged in `spectra/` directory) | +| config_file | path | PTM-Shepherd configuration file (`shepherd.config`) | +| fasta | path | Protein database FASTA (shared resource) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Results directory containing all PTM-Shepherd output | -| global_profile | tuple(val, path) | Global mass shift profile across all samples (`global.profile.tsv`, optional) | -| global_modsummary | tuple(val, path) | Global modification summary with annotations (`global.modsummary.tsv`, optional) | -| diagmine | tuple(val, path) | Diagnostic ion mining results (`*diagmine.tsv`, optional) | -| localization | tuple(val, path) | PTM site localization results (`*localization.tsv`, optional) | -| glycoprofile | tuple(val, path) | Glycoproteomics profile results (`*glycoprofile.tsv`, optional) | -| versions_ptmshepherd | tuple (topic: versions) | PTM-Shepherd version | -| versions_fragpipe | tuple (topic: versions) | FragPipe version | +| Channel | Type | Description | +| -------------------- | ----------------------- | -------------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Results directory containing all PTM-Shepherd output | +| global_profile | tuple(val, path) | Global mass shift profile across all samples (`global.profile.tsv`, optional) | +| global_modsummary | tuple(val, path) | Global modification summary with annotations (`global.modsummary.tsv`, optional) | +| diagmine | tuple(val, path) | Diagnostic ion mining results (`*diagmine.tsv`, optional) | +| localization | tuple(val, path) | PTM site localization results (`*localization.tsv`, optional) | +| glycoprofile | tuple(val, path) | Glycoproteomics profile results (`*glycoprofile.tsv`, optional) | +| versions_ptmshepherd | tuple (topic: versions) | PTM-Shepherd version | +| versions_fragpipe | tuple (topic: versions) | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional CLI arguments appended to PTM-Shepherd Java command after config file path | -| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | +| Parameter | Default | Description | +| ---------------------- | -------------- | ------------------------------------------------------------------------------------- | +| ext.args | '' | Additional CLI arguments appended to PTM-Shepherd Java command after config file path | +| ext.fragpipe_tools_dir | (default path) | Override FragPipe tools directory | ## Container diff --git a/docs/modules/saintexpress.md b/docs/modules/saintexpress.md index 864d77c8..2fdba914 100644 --- a/docs/modules/saintexpress.md +++ b/docs/modules/saintexpress.md @@ -10,31 +10,31 @@ This module discovers the SAINTexpress binary from the FragPipe tools directory ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| inter_file | path | Interaction file containing prey-bait spectral counts or intensities (`inter.dat`) | -| bait_file | path | Bait definition file mapping samples to baits and controls (`bait.dat`) | -| prey_file | path | Prey definition file with protein lengths (`prey.dat`) | -| mode | val(string) | Scoring mode: `"spc"` for spectral count or `"int"` for intensity | -| config_cli | val(string) | SAINTexpress parameters as CLI string (e.g., `-R 2 -L 4`) | +| Channel | Type | Description | +| ---------- | ----------- | ---------------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| inter_file | path | Interaction file containing prey-bait spectral counts or intensities (`inter.dat`) | +| bait_file | path | Bait definition file mapping samples to baits and controls (`bait.dat`) | +| prey_file | path | Prey definition file with protein lengths (`prey.dat`) | +| mode | val(string) | Scoring mode: `"spc"` for spectral count or `"int"` for intensity | +| config_cli | val(string) | SAINTexpress parameters as CLI string (e.g., `-R 2 -L 4`) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing SAINTexpress results and log files | -| results_list | tuple(val, path) | `${prefix}/list.txt` with interaction scores | -| versions_saintexpress | topic: versions | SAINTexpress version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| --------------------- | ---------------- | -------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing SAINTexpress results and log files | +| results_list | tuple(val, path) | `${prefix}/list.txt` with interaction scores | +| versions_saintexpress | topic: versions | SAINTexpress version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended after `config_cli` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for binary discovery | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended after `config_cli` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for binary discovery | ## Container diff --git a/docs/modules/samplesheet_check.md b/docs/modules/samplesheet_check.md index a83ee9fb..5ea6ed8b 100644 --- a/docs/modules/samplesheet_check.md +++ b/docs/modules/samplesheet_check.md @@ -10,29 +10,29 @@ The validated file is passed through to downstream processes. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| input_file | path | Samplesheet or SDRF file (`*.tsv`, `*.txt`, `*.csv`) | -| is_sdrf | val(boolean) | Whether the input file is in SDRF format | +| Channel | Type | Description | +| ------------------- | ------------ | ------------------------------------------------------------ | +| input_file | path | Samplesheet or SDRF file (`*.tsv`, `*.txt`, `*.csv`) | +| is_sdrf | val(boolean) | Whether the input file is in SDRF format | | validate_ontologies | val(boolean) | Whether to validate ontologies (false skips SDRF validation) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| log | path | `*.log` validation log | +| Channel | Type | Description | +| ------------ | ---- | ---------------------------------------- | +| log | path | `*.log` validation log | | checked_file | path | Pass-through of the validated input file | -| versions | path | `versions.yml` with software versions | +| versions | path | `versions.yml` with software versions | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for `quantmsutilsc checksamplesheet` | -| params.skip_ms_validation | false | Skip mass spectrometry validation | -| params.skip_factor_validation | false | Skip factor validation | -| params.skip_experimental_design_validation | false | Skip experimental design validation | -| params.use_ols_cache_only | false | Use OLS cache only for ontology lookups | +| Parameter | Default | Description | +| ------------------------------------------ | ------- | ---------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for `quantmsutilsc checksamplesheet` | +| params.skip_ms_validation | false | Skip mass spectrometry validation | +| params.skip_factor_validation | false | Skip factor validation | +| params.skip_experimental_design_validation | false | Skip experimental design validation | +| params.use_ols_cache_only | false | Use OLS cache only for ontology lookups | ## Container diff --git a/docs/modules/sdrf_parsing.md b/docs/modules/sdrf_parsing.md index 70ac91f8..d20cb617 100644 --- a/docs/modules/sdrf_parsing.md +++ b/docs/modules/sdrf_parsing.md @@ -10,25 +10,25 @@ When `params.convert_dotd` is enabled, it handles `.d` format extension conversi ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| sdrf | path | A valid SDRF file | +| Channel | Type | Description | +| ------- | ---- | ----------------- | +| sdrf | path | A valid SDRF file | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| ch_expdesign | path | `${sdrf.baseName}_openms_design.tsv` experimental design file in OpenMS format | -| ch_sdrf_config_file | path | `${sdrf.baseName}_config.tsv` config file with search engine parameters | -| log | path | `*.log` parsing log | -| versions | path | `versions.yml` with software versions | +| Channel | Type | Description | +| ------------------- | ---- | ------------------------------------------------------------------------------ | +| ch_expdesign | path | `${sdrf.baseName}_openms_design.tsv` experimental design file in OpenMS format | +| ch_sdrf_config_file | path | `${sdrf.baseName}_config.tsv` config file with search engine parameters | +| log | path | `*.log` parsing log | +| versions | path | `versions.yml` with software versions | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended to `parse_sdrf convert-openms` | -| params.convert_dotd | false | Enable `.d` format extension conversions to mzML | +| Parameter | Default | Description | +| ------------------- | ------- | ------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended to `parse_sdrf convert-openms` | +| params.convert_dotd | false | Enable `.d` format extension conversions to mzML | ## Container diff --git a/docs/modules/skyline.md b/docs/modules/skyline.md index f88c1f2a..582675e8 100644 --- a/docs/modules/skyline.md +++ b/docs/modules/skyline.md @@ -10,32 +10,32 @@ Memory is auto-calculated from `task.memory`. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| results_dir | path | FragPipe output directory containing psm.tsv and library files | -| mzml_files | path (stageAs `spectra/*`) | Mass spectrometry files for import (`*.mzML`, `*.mzXML`) | -| speclib | path | Spectral library file (`*.speclib`, `*.sptxt`, `*.blib`) | -| config_cli | val(string) | Skyline parameters as CLI string (modsMode, tolerances, etc.) | -| skyline_path | val(string) | Path to Skyline executable (shared resource) | +| Channel | Type | Description | +| ------------ | -------------------------- | -------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| results_dir | path | FragPipe output directory containing psm.tsv and library files | +| mzml_files | path (stageAs `spectra/*`) | Mass spectrometry files for import (`*.mzML`, `*.mzXML`) | +| speclib | path | Spectral library file (`*.speclib`, `*.sptxt`, `*.blib`) | +| config_cli | val(string) | Skyline parameters as CLI string (modsMode, tolerances, etc.) | +| skyline_path | val(string) | Path to Skyline executable (shared resource) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing Skyline output files | -| skyline_document | tuple(val, path) | `${prefix}/skyline_files/fragpipe.sky` Skyline document (optional) | -| reports | tuple(val, path) | `${prefix}/*.csv` quantification report files (optional) | -| versions_skyline | topic: versions | Skyline version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| ----------------- | ---------------- | ------------------------------------------------------------------ | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing Skyline output files | +| skyline_document | tuple(val, path) | `${prefix}/skyline_files/fragpipe.sky` Skyline document (optional) | +| reports | tuple(val, path) | `${prefix}/*.csv` quantification report files (optional) | +| versions_skyline | topic: versions | Skyline version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for the Skyline Java wrapper | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for JAR discovery | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | -------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for the Skyline Java wrapper | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for JAR discovery | ## Container diff --git a/docs/modules/speclibgen.md b/docs/modules/speclibgen.md index 295deb21..9aa78b5d 100644 --- a/docs/modules/speclibgen.md +++ b/docs/modules/speclibgen.md @@ -10,34 +10,34 @@ Output formats include TSV, Spectronaut (`.speclib`), and Parquet, with automati ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| psm_files | path (stageAs `psms/sample_*`) | Per-sample psm.tsv files from PHILOSOPHER_FILTER | -| peptide_files | path (stageAs `peps/sample_*`) | Per-sample peptide.tsv files from PHILOSOPHER_FILTER | -| mzml_files | path (stageAs `spectra/*`) | Mass spec files for spectrum extraction | -| config_cli | val(string) | Bash-sourceable KEY='value' lines (CONVERT_ARGS, FRAGMENT_TYPES, LIBRARY_ARGS, RT_CAL, IM_CAL, KEEP_INTERMEDIATE) | -| fasta | path | Protein sequence database | +| Channel | Type | Description | +| ------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| psm_files | path (stageAs `psms/sample_*`) | Per-sample psm.tsv files from PHILOSOPHER_FILTER | +| peptide_files | path (stageAs `peps/sample_*`) | Per-sample peptide.tsv files from PHILOSOPHER_FILTER | +| mzml_files | path (stageAs `spectra/*`) | Mass spec files for spectrum extraction | +| config_cli | val(string) | Bash-sourceable KEY='value' lines (CONVERT_ARGS, FRAGMENT_TYPES, LIBRARY_ARGS, RT_CAL, IM_CAL, KEEP_INTERMEDIATE) | +| fasta | path | Protein sequence database | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing all spectral library files | -| library_tsv | tuple(val, path) | `${prefix}/library.tsv` spectral library in TSV format (optional) | -| library_speclib | tuple(val, path) | `${prefix}/library.speclib` in speclib binary format (optional) | -| library_parquet | tuple(val, path) | `${prefix}/library.parquet` in Parquet columnar format (optional) | -| versions_speclibgen | topic: versions | SpecLibGen version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| ------------------- | ---------------- | ------------------------------------------------------------------ | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing all spectral library files | +| library_tsv | tuple(val, path) | `${prefix}/library.tsv` spectral library in TSV format (optional) | +| library_speclib | tuple(val, path) | `${prefix}/library.speclib` in speclib binary format (optional) | +| library_parquet | tuple(val, path) | `${prefix}/library.parquet` in Parquet columnar format (optional) | +| versions_speclibgen | topic: versions | SpecLibGen version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended to EasyPQP commands | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for binary discovery | -| ext.decoy_tag | `rev_` | Decoy protein prefix | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | -------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended to EasyPQP commands | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for binary discovery | +| ext.decoy_tag | `rev_` | Decoy protein prefix | ## Container diff --git a/docs/modules/split_fasta.md b/docs/modules/split_fasta.md index 9a5987c3..b35a1377 100644 --- a/docs/modules/split_fasta.md +++ b/docs/modules/split_fasta.md @@ -10,25 +10,25 @@ Each chunk is written to a numbered subdirectory under `split_db/`. ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| fasta | path | Protein sequence database in FASTA format | -| num_chunks | val(integer) | Number of chunks to split into (>= 1) | +| Channel | Type | Description | +| ---------- | ------------ | ----------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| fasta | path | Protein sequence database in FASTA format | +| num_chunks | val(integer) | Number of chunks to split into (>= 1) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| fasta_chunks | tuple(val, path) | `split_db/*/*.fasta` chunk files in numbered subdirectories | -| versions_python | topic: versions | Python version | +| Channel | Type | Description | +| --------------- | ---------------- | ----------------------------------------------------------- | +| fasta_chunks | tuple(val, path) | `split_db/*/*.fasta` chunk files in numbered subdirectories | +| versions_python | topic: versions | Python version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional arguments (not directly used by the bin script) | -| ext.prefix | `${meta.id}` | Prefix for naming | +| Parameter | Default | Description | +| ---------- | ------------ | ---------------------------------------------------------- | +| ext.args | '' | Additional arguments (not directly used by the bin script) | +| ext.prefix | `${meta.id}` | Prefix for naming | ## Container diff --git a/docs/modules/tdf2mzml.md b/docs/modules/tdf2mzml.md index ac9ff80d..be304052 100644 --- a/docs/modules/tdf2mzml.md +++ b/docs/modules/tdf2mzml.md @@ -10,25 +10,25 @@ The original `.d` directory is preserved and emitted as an output alongside the ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata (uses `meta.mzml_id` for tag) | -| rawfile | path | Bruker `.d` raw file | +| Channel | Type | Description | +| ------- | -------- | --------------------------------------------- | +| meta | val(map) | Sample metadata (uses `meta.mzml_id` for tag) | +| rawfile | path | Bruker `.d` raw file | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| mzmls_converted | tuple(val, path) | `*.mzML` converted file | -| dotd_files | tuple(val, path) | `*.d` original file (preserved and renamed) | -| versions | path | `versions.yml` with software versions | -| log | path | `*.log` conversion log | +| Channel | Type | Description | +| --------------- | ---------------- | ------------------------------------------- | +| mzmls_converted | tuple(val, path) | `*.mzML` converted file | +| dotd_files | tuple(val, path) | `*.d` original file (preserved and renamed) | +| versions | path | `versions.yml` with software versions | +| log | path | `*.log` conversion log | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended to `tdf2mzml.py -i` | +| Parameter | Default | Description | +| --------- | ------- | -------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended to `tdf2mzml.py -i` | ## Container diff --git a/docs/modules/thermorawfileparser.md b/docs/modules/thermorawfileparser.md index a1e87ec6..89d04f3f 100644 --- a/docs/modules/thermorawfileparser.md +++ b/docs/modules/thermorawfileparser.md @@ -10,25 +10,25 @@ The output format is determined by `ext.args` flags (`--format 0`=mgf, `1`/`2`=m ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample metadata | -| raw | path | Thermo `.raw` file | +| Channel | Type | Description | +| ------- | -------- | ------------------ | +| meta | val(map) | Sample metadata | +| raw | path | Thermo `.raw` file | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| spectra | tuple(val, path) | Converted spectra file (`*.mzML`, `*.mzML.gz`, `*.mgf`, `*.mgf.gz`, `*.parquet`, `*.parquet.gz`) | -| versions | path | `versions.yml` with software versions | -| versions_thermorawfileparser | topic: versions | ThermoRawFileParser version | +| Channel | Type | Description | +| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------------------ | +| spectra | tuple(val, path) | Converted spectra file (`*.mzML`, `*.mzML.gz`, `*.mgf`, `*.mgf.gz`, `*.parquet`, `*.parquet.gz`) | +| versions | path | `versions.yml` with software versions | +| versions_thermorawfileparser | topic: versions | ThermoRawFileParser version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Command-line arguments for ThermoRawFileParser (controls format and compression) | -| ext.prefix | `${meta.id}` | Output file prefix | +| Parameter | Default | Description | +| ---------- | ------------ | -------------------------------------------------------------------------------- | +| ext.args | '' | Command-line arguments for ThermoRawFileParser (controls format and compression) | +| ext.prefix | `${meta.id}` | Output file prefix | ## Container diff --git a/docs/modules/tmtintegrator.md b/docs/modules/tmtintegrator.md index 4df040f6..033ac717 100644 --- a/docs/modules/tmtintegrator.md +++ b/docs/modules/tmtintegrator.md @@ -10,32 +10,32 @@ The module generates abundance and ratio tables and handles annotation format co ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| psm_dirs | path (stageAs `input_results/*`) | Per-sample directories containing psm.tsv and protein.tsv from PHILOSOPHER_FILTER | -| annotation_files | path | TMT annotation file (2-column IonQuant format or 6-column TMTIntegrator format) | -| config_file | path | TMT-Integrator YAML configuration file (ref_tag, min_pep_prob, prot_norm, groupby, etc.) | +| Channel | Type | Description | +| ---------------- | -------------------------------- | ---------------------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| psm_dirs | path (stageAs `input_results/*`) | Per-sample directories containing psm.tsv and protein.tsv from PHILOSOPHER_FILTER | +| annotation_files | path | TMT annotation file (2-column IonQuant format or 6-column TMTIntegrator format) | +| config_file | path | TMT-Integrator YAML configuration file (ref_tag, min_pep_prob, prot_norm, groupby, etc.) | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| results_dir | tuple(val, path) | Output directory `${prefix}` containing all TMT-Integrator results | -| abundance | tuple(val, path) | `${prefix}/abundance_*.tsv` abundance tables at various levels (optional) | -| ratio | tuple(val, path) | `${prefix}/ratio_*.tsv` ratio tables with log2 fold changes (optional) | -| proteins_txt | tuple(val, path) | `${prefix}/*_Proteins.txt` protein-level summary (optional) | -| peptides_txt | tuple(val, path) | `${prefix}/*_Peptides.txt` peptide-level summary (optional) | -| versions_tmtintegrator | topic: versions | TMT-Integrator version | -| versions_fragpipe | topic: versions | FragPipe version | +| Channel | Type | Description | +| ---------------------- | ---------------- | ------------------------------------------------------------------------- | +| results_dir | tuple(val, path) | Output directory `${prefix}` containing all TMT-Integrator results | +| abundance | tuple(val, path) | `${prefix}/abundance_*.tsv` abundance tables at various levels (optional) | +| ratio | tuple(val, path) | `${prefix}/ratio_*.tsv` ratio tables with log2 fold changes (optional) | +| proteins_txt | tuple(val, path) | `${prefix}/*_Proteins.txt` protein-level summary (optional) | +| peptides_txt | tuple(val, path) | `${prefix}/*_Peptides.txt` peptide-level summary (optional) | +| versions_tmtintegrator | topic: versions | TMT-Integrator version | +| versions_fragpipe | topic: versions | FragPipe version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments appended to `java -jar TMT-Integrator.jar` | -| ext.prefix | `${meta.id}` | Output directory name | -| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for JAR discovery | +| Parameter | Default | Description | +| ---------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------- | +| ext.args | '' | Additional command-line arguments appended to `java -jar TMT-Integrator.jar` | +| ext.prefix | `${meta.id}` | Output directory name | +| ext.fragpipe_tools_dir | `/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools` | FragPipe tools directory for JAR discovery | ## Container diff --git a/docs/modules/tmtlabelcheck.md b/docs/modules/tmtlabelcheck.md index f47f1797..49dedcee 100644 --- a/docs/modules/tmtlabelcheck.md +++ b/docs/modules/tmtlabelcheck.md @@ -11,31 +11,31 @@ Generates QC reports in HTML, Markdown, and TSV formats with pass/warn/fail thre ## Inputs -| Channel | Type | Description | -|---------|------|-------------| -| meta | val(map) | Sample/experiment metadata | -| input_files | path | Per-sample result directories (psm mode) or combined_modified_peptide.tsv (ionquant mode) | -| tmt_type | val(string) | TMT reagent type (TMT0, TMT2, TMT6, TMT10, TMT11, TMT16, TMT18, TMT35, TMTPRO) | -| mode | val(string) | `'psm'` for per-sample PSM files, `'ionquant'` for combined_modified_peptide.tsv | +| Channel | Type | Description | +| ----------- | ----------- | ----------------------------------------------------------------------------------------- | +| meta | val(map) | Sample/experiment metadata | +| input_files | path | Per-sample result directories (psm mode) or combined_modified_peptide.tsv (ionquant mode) | +| tmt_type | val(string) | TMT reagent type (TMT0, TMT2, TMT6, TMT10, TMT11, TMT16, TMT18, TMT35, TMTPRO) | +| mode | val(string) | `'psm'` for per-sample PSM files, `'ionquant'` for combined_modified_peptide.tsv | ## Outputs -| Channel | Type | Description | -|---------|------|-------------| -| html_report | tuple(val, path) | `report.html` rich HTML report with color-coded labeling status | -| md_report | tuple(val, path) | `report.md` Markdown report for documentation | -| summary | tuple(val, path) | `labeling_summary.tsv` machine-readable summary | -| per_sample | tuple(val, path) | `per_sample_efficiency.csv` per-sample efficiency data | -| versions_python | topic: versions | Python version | +| Channel | Type | Description | +| --------------- | ---------------- | --------------------------------------------------------------- | +| html_report | tuple(val, path) | `report.html` rich HTML report with color-coded labeling status | +| md_report | tuple(val, path) | `report.md` Markdown report for documentation | +| summary | tuple(val, path) | `labeling_summary.tsv` machine-readable summary | +| per_sample | tuple(val, path) | `per_sample_efficiency.csv` per-sample efficiency data | +| versions_python | topic: versions | Python version | ## Parameters -| Parameter | Default | Description | -|-----------|---------|-------------| -| ext.args | '' | Additional command-line arguments for tmt_qc scripts | -| ext.pass_threshold | 0.95 | Labeling efficiency pass threshold | -| ext.warn_threshold | 0.85 | Labeling efficiency warning threshold | -| ext.prob_threshold | 0.95 | PSM probability threshold for filtering | +| Parameter | Default | Description | +| ------------------ | ------- | ---------------------------------------------------- | +| ext.args | '' | Additional command-line arguments for tmt_qc scripts | +| ext.pass_threshold | 0.95 | Labeling efficiency pass threshold | +| ext.warn_threshold | 0.85 | Labeling efficiency warning threshold | +| ext.prob_threshold | 0.95 | PSM probability threshold for filtering | ## Container diff --git a/modules.json b/modules.json index d3ed0efb..02b9949f 100644 --- a/modules.json +++ b/modules.json @@ -8,52 +8,38 @@ "diann": { "branch": "master", "git_sha": "c246b66faacda1eeff12cc46b0944b8fc466179c", - "installed_by": [ - "dia_proteomics_analysis" - ], + "installed_by": ["dia_proteomics_analysis"], "patch": "modules/nf-core/diann/diann.diff" }, "fastqc": { "branch": "master", "git_sha": "4f6c351f7bbc62173b30f5a430e21ec907720676", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "multiqc": { "branch": "master", "git_sha": "cb9f4bec379866ca560f7f79d9a9a06bea8c9b51", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "quantmsutils/diann2mztab": { "branch": "master", "git_sha": "c246b66faacda1eeff12cc46b0944b8fc466179c", - "installed_by": [ - "dia_proteomics_analysis" - ] + "installed_by": ["dia_proteomics_analysis"] }, "quantmsutils/dianncfg": { "branch": "master", "git_sha": "c3ef6747c66c2d6217d067fd2dfb3412ff46bc3e", - "installed_by": [ - "dia_proteomics_analysis" - ] + "installed_by": ["dia_proteomics_analysis"] }, "quantmsutils/mzmlstatistics": { "branch": "master", "git_sha": "c3ef6747c66c2d6217d067fd2dfb3412ff46bc3e", - "installed_by": [ - "dia_proteomics_analysis" - ] + "installed_by": ["dia_proteomics_analysis"] }, "thermorawfileparser": { "branch": "master", "git_sha": "28ed9d65d3c487772622645d6052bf623816b358", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] } } }, @@ -62,35 +48,27 @@ "dia_proteomics_analysis": { "branch": "master", "git_sha": "146a155d778ba9a944ded6939ed5644307a8600a", - "installed_by": [ - "subworkflows" - ], + "installed_by": ["subworkflows"], "patch": "subworkflows/nf-core/dia_proteomics_analysis/dia_proteomics_analysis.diff" }, "utils_nextflow_pipeline": { "branch": "master", "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", - "installed_by": [ - "subworkflows" - ] + "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", "git_sha": "f0b535b3ae20080f8db03dd5388876ad1ec29d70", - "installed_by": [ - "subworkflows" - ], + "installed_by": ["subworkflows"], "patch": "subworkflows/nf-core/utils_nfcore_pipeline/utils_nfcore_pipeline.diff" }, "utils_nfschema_plugin": { "branch": "master", "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57", - "installed_by": [ - "subworkflows" - ] + "installed_by": ["subworkflows"] } } } } } -} \ No newline at end of file +} diff --git a/modules/local/crystalc/main.nf b/modules/local/crystalc/main.nf index 8f804a5f..aeb53dce 100644 --- a/modules/local/crystalc/main.nf +++ b/modules/local/crystalc/main.nf @@ -30,7 +30,7 @@ process CRYSTALC { def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/diatracer/main.nf b/modules/local/diatracer/main.nf index 4adb6330..1806fd8a 100644 --- a/modules/local/diatracer/main.nf +++ b/modules/local/diatracer/main.nf @@ -40,7 +40,7 @@ process DIATRACER { // --RFMax: max RF value """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/diaumpire/main.nf b/modules/local/diaumpire/main.nf index 7fe6181a..ebfbe11c 100644 --- a/modules/local/diaumpire/main.nf +++ b/modules/local/diaumpire/main.nf @@ -31,7 +31,7 @@ process DIAUMPIRE { def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/fpop/main.nf b/modules/local/fpop/main.nf index bf8d8ca8..2ab1e265 100644 --- a/modules/local/fpop/main.nf +++ b/modules/local/fpop/main.nf @@ -31,7 +31,7 @@ process FPOP { def secondary_arg = secondary_file.name != 'NO_FILE' ? secondary_file : '' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/fragpipe/main.nf b/modules/local/fragpipe/main.nf index 3d560dc2..f5b23b92 100644 --- a/modules/local/fragpipe/main.nf +++ b/modules/local/fragpipe/main.nf @@ -34,7 +34,7 @@ process FRAGPIPE { def num_samples = mzml_list.size() """ - + #!/bin/bash echo "============================================================" diff --git a/modules/local/freequant/main.nf b/modules/local/freequant/main.nf index 7700b7c8..989ce159 100644 --- a/modules/local/freequant/main.nf +++ b/modules/local/freequant/main.nf @@ -36,7 +36,7 @@ process FREEQUANT { // --raw: use raw files (for Thermo .raw) """ - + export HOME=\$(pwd) WORK_DIR=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/ionquant/main.nf b/modules/local/ionquant/main.nf index 2d15e5dc..b4848b5a 100644 --- a/modules/local/ionquant/main.nf +++ b/modules/local/ionquant/main.nf @@ -36,7 +36,7 @@ process IONQUANT { def agree_license = task.ext.agree_fragpipe_license_agreement ?: false """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/mbg/main.nf b/modules/local/mbg/main.nf index 38618489..99d6537f 100644 --- a/modules/local/mbg/main.nf +++ b/modules/local/mbg/main.nf @@ -53,7 +53,7 @@ process MBG { // --allowchimeric: allow chimeric spectra (true/false) """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/msbooster/main.nf b/modules/local/msbooster/main.nf index 0b745b5e..81715792 100644 --- a/modules/local/msbooster/main.nf +++ b/modules/local/msbooster/main.nf @@ -33,7 +33,7 @@ process MSBOOSTER { def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/msfragger/main.nf b/modules/local/msfragger/main.nf index 980e13cd..888ead73 100644 --- a/modules/local/msfragger/main.nf +++ b/modules/local/msfragger/main.nf @@ -53,7 +53,7 @@ process MSFRAGGER { def partial_flag = meta.chunk_id != null ? "--partial ${meta.chunk_id}" : '' """ - + export HOME=\$(pwd) mkdir -p ${prefix} export JAVA_OPTS="-Xmx${mem}G" diff --git a/modules/local/msfragger_calibrate/main.nf b/modules/local/msfragger_calibrate/main.nf index 2c99b7c5..857ad018 100644 --- a/modules/local/msfragger_calibrate/main.nf +++ b/modules/local/msfragger_calibrate/main.nf @@ -47,7 +47,7 @@ process MSFRAGGER_CALIBRATE { def mzml_input = mzml_files instanceof List ? mzml_files.join(' ') : mzml_files """ - + export HOME=\$(pwd) export JAVA_OPTS="-Xmx${mem}G" diff --git a/modules/local/opair/main.nf b/modules/local/opair/main.nf index 5f316754..603007c7 100644 --- a/modules/local/opair/main.nf +++ b/modules/local/opair/main.nf @@ -47,7 +47,7 @@ process OPAIR { // -o: output directory """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/percolator/main.nf b/modules/local/percolator/main.nf index 2ca9fe3f..8d1bb227 100644 --- a/modules/local/percolator/main.nf +++ b/modules/local/percolator/main.nf @@ -40,7 +40,7 @@ process PERCOLATOR { def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/ptmprophet/main.nf b/modules/local/ptmprophet/main.nf index 9f640d79..c8b53301 100644 --- a/modules/local/ptmprophet/main.nf +++ b/modules/local/ptmprophet/main.nf @@ -33,7 +33,7 @@ process PTMPROPHET { // PTMProphet uses UPPERCASE=value format for parameters // Common params: MINPROB=0.5, MAXTHREADS=1, STATIC, KEEPOLD, LABILEMODS, NOSTACK """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/ptmshepherd/main.nf b/modules/local/ptmshepherd/main.nf index 2cd3eaf7..3b580ec1 100644 --- a/modules/local/ptmshepherd/main.nf +++ b/modules/local/ptmshepherd/main.nf @@ -34,7 +34,7 @@ process PTMSHEPHERD { def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + # Clean up files from previous attempts (Nextflow retries in same work dir, # and bash -C noclobber prevents overwriting existing files) rm -f .ptmshepherd_version .fragpipe_version shepherd.config 2>/dev/null || true diff --git a/modules/local/saintexpress/main.nf b/modules/local/saintexpress/main.nf index 54d546dd..7ef77b77 100644 --- a/modules/local/saintexpress/main.nf +++ b/modules/local/saintexpress/main.nf @@ -36,7 +36,7 @@ process SAINTEXPRESS { // Input files must be in current directory: inter.dat, bait.dat, prey.dat """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/skyline/main.nf b/modules/local/skyline/main.nf index de965262..79023c90 100644 --- a/modules/local/skyline/main.nf +++ b/modules/local/skyline/main.nf @@ -43,7 +43,7 @@ process SKYLINE { // runSkylineQuant: run Skyline quantification """ - + export HOME=\$(pwd) mkdir -p ${prefix}/skyline_files diff --git a/modules/local/speclibgen/main.nf b/modules/local/speclibgen/main.nf index ed789922..937941eb 100644 --- a/modules/local/speclibgen/main.nf +++ b/modules/local/speclibgen/main.nf @@ -37,7 +37,7 @@ process SPECLIBGEN { def decoy_tag = task.ext.decoy_tag ?: 'rev_' """ - + export HOME=\$(pwd) mkdir -p ${prefix} diff --git a/modules/local/tmtintegrator/main.nf b/modules/local/tmtintegrator/main.nf index 62e44dda..2a93608a 100644 --- a/modules/local/tmtintegrator/main.nf +++ b/modules/local/tmtintegrator/main.nf @@ -30,7 +30,7 @@ process TMTINTEGRATOR { def mem = task.memory ? Math.max(1, task.memory.toGiga() - 2) : 30 def tools_dir = task.ext.fragpipe_tools_dir ?: '/fragpipe_bin/fragpipe-24.0/fragpipe-24.0/tools' """ - + export HOME=\$(pwd) mkdir -p ${prefix} From 1c99987800b56886d644b6d1e3293f2c8e06d5be Mon Sep 17 00:00:00 2001 From: an-altosian Date: Wed, 30 Sep 2026 05:16:33 +0000 Subject: [PATCH 13/13] test: clear params.database in the reference-proteome function tests nf-test.config loads profile 'test', and conf/test.config now sets params.database, so the organism-only and unknown-organism cases resolved to that database instead of the UniProt reference proteome (CI nf-test shards 3/7, 4/7). Local runs with --profile docker replaced the default profile and hid it; verified with --profile +docker (96/96 stubs). --- .../tests/main.function.nf.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test b/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test index 996a0765..9922a320 100644 --- a/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test +++ b/subworkflows/local/utils_nfcore_msproteomics_pipeline/tests/main.function.nf.test @@ -11,6 +11,10 @@ nextflow_function { test("getProteinDatabase - organism without --database resolves to the UniProt reference proteome") { when { + // -profile test sets params.database; clear it so the reference proteome is used + params { + database = null + } function { """ input[0] = 'Homo sapiens' @@ -29,6 +33,10 @@ nextflow_function { test("getProteinDatabase - unknown organism without --database fails with a clear message") { when { + // -profile test sets params.database; clear it so the reference proteome is used + params { + database = null + } function { """ input[0] = 'Xenopus laevis'