Skip to content

fix(qpx): use write_dataset_mudata so a partial MuData cannot ship - #732

Draft
ypriverol wants to merge 1 commit into
bigbio:devfrom
ypriverol:fix/qpx-mudata-modality-guard
Draft

ypriverol wants to merge 1 commit into
bigbio:devfrom
ypriverol:fix/qpx-mudata-modality-guard

Conversation

@ypriverol

Copy link
Copy Markdown
Contributor

Draft until qpx 1.1.4 is tagged — the ghcr.io/bigbio/qpx:1.1.4 image does not exist yet, so CI will fail to pull it. Depends on bigbio/qpx#316.

The problem

QPX_OPENMSCONSENSUS calls build_mudata() + mdata.write() directly, which bypasses qpx's own writer. write_dataset_mudata checks:

missing = required_modalities - set(mdata.mod)
if missing:
    raise ValueError(f"Missing required quantification modalities: ...")

build_mudata catches per-modality build failures, logs them, and continues — so a modality that fails to build is simply absent from the result. The module then wrote that incomplete MuData and the task exited 0.

This is not theoretical. Validating the 1.1.4 container against MSV000085836 (TMT, 552 runs x 10 channels) produced:

Failed to build precursors modality: offset overflow while concatenating arrays
...
modalities present: ['proteins']

A 451 MB h5mu with no precursors, reported as success. The underlying overflow is fixed in bigbio/qpx#316 (that dataset now yields ['precursors', 'proteins'], 988 MB), but the module would have shipped the partial view for any future modality failure — so the guard matters independently of that bug.

Changes

  1. Use write_dataset_mudata. Gets the modality guard, plus a tmp-file write and removal of a stale h5mu when the build fails — neither of which the inline heredoc did.
  2. Make *.h5mu optional. It had been made a required output, which inverted qpx's contract: the parquet views are the dataset's source of truth and the MuData view is explicitly best-effort. A view that cannot be built should not destroy an otherwise complete run — which is exactly what happened on MSV000085836, where a ~1h19 conversion succeeded and the run died afterwards on the h5mu step.
  3. Bump container and conda pins to 1.1.4.

Net behaviour: a complete view, or no view plus a warning — never a silently partial one.

Scope check

out.mudata is consumed only by this module's own nf-test (assert process.out.mudata.size() == 1), which exercises the stub and still passes; no workflow consumes the channel, so optional: true changes nothing downstream.

QPX_OPENMSCONSENSUS called build_mudata() + mdata.write() directly. That
bypasses qpx's own writer, which checks

    missing = required_modalities - set(mdata.mod)

and refuses a MuData missing a required quantification modality.

build_mudata catches per-modality failures, logs them and continues, so a
modality that failed to build was simply absent: the module wrote an
INCOMPLETE h5mu and the task exited 0. On MSV000085836 (TMT) that shipped
a view with proteins and no precursors, from a pyarrow offset overflow
(bigbio/qpx#316).

Also make *.h5mu an optional output. It was made required, which inverted
qpx's contract: the parquet views are the dataset's source of truth and
the MuData view is best-effort, so a view that cannot be built must not
destroy an otherwise complete run. Combined with the writer's guard the
behaviour is now: complete view, or no view and a warning - never a
silently partial one.

write_dataset_mudata also writes via a temporary file and removes a stale
h5mu when the build fails, which the inline heredoc did not.

Requires qpx 1.1.4: write_dataset_mudata was extracted in bigbio/qpx#312
and the overflow fixed in bigbio/qpx#316. Container and conda pins bumped.
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

nf-core pipelines lint overall result: Passed ✅ ⚠️

Posted for pipeline commit 78bc810

+| ✅ 117 tests passed       |+
#| ❔  18 tests were ignored |#
#| ❔   1 tests had warnings |#
!| ❗   7 tests had warnings |!
Details

❗ Test warnings:

  • pipeline_todos - TODO string in nextflow.config: Optionally, you can add a pipeline-specific nf-core config at https://github.com/nf-core/configs
  • pipeline_todos - TODO string in nextflow.config: Specify any additional parameters here
  • pipeline_todos - TODO string in CONTRIBUTING.md: Add any pipeline specific contribution guidelines here, such as coding styles, procedures, checklists etc.
  • pipeline_todos - TODO string in base.config: Check the defaults for all processes
  • pipeline_todos - TODO string in base.config: Customise requirements for specific processes.
  • pipeline_if_empty_null - ifEmpty(null) found in /home/runner/work/quantms/quantms/subworkflows/local/id/main.nf: _ ch_software_versions = ch_software_versions.mix(PHOSPHO_SCORING.out.versions.ifEmpty(null))
    _
  • pipeline_if_empty_null - ifEmpty(null) found in /home/runner/work/quantms/quantms/subworkflows/local/dda_id/main.nf: _ ch_software_versions = ch_software_versions.mix(PHOSPHO_SCORING.out.versions.ifEmpty(null))
    _

❔ Tests ignored:

❔ Tests fixed:

✅ Tests passed:

Run details

  • nf-core/tools version 4.1.0
  • Run at 2026-09-13 05:15:09

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant