inferenceCoreTemp.ts

Runs ONNX-based core body temperature inference across multiple model variants

Purpose

This module predicts core body temperature (in Celsius) from physiological and environmental inputs using one of several ONNX model variants, with a physics-based fallback for environments where the ONNX runtime is unavailable.

Its responsibilities include:

  • Validating all required finite numeric inputs before inference
  • Selecting the appropriate ONNX model (or baseline) based on the model argument
  • Constructing a correctly ordered feature vector per model variant
  • Loading and caching the ONNX session via getOnnxSession
  • Running the session and extracting the scalar core temperature output
  • Classifying the result into a heat-stress severity state
  • Returning a structured result with the temperature, model identifier, and state

Invariants

Input Validation

All required inputs must be finite numbers before any model is invoked.

The following fields are validated unconditionally:

  • wbgt
  • gender
  • bmi
  • age
  • daysActive14

Invalid inputs throw an Error with a descriptive field name.


Optional Input Enforcement

Each model variant enforces its own optional input requirements at runtime:

ModelRequired optional inputs
baselinecpm40
watch-onlyhbpm40
hybridhbpm40 and cpm40
phone-onlycpm40

Missing required optional inputs return { coreTempC: 0, ... } with an error log rather than throwing.


Zero-Value Error Sentinel

coreTempC: 0 is used as the error sentinel value throughout.

Callers must treat a coreTempC of 0 as an inference failure, not a valid physiological reading.


Feature Vector Ordering

Each model variant uses a fixed, order-sensitive feature vector.

Incorrect ordering would silently produce wrong predictions; the ordering is maintained per model in code and must not be changed without retraining:

ModelFeature order
baseline[wbgt, cpm40, gender, bmi, age]
watch-only[hbpm40, wbgt, age, gender, bmi, daysActive14]
hybrid[hbpm40, cpm40, wbgt, age, gender, bmi, daysActive14]
phone-only[cpm40, wbgt, age, gender, bmi, daysActive14]

State Classification Thresholds

Core temp (°C)State
< 37.5normal
37.5 – < 38.0elevated
38.0 – < 39.0heat-strain
≥ 39.0heat-stroke-risk

Variants

Model Selection

The model parameter selects the inference path:

  • "baseline" — Physics-based formula; no ONNX session is created. Intended for use in Expo Go or test environments where the native runtime is unavailable.
  • "watch-only" — ONNX model using heart rate and environmental features (filtered_model2.onnx).
  • "hybrid" — ONNX model using both heart rate and accelerometer features (filtered_model3.onnx).
  • "phone-only" (default) — ONNX model using accelerometer and environmental features (filtered_model1.onnx).

Baseline Formula

The fallback computation approximates core temperature as:

T = 36.9
  + 0.08 × (wbgt − 28)
  + 0.0002 × cpm40
  + 0.01 × ((bmi − 25) / 5)
  + 0.01 × ((age − 35) / 10)
  + genderAdj

Where genderAdj is 0.03 for male, 0.0 for female, and 0.01 for unknown.

The result is clamped to [35.0, 42.0] °C.


Exports

Gender

type Gender = 0 | 1 | 2;

Encodes biological sex used during model training:

ValueMeaning
0Other / unknown
1Male
2Female

CoreTempInputs

type CoreTempInputs = {
	wbgt: number;
	age: number;
	gender: Gender;
	bmi: number;
	daysActive14: number;
	cpm40?: number;
	hbpm40?: number;
};

All required fields must be finite numbers. Optional fields are enforced per model variant.


CoreTempResult

type CoreTempResult = {
	coreTempC: number;
	modelUsed: string;
	state: "normal" | "elevated" | "heat-strain" | "heat-stroke-risk";
};

coreTempC: 0 indicates an inference failure. modelUsed identifies which model path was taken.


runCoreTempInference(...)

async function runCoreTempInference(
	inputs: CoreTempInputs,
	model?: string,
): Promise<CoreTempResult>

Runs core temperature inference using the specified model variant.

Parameters

ParameterDescription
inputsPhysiological and environmental feature inputs
modelModel variant selector ("baseline", "watch-only", "hybrid", "phone-only")

Returns

A Promise<CoreTempResult> containing the predicted core temperature, model identifier, and heat-stress state.

Throws

Throws when required inputs are non-finite (via validateInputs). Returns a zero-sentinel result (does not throw) when optional model-specific inputs are missing or when no model could be selected.