Problem
The arena has one mobility: Vec<f32> column and one mutually exclusive MobilityKind, but a library can contain any combination of:
- inverse reduced mobility (1/K0)
- drift time
- FAIMS compensation voltage
- collision cross section (CCS; preserved metadata, not necessarily a search axis)
The mzSpecLib reader currently stores 1/K0 or fallback drift time in the same column, maps absence to 0.0, and leaves the library reporting Ook0. Consequently im_axis_filterable can apply a TIMS window around a fake zero and silently produce no IDs.
Required invariants
- Preserve each observable independently, including multiple observables on one entry.
- Represent absence explicitly;
0.0 is a valid value, not a sentinel.
- Derive capabilities from presence, not values.
- Restrict search only on compatible observables shared by the run and library entry. Otherwise leave that dimension unrestricted and its score unavailable/neutral.
- Never interpret drift time or FAIMS CV as 1/K0. Any conversion must be explicit and carry its calibration/physical assumptions.
This likely means renaming the current column to inverse_reduced_mobility and adding optional drift-time, FAIMS-CV, and CCS columns. Exact storage and capability representation are implementation choices.
Acceptance
- no-IM library + TIMS data degrades to search without IM restriction
- 1/K0 library + non-IM data does likewise
- matching 1/K0 inputs retain current filtering
- observables round-trip independently; entries carrying both FAIMS CV and 1/K0 retain both
- missing and legitimate-zero values remain distinguishable
Separate from mzSpecLib interchange because this changes the arena schema, capability/query contract, scoring availability, and serialization—not just parsing.
Problem
The arena has one
mobility: Vec<f32>column and one mutually exclusiveMobilityKind, but a library can contain any combination of:The mzSpecLib reader currently stores 1/K0 or fallback drift time in the same column, maps absence to
0.0, and leaves the library reportingOok0. Consequentlyim_axis_filterablecan apply a TIMS window around a fake zero and silently produce no IDs.Required invariants
0.0is a valid value, not a sentinel.This likely means renaming the current column to
inverse_reduced_mobilityand adding optional drift-time, FAIMS-CV, and CCS columns. Exact storage and capability representation are implementation choices.Acceptance
Separate from mzSpecLib interchange because this changes the arena schema, capability/query contract, scoring availability, and serialization—not just parsing.