Skip to content

fix: NovaBio Flex2 - do not emit pH measurement when only vessel temperature is present - #1261

Merged
slopez-b merged 2 commits into
mainfrom
slopez/novabio-flex2-ph-detection-requires-ph
Sep 3, 2026
Merged

fix: NovaBio Flex2 - do not emit pH measurement when only vessel temperature is present#1261
slopez-b merged 2 commits into
mainfrom
slopez/novabio-flex2-ph-detection-requires-ph

Conversation

@slopez-b

@slopez-b slopez-b commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Converting a NovaBio BioProfile Flex2 SampleResults.csv failed schema validation and aborted the entire file whenever any row had a Vessel Temperature (°C) value but a blank pH. Reported by a customer (CUST-12475) whose failing sample had a vessel temperature of 37 °C and no pH reading.

Root cause

DETECTION_PROPERTY_MAPPING["ph-detection"] groups ph and temperature into a single measurement, and _get_measurements() emitted that measurement whenever any of its properties was non-None:

if any(value is not None for value in kwargs.values()):
    measurements.append(_create_measurement(sample, detection_type=..., **kwargs))

A row with a temperature but no pH therefore produced a ph-detection measurement carrying only a temperature. The Allotrope pH-detector schema (adm/ph/REC/2024/09/ph-detector.schema.json, measurementDocumentItems) marks pH as required and temperature as optional, so the measurement failed the anyOf validation:

AllotropeValidationError: Failed to validate allotrope model against schema:
{'device control aggregate document': {'device control document': [{'detection type': 'ph-detection', ...}]},
 ... 'temperature': {'value': 37.0, 'unit': 'degC'}} is not valid under any of the given schemas
Failed validating 'anyOf' in schema[...]['measurement document']['items']['allOf'][1]

Fix

Skip a detection type when its schema-required measured value is absent. Implemented as a small mapping rather than a one-off if detection_type == "ph-detection" check, so the same guard can cover other detection types later:

# Detection types whose ASM measurement schema requires a specific measured value; a
# measurement must not be emitted when that value is absent.
REQUIRED_PROPERTY_BY_DETECTION_TYPE = {"ph-detection": "ph"}

The guard sits at the top of the loop body, so it also avoids building kwargs needlessly.
Temperature-only samples now simply produce no pH measurement; every other detection type on the sample is unaffected.

Test plan

  • New parametrized test_ph_detection_requires_ph_value covers all four pH/temperature combinations: temperature-only and empty samples yield no ph-detection, while both pH cases still do.
  • New SampleResults2025-02-09_104000.csv fixture (plus generated .json snapshot) exercises full file conversion across three samples: temperature-without-pH, pH-with-temperature, and pH-without-temperature. The first yields only metabolite and blood-gas measurements; the other two retain ph-detection.
  • Both new tests confirmed to fail on the unpatched parser and pass with the fix.
  • The three pre-existing NovaBio Flex2 snapshots are byte-identical, so samples that do have pH are provably unchanged.
  • Full suite green: 1128 tests passed.
  • ruff, black, and mypy clean on the changed files.

Manual validation

Before the fix this raised AllotropeValidationError; after the fix it converts and validates cleanly, keeping the metabolite detection:

CONVERTED OK
detection types: ['metabolite-detection']

Out of scope

Two pre-existing behaviors are deliberately left alone, as neither is the reported scenario and both need a different remedy:

  1. A sample with only a temperature and no other measurable data still fails, because an empty metabolite-detection measurement is emitted.
  2. When a file has a units row, po2_unit/pco2_unit are populated from that row even when the PO2/PCO2 values are blank, making the any(value is not None ...) guard true and emitting a valueless blood-gas-detection measurement that fails validation the same way. This has the same shape as the bug fixed here, but the trigger is a units-only measurement rather than a missing required field. The new fixture supplies gas values on every row to avoid it.

…erature is present

A sample with a vessel temperature but a blank pH aborted the entire file
conversion: pH and temperature are grouped into one ph-detection measurement,
which was emitted whenever either value was present, but the Allotrope
pH-detector schema requires a pH value.
Skip a detection type when its schema-required measured value is absent.
@slopez-b
slopez-b requested a review from a team as a code owner September 2, 2026 21:51

@ajcariaga16 ajcariaga16 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🚢

@slopez-b
slopez-b merged commit 56c18e1 into main Sep 3, 2026
9 checks passed
@slopez-b
slopez-b deleted the slopez/novabio-flex2-ph-detection-requires-ph branch September 3, 2026 13:40
ajcariaga16 added a commit that referenced this pull request Sep 8, 2026
### Added

- Thermo Fisher Diomni - initial implementation (#1251)
- Beckman Coulter PharmSpec - add container id to the sample custom
document (#1253)

### Fixed

- NovaBio Flex2 - do not emit pH measurement when only vessel
temperature is present (#1261)
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.

2 participants