Skip to content

Implement Reader::iter_chromatograms (TIC chromatogram)#22

Open
Nabejo wants to merge 1 commit into
Sigilweaver:mainfrom
Nabejo:iter-chromatograms-opensxraw
Open

Implement Reader::iter_chromatograms (TIC chromatogram)#22
Nabejo wants to merge 1 commit into
Sigilweaver:mainfrom
Nabejo:iter-chromatograms-opensxraw

Conversation

@Nabejo

@Nabejo Nabejo commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #21

Summary

Implements Reader::iter_chromatograms as a SpectrumSource override in crates/opensxraw/src/reader.rs, emitting exactly one total ion current chromatogram (MS:1000235 "total ion current chromatogram") built entirely from the already-decoded idx_records:

  • one point per IdxRecord
  • time_sec = retention_time_min * 60.0
  • intensity = the record's Idx tic (cps)
  • precursor_mz / product_mz = None

This is a pure wire-up of existing decoded fields into openmassspec_core::ChromatogramRecord; no new raw-format decode work is involved. As a result, TIC chromatograms now appear in the <chromatogramList> of the mzML OpenSXRaw produces, instead of falling through to the empty default impl.

Why the per-spectrum TIC reasoning does not apply here

iter_spectra deliberately leaves SpectrumRecord.total_ion_current as None because the Idx TIC is in cps (physically calibrated) and would fail the conformance suite's rel_close check against sum(raw intensities). That constraint is specific to the per-spectrum field. A TIC chromatogram is a separate trace of (retention time, cps) points; assert_source_invariants never inspects iter_chromatograms, so the mismatch does not apply. The per-spectrum field is left None exactly as before, so existing conformance behaviour is unchanged.

Scope: TIC only

BPC and SRM/MRM are intentionally left out, as the issue notes they need materially different net-new decode work:

  • BPC would require a per-scan base peak, which nothing decodes today (base_peak_mz/base_peak_intensity are hardcoded None).
  • SRM/MRM would require Q1/Q3 transition-level data, which is not decoded anywhere in this reader.

Suggest tracking both as separate follow-up issues if pursued.

Testing

  • cargo fmt --all -- --check - clean
  • cargo clippy --all-targets -- -D warnings - clean
  • cargo test --workspace - all pass

Added:

  • Two unit tests in reader.rs (synthetic idx_records, no corpus needed): verify a single TIC record with the correct CV term, None precursor/product, and that time_sec/intensity derive from retention_time_min/tic (including a large-cps regression guard confirming the value passes through verbatim rather than being tied to the per-spectrum field).
  • One corpus-gated integration test in tests/conformance.rs (skips cleanly when the out-of-tree corpus is absent) asserting exactly one TIC chromatogram with one point per Idx record.

The existing conformance suite continues to pass unchanged.

Clean-room note

TIC values come only from bytes already parsed from the .wiff container by this project's own code. No comparison against Analyst / SCIEX OS / MultiQuant / msconvert output was made or used in verifying this feature, per CONTRIBUTING.md.

(Contributed by @Nabejo.)

Wire the already-decoded Idx TIC data into a total ion current chromatogram
(MS:1000235) via a SpectrumSource::iter_chromatograms override. One point per
IdxRecord: time_sec from retention_time_min * 60.0, intensity from the record's
tic (cps). No new raw-format decode work, only wiring existing fields into
openmassspec_core::ChromatogramRecord, so TIC chromatograms now appear in the
mzML <chromatogramList> OpenSXRaw produces.

The per-spectrum SpectrumRecord.total_ion_current field is left None as before:
that value must match sum(raw intensities) for the conformance suite's rel_close
check, which is a per-spectrum constraint and does not apply to a separate
chromatogram trace (assert_source_invariants never inspects iter_chromatograms).

BPC and SRM/MRM are intentionally out of scope: a per-scan base peak is not
decoded today, and no Q1/Q3 transition-level data is decoded anywhere in this
reader. Both need net-new decode work and should be separate follow-up issues.

Adds unit tests for the chromatogram wiring and a corpus-gated integration test.

Refs Sigilweaver#21

Claude-Session: https://claude.ai/code/session_01TLSifJpmaN7RvW3xi2uWgo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement iter_chromatograms: wire up existing Idx TIC data; BPC/SRM need new decode work

1 participant