Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conf/modules/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ process {
}

// Result tables from multiple pipelines including LFQ, TMT, DIA, DDA
withName: '.*:PROTEOMICSLFQ|PROTEIN_QUANTIFIER|MSSTATS_CONVERTER|FINAL_QUANTIFICATION|CONVERT_RESULTS' {
withName: '.*:PROTEOMICSLFQ|PROTEIN_QUANTIFIER|MSSTATS_CONVERTER|FINAL_QUANTIFICATION|CONVERT_RESULTS|ISOBARIC_WORKFLOW' {
publishDir = [
path: { "${params.outdir}/quant_tables" },
mode: 'copy',
Expand Down
64 changes: 64 additions & 0 deletions modules/local/openms/isobaric_workflow/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
process ISOBARIC_WORKFLOW {
tag "${expdes.baseName}"
label 'process_high'
label 'openms'

container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
'oras://ghcr.io/bigbio/openms-tools-thirdparty-sif:2025.04.14' :
'ghcr.io/bigbio/openms-tools-thirdparty:2025.04.14' }"

input:
path(mzmls)
path(id_files)
path(expdes)

output:
path "${expdes.baseName}_openms.mzTab", emit: out_mztab
path "${expdes.baseName}_openms.consensusXML", emit: out_consensusXML
path "*.log", emit: log
path "versions.yml", emit: versions

script:
def args = task.ext.args ?: ''
def extractBaseName = { filename ->
def name = filename.toString()
name = name.replaceAll(/\.mzML$/, '')

if (name.endsWith('.idXML')) {
name = name.replaceAll(/\.idXML$/, '')
name = name.replaceAll(/_(comet|msgf|sage|consensus)(_perc)?(_filter)?(_fdr)?$/, '')
}
return name
}

def mzml_sorted = mzmls.collect().sort{ a, b ->
extractBaseName(a.name) <=> extractBaseName(b.name)
}
def id_sorted = id_files.collect().sort{ a, b ->
extractBaseName(a.name) <=> extractBaseName(b.name)
}

"""
IsobaricWorkflow \\
-threads ${task.cpus} \\
-in ${mzml_sorted.join(' ')} \\
-in_id ${id_sorted.join(' ')} \\
-exp_design ${expdes} \\
-type ${params.type} \\
-inference_method ${params.protein_inference_method} \\
Comment on lines +46 to +48
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Wrong label type source 🐞 Bug ≡ Correctness

ISOBARIC_WORKFLOW passes the IsobaricWorkflow “-type” argument from params.type (default
itraq4plex), which is disconnected from the pipeline’s existing experiment label type
(meta.labelling_type / params.labelling_type), so TMT runs can be processed with the wrong plex
setting and yield incorrect quantification.
Agent Prompt
## Issue description
`ISOBARIC_WORKFLOW` passes `-type` from `params.type` (new, defaults to `itraq4plex`), but the pipeline already tracks the experiment label type as `labelling_type` (in `meta.labelling_type`, derived from SDRF or `params.labelling_type`). This can cause TMT experiments to run with the wrong `-type` value.

## Issue Context
- `meta.labelling_type` is the pipeline’s current source-of-truth for label type.
- `params.labelling_type` is already a top-level parameter.
- Introducing a separate `params.type` makes the behavior diverge from the rest of the pipeline.

## Fix Focus Areas
- modules/local/openms/isobaric_workflow/main.nf[41-57]
- workflows/tmt.nf[41-60]
- subworkflows/local/create_input_channel/main.nf[102-114]
- subworkflows/local/create_input_channel/main.nf[144-152]
- nextflow.config[69-75]
- nextflow.config[181-183]

## Suggested fix
1. Remove the new `params.type` (or at least stop using it).
2. Plumb the experiment’s labeling type into `ISOBARIC_WORKFLOW` and pass that to the tool:
   - Option A (preferred): add a `val labelling_type` input to the `ISOBARIC_WORKFLOW` process and compute it in `workflows/tmt.nf` from `ch_file_preparation_results` metadata (e.g., extract `it[0].labelling_type`, ensure it’s unique, then pass it).
   - Option B: use `params.labelling_type` if you also ensure it is populated for SDRF runs (currently SDRF sets `meta.labelling_type`, not necessarily `params.labelling_type`).
3. Update the IsobaricWorkflow invocation to `-type ${labelling_type}` (or `${meta.labelling_type}` if you decide to pass `meta`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

-protein_quantification ${params.protein_quant} \\
-psmFDR ${params.psm_level_fdr_cutoff} \\
-proteinFDR ${params.protein_level_fdr_cutoff} \\
-picked_fdr ${params.picked_fdr} \\
-picked_decoy_string ${params.decoy_string} \\
-out ${expdes.baseName}_openms.consensusXML \\
-out_mzTab ${expdes.baseName}_openms.mzTab \\
$args \\
2>&1 | tee isobaricworkflow.log

cat <<-END_VERSIONS > versions.yml
"${task.process}":
IsobaricWorkflow: \$(IsobaricWorkflow 2>&1 | grep -E '^Version(.*)' | sed 's/Version: //g' | cut -d ' ' -f 1)
END_VERSIONS
"""
}
42 changes: 42 additions & 0 deletions modules/local/openms/isobaric_workflow/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: isobaric_workflow
description: Extracts and normalizes isobaric labeling information from an LC-MS/MS experiment.
keywords:
- OpenMS
- quantification
tools:
- IsobaricWorkflow:
description: |
Extracts and normalizes isobaric labeling information from an LC-MS/MS experiment.
homepage: https://abibuilder.cs.uni-tuebingen.de/archive/openms/Documentation/release/latest/html/TOPP_IsobaricWorkflow.html
documentation: https://abibuilder.cs.uni-tuebingen.de/archive/openms/Documentation/release/latest/html/TOPP_IsobaricWorkflow.html
- mzmls:
type: file
description: Input Spectra in mzML format
pattern: "*.mzML"
- id_files:
type: file
description: Identifications in idXML or mzIdentML format with posterior error probabilities as score type.
pattern: "*.idXML"
- expdes:
type: file
description: An experimental design file
pattern: "*.tsv"
output:
- out_mztab:
type: file
description: mzTab file with analysis results
pattern: "*.mzTab"
- out_consensusXML:
type: file
description: ConsensusXML file for visualization and further processing in OpenMS.
pattern: "*.consensusXML"
- log:
type: file
description: log file
pattern: "*.log"
- version:
type: file
description: File containing software version
pattern: "versions.yml"
authors:
- "@MaLLLiYA"
3 changes: 3 additions & 0 deletions nextflow.config
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ params {
add_triqler_output = false
quantify_decoys = false

// IsobaricWorkflow flags
type = 'itraq4plex'

// ProteomicsLFQ MBR parameters
targeted_only = true // If false MBR will be applied for quantification of all proteins
feature_with_id_min_score = 0.10
Expand Down
45 changes: 20 additions & 25 deletions workflows/tmt.nf
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
//
// MODULES: Local to the pipeline
//
include { FILE_MERGE } from '../modules/local/openms/file_merge/main'
include { MSSTATS_TMT } from '../modules/local/msstats/msstats_tmt/main'
include { ISOBARIC_WORKFLOW } from '../modules/local/openms/isobaric_workflow/main'
include { MSSTATS_CONVERTER } from '../modules/local/openms/msstats_converter/main'

//
// SUBWORKFLOWS: Consisting of a mix of local and nf-core/modules
//
include { FEATURE_MAPPER } from '../subworkflows/local/feature_mapper/main'
include { PROTEIN_INFERENCE } from '../subworkflows/local/protein_inference/main'
include { PROTEIN_QUANT } from '../subworkflows/local/protein_quant/main'
include { ID } from '../subworkflows/local/id/main'

/*
Expand All @@ -41,35 +39,32 @@ workflow TMT {
ch_software_versions = ch_software_versions.mix(ID.out.versions)

//
// SUBWORKFLOW: FEATUREMAPPER
// SUBWORKFLOW: ISOBARIC_WORKFLOW
//
FEATURE_MAPPER(ch_file_preparation_results, ID.out.id_results)
ch_software_versions = ch_software_versions.mix(FEATURE_MAPPER.out.versions)
ch_file_preparation_results.join(ID.out.id_results)
.multiMap { it ->
mzmls: pmultiqc_mzmls: it[1]
ids: it[2]
}
.set{ ch_iso_workflow }
ISOBARIC_WORKFLOW(ch_iso_workflow.mzmls.collect(),
ch_iso_workflow.ids.collect(),
ch_expdesign
)
ch_software_versions = ch_software_versions.mix(ISOBARIC_WORKFLOW.out.versions)

//
// MODULE: FILEMERGE
// MODULE: MSSTATS_CONVERTER
//
FILE_MERGE(FEATURE_MAPPER.out.id_map.collect())
ch_software_versions = ch_software_versions.mix(FILE_MERGE.out.versions)

//
// SUBWORKFLOW: PROTEININFERENCE
//
PROTEIN_INFERENCE(FILE_MERGE.out.id_merge)
ch_software_versions = ch_software_versions.mix(PROTEIN_INFERENCE.out.versions)

//
// SUBWORKFLOW: PROTEINQUANT
//
PROTEIN_QUANT(PROTEIN_INFERENCE.out.epi_idfilter, ch_expdesign)
ch_software_versions = ch_software_versions.mix(PROTEIN_QUANT.out.versions)
MSSTATS_CONVERTER(ISOBARIC_WORKFLOW.out.out_consensusXML, ch_expdesign, "ISO")
ch_software_versions = ch_software_versions.mix(MSSTATS_CONVERTER.out.versions)

//
// MODULE: MSSTATSTMT
//
ch_msstats_out = Channel.empty()
if(!params.skip_post_msstats){
MSSTATS_TMT(PROTEIN_QUANT.out.msstats_csv)
MSSTATS_TMT(MSSTATS_CONVERTER.out.out_msstats)
ch_msstats_out = MSSTATS_TMT.out.msstats_csv
ch_software_versions = ch_software_versions.mix(MSSTATS_TMT.out.versions)
}
Expand All @@ -85,8 +80,8 @@ workflow TMT {
emit:
ch_pmultiqc_ids = ch_pmultiqc_ids
ch_pmultiqc_consensus = ch_pmultiqc_consensus
final_result = PROTEIN_QUANT.out.out_mztab
msstats_in = PROTEIN_QUANT.out.msstats_csv
final_result = ISOBARIC_WORKFLOW.out.out_mztab
msstats_in = MSSTATS_CONVERTER.out.out_msstats
msstats_out = ch_msstats_out
versions = ch_software_versions
}
Loading