Skip to content

fix(scan-event): decode Exploris coefficients + MS2 precursor#4

Open
oskarsari wants to merge 1 commit into
Sigilweaver:mainfrom
karsa-oy:pr/exploris-scan-event
Open

fix(scan-event): decode Exploris coefficients + MS2 precursor#4
oskarsari wants to merge 1 commit into
Sigilweaver:mainfrom
karsa-oy:pr/exploris-scan-event

Conversation

@oskarsari

Copy link
Copy Markdown

Closes #2 .

What

Decodes two scan-event-derived values that were missing for Orbitrap Exploris files (v66, body_size 136): the frequency->m/z calibration coefficients (so the profile m/z converts correctly) and the MS2 precursor m/z (so dependent scans report their precursor and the rendered filter includes it).

Why

The v66 parser read the nparam/coefficients block at a fixed body_size - 64 and the MS2 reaction record at body offset 8. Both hold for Q Exactive (body_size 144) but not Exploris (136):

  • On Exploris MS1, body_size - 64 landed on a zero word, so coefficients came back empty and Profile::to_mz_intensity passed the raw frequency through unconverted (profile m/z was wrong, e.g. ~600-2050 instead of ~40-470).
  • On Exploris MS2, the reaction record starts at body offset 4 (no leading count word), so the offset-8 parse read the precursor double's low word as a reaction count, found it implausible, and returned no reaction. The precursor and HCD energy were lost and the filter dropped the precursor.

How

  • Coefficients: read the nparam/coefficients block immediately after the located scan-window FractionCollector (offset 80 for the offset-64 FC family) instead of a fixed body_size - 64. On body_size 144 (Q Exactive) this is the same offset 80, so that path is unchanged; Exploris (136) now finds its A/B/C.
  • Precursor: when an MS2+/dependent, non-tribrid scan yields no reaction from the offset-8 parse, fall back to the Exploris layout where the reaction record begins at body offset 4 (precursor f64 at body[4..12]).

Both changes are additive/guarded; other instrument families take the existing paths.

Testing

cargo fmt --check, cargo clippy --all-targets -- -D warnings, and cargo test --all pass. Validated against the vendor reader on Orbitrap Exploris 120 acquisitions:

  • Profile m/z now converts correctly, matching the vendor reader to the last digit.
  • MS2 precursor and activation energy match exactly, and build_filter now renders e.g. ... ms2 100.0757@hcd3.00 ....

No regression on Q Exactive Plus files (identical coefficients/profile before and after). All format knowledge is from public-corpus files and my own analysis.

Checklist

  • CHANGELOG [Unreleased] updated
  • cargo fmt / cargo clippy -D warnings / cargo test --all pass
  • ASCII-only source

The v66 parser read the nparam/coefficients block at a fixed body_size - 64
and the MS2 reaction record at body offset 8. Both hold for Q Exactive
(body_size 144) but not Orbitrap Exploris (body_size 136), where the profile
m/z came out mis-converted (no coefficients) and the precursor m/z was lost.

- Coefficients: read the nparam block immediately after the located scan-window
  FractionCollector. For the offset-64 FC family (Q Exactive / Exploris /
  Astral) that is offset 80; on body_size 144 this equals the legacy
  body_size - 64 (no change), while Exploris (136) now finds its A/B/C.
- Precursor: when an MS2+/dependent non-tribrid scan yields no reaction from
  the offset-8 parse, fall back to the Exploris layout where the reaction
  record begins at body offset 4 (precursor f64 at body[4..12]).

Validated against the vendor reader: Exploris profile m/z is now correctly
converted, and MS2 precursor + activation energy match exactly.
Q Exactive Plus file reads are unchanged.
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.

Exploris scan-event: profile m/z mis-calibrated and MS2 precursor not decoded

1 participant