///|
/// A source-neutral sample emitted by a wearable or an offline recorder.
///
/// The type deliberately keeps the original timestamp and sensor metadata so
/// downstream reports can explain how a metric was produced. A sample may
/// carry both an RR interval and a heart-rate value; the ingestion layer
/// reconciles them without silently discarding the source values.
pub(all) struct WearableSample {
timestamp_seconds : Double
rr_ms : Double
heart_rate_bpm : Double
movement_g : Double
temperature_c : Double
signal_quality : Double
source_id : String
sequence_number : Int
} derive(FromJson, ToJson, Debug, Eq)
///|
/// Disposition of a sample after validation.
pub(all) enum WearableSampleDisposition {
Accepted
Invalid
Duplicate
OutOfOrder
LowQuality
} derive(FromJson, ToJson, Debug, Eq)
///|
/// An ingestion notice is machine-readable and suitable for audit logs.
pub(all) struct IngestNotice {
index : Int
code : String
message : String
severity : String
disposition : WearableSampleDisposition
} derive(FromJson, ToJson, Debug, Eq)
///|
/// Ingestion settings shared by batch and streaming adapters.
pub(all) struct WearableIngestConfig {
minimum_quality : Double
maximum_gap_seconds : Double
maximum_duration_seconds : Double
allow_out_of_order : Bool
reject_duplicates : Bool
derive_missing_heart_rate : Bool
derive_missing_rr : Bool
source_name : String
} derive(FromJson, ToJson, Debug, Eq)
///|
/// Conservative defaults for wearable telemetry.
pub fn WearableIngestConfig::default() -> WearableIngestConfig {
{
minimum_quality: 0.70,
maximum_gap_seconds: 5.0,
maximum_duration_seconds: 86400.0,
allow_out_of_order: false,
reject_duplicates: true,
derive_missing_heart_rate: true,
derive_missing_rr: true,
source_name: "unknown",
}
}
///|
/// A stable summary returned by every ingestion operation.
pub(all) struct WearableIngestReport {
samples : Array[WearableSample]
notices : Array[IngestNotice]
accepted_count : Int
rejected_count : Int
duplicate_count : Int
out_of_order_count : Int
low_quality_count : Int
invalid_count : Int
gap_count : Int
duration_seconds : Double
quality_ratio : Double
complete : Bool
} derive(FromJson, ToJson, Debug, Eq)
///|
/// A fixed-width time window over accepted telemetry.
pub(all) struct TelemetryWindow {
ordinal : Int
start_seconds : Double
end_seconds : Double
samples : Array[WearableSample]
rr_intervals : Array[Double]
mean_quality : Double
gap_count : Int
complete : Bool
} derive(FromJson, ToJson, Debug, Eq)
///|
/// A normalized sample with a source-independent quality weight.
pub(all) struct NormalizedWearableSample {
sample : WearableSample
quality_weight : Double
disposition : WearableSampleDisposition
repaired : Bool
} derive(FromJson, ToJson, Debug, Eq)
///|
/// Make a sample without requiring a particular device SDK.
pub fn make_wearable_sample(
timestamp_seconds : Double,
rr_ms : Double,
heart_rate_bpm : Double,
signal_quality : Double,
source_id : String,
sequence_number : Int,
) -> WearableSample {
{
timestamp_seconds,
rr_ms,
heart_rate_bpm,
movement_g: 0.0,
temperature_c: 0.0,
signal_quality,
source_id,
sequence_number,
}
}
///|
/// Return a copy with optional movement and temperature channels attached.
pub fn wearable_sample_with_context(
sample : WearableSample,
movement_g : Double,
temperature_c : Double,
) -> WearableSample {
{
timestamp_seconds: sample.timestamp_seconds,
rr_ms: sample.rr_ms,
heart_rate_bpm: sample.heart_rate_bpm,
movement_g,
temperature_c,
signal_quality: sample.signal_quality,
source_id: sample.source_id,
sequence_number: sample.sequence_number,
}
}
///|
/// Check whether a floating-point value is usable in a telemetry record.
pub fn wearable_finite(value : Double) -> Bool {
!value.is_nan() && !value.is_inf()
}
///|
/// Return whether a sample carries at least one usable cardiac channel.
pub fn wearable_sample_has_cardiac_value(sample : WearableSample) -> Bool {
(wearable_finite(sample.rr_ms) && sample.rr_ms > 0.0) ||
(wearable_finite(sample.heart_rate_bpm) && sample.heart_rate_bpm > 0.0)
}
///|
/// Validate a sample against broad transport-level constraints.
pub fn wearable_sample_is_valid(
sample : WearableSample,
config : WearableIngestConfig,
) -> Bool {
let timestamp_ok = wearable_finite(sample.timestamp_seconds) &&
sample.timestamp_seconds >= 0.0
let rr_ok = !wearable_finite(sample.rr_ms) ||
sample.rr_ms == 0.0 ||
(sample.rr_ms >= 200.0 && sample.rr_ms <= 5000.0)
let hr_ok = !wearable_finite(sample.heart_rate_bpm) ||
sample.heart_rate_bpm == 0.0 ||
(sample.heart_rate_bpm >= 10.0 && sample.heart_rate_bpm <= 300.0)
let quality_ok = wearable_finite(sample.signal_quality) &&
sample.signal_quality >= 0.0 &&
sample.signal_quality <= 1.0
let context_ok = (
!wearable_finite(sample.movement_g) || sample.movement_g >= 0.0
) &&
(
!wearable_finite(sample.temperature_c) ||
(sample.temperature_c >= -100.0 && sample.temperature_c <= 100.0)
)
timestamp_ok &&
rr_ok &&
hr_ok &&
quality_ok &&
context_ok &&
wearable_sample_has_cardiac_value(sample) &&
sample.signal_quality >= config.minimum_quality
}
///|
/// Reconcile an RR interval and heart rate without changing source metadata.
pub fn reconcile_cardiac_channels(
sample : WearableSample,
config : WearableIngestConfig,
) -> (WearableSample, Bool) {
let rr = if wearable_finite(sample.rr_ms) && sample.rr_ms > 0.0 {
sample.rr_ms
} else if config.derive_missing_rr && sample.heart_rate_bpm > 0.0 {
60000.0 / sample.heart_rate_bpm
} else {
sample.rr_ms
}
let hr = if wearable_finite(sample.heart_rate_bpm) &&
sample.heart_rate_bpm > 0.0 {
sample.heart_rate_bpm
} else if config.derive_missing_heart_rate && rr > 0.0 {
60000.0 / rr
} else {
sample.heart_rate_bpm
}
(
{
timestamp_seconds: sample.timestamp_seconds,
rr_ms: rr,
heart_rate_bpm: hr,
movement_g: sample.movement_g,
temperature_c: sample.temperature_c,
signal_quality: sample.signal_quality,
source_id: sample.source_id,
sequence_number: sample.sequence_number,
},
rr != sample.rr_ms || hr != sample.heart_rate_bpm,
)
}
///|
/// Clamp quality to a finite unit interval for scoring.
pub fn wearable_quality_weight(value : Double) -> Double {
if !wearable_finite(value) {
0.0
} else {
value.clamp(min=0.0, max=1.0)
}
}
///|
/// Normalize one sample and report whether a channel was derived.
pub fn normalize_wearable_sample(
sample : WearableSample,
config : WearableIngestConfig,
) -> NormalizedWearableSample {
let (reconciled, repaired) = reconcile_cardiac_channels(sample, config)
{
sample: reconciled,
quality_weight: wearable_quality_weight(reconciled.signal_quality),
disposition: if wearable_sample_is_valid(reconciled, config) {
Accepted
} else {
Invalid
},
repaired,
}
}
///|
/// Return whether two samples represent the same transport event.
pub fn wearable_samples_are_duplicate(
left : WearableSample,
right : WearableSample,
) -> Bool {
left.timestamp_seconds == right.timestamp_seconds &&
left.source_id == right.source_id &&
(
left.sequence_number == right.sequence_number ||
left.sequence_number < 0 ||
right.sequence_number < 0
)
}
///|
/// Add a notice to an array while keeping notice construction uniform.
fn add_ingest_notice(
notices : Array[IngestNotice],
index : Int,
code : String,
message : String,
severity : String,
disposition : WearableSampleDisposition,
) -> Unit {
notices.push({ index, code, message, severity, disposition })
}
///|
/// Detect whether a gap exceeds the configured transport interval.
pub fn wearable_gap_detected(
previous_timestamp : Double,
current_timestamp : Double,
maximum_gap_seconds : Double,
) -> Bool {
maximum_gap_seconds > 0.0 &&
current_timestamp - previous_timestamp > maximum_gap_seconds
}
///|
/// Ingest a batch, reject malformed events, and retain an audit trail.
pub fn ingest_wearable_samples(
input : Array[WearableSample],
config : WearableIngestConfig,
) -> WearableIngestReport {
let accepted = []
let notices = []
let mut duplicates = 0
let mut out_of_order = 0
let mut low_quality = 0
let mut invalid = 0
let mut gaps = 0
for i in 0.. 0 {
let previous = accepted[accepted.length() - 1]
if wearable_samples_are_duplicate(previous, sample) &&
config.reject_duplicates {
duplicates += 1
add_ingest_notice(
notices,
i,
"duplicate_sample",
"sample has the same transport identity as the previous event",
"warning",
Duplicate,
)
continue
}
if sample.timestamp_seconds < previous.timestamp_seconds {
out_of_order += 1
if !config.allow_out_of_order {
add_ingest_notice(
notices,
i,
"out_of_order",
"sample timestamp precedes the last accepted event",
"error",
OutOfOrder,
)
continue
}
}
if wearable_gap_detected(
previous.timestamp_seconds,
sample.timestamp_seconds,
config.maximum_gap_seconds,
) {
gaps += 1
add_ingest_notice(
notices,
i,
"timestamp_gap",
"timestamp gap exceeds the configured transport interval",
"warning",
Accepted,
)
}
}
accepted.push(sample)
}
let duration = if accepted.length() < 2 {
0.0
} else {
accepted[accepted.length() - 1].timestamp_seconds -
accepted[0].timestamp_seconds
}
let duration_ok = config.maximum_duration_seconds <= 0.0 ||
duration <= config.maximum_duration_seconds
let quality_ratio = if input.length() == 0 {
0.0
} else {
accepted.length().to_double() / input.length().to_double()
}
{
samples: accepted,
notices,
accepted_count: accepted.length(),
rejected_count: input.length() - accepted.length(),
duplicate_count: duplicates,
out_of_order_count: out_of_order,
low_quality_count: low_quality,
invalid_count: invalid,
gap_count: gaps,
duration_seconds: if duration_ok {
duration
} else {
0.0
},
quality_ratio,
complete: duration_ok && invalid == 0 && out_of_order == 0,
}
}
///|
/// Sort a batch by timestamp while preserving deterministic tie order.
pub fn sort_wearable_samples(
samples : Array[WearableSample],
) -> Array[WearableSample] {
let result = []
for sample in samples {
result.push(sample)
}
result.sort_by((left, right) => {
if left.timestamp_seconds < right.timestamp_seconds {
-1
} else if left.timestamp_seconds > right.timestamp_seconds {
1
} else if left.sequence_number < right.sequence_number {
-1
} else if left.sequence_number > right.sequence_number {
1
} else {
0
}
})
result
}
///|
/// Ingest after ordering a device batch by timestamp.
pub fn ingest_sorted_wearable_samples(
input : Array[WearableSample],
config : WearableIngestConfig,
) -> WearableIngestReport {
ingest_wearable_samples(sort_wearable_samples(input), config)
}
///|
/// Return the accepted RR stream in milliseconds.
pub fn wearable_rr_intervals(report : WearableIngestReport) -> Array[Double] {
let result = []
for sample in report.samples {
if sample.rr_ms > 0.0 && wearable_finite(sample.rr_ms) {
result.push(sample.rr_ms)
}
}
result
}
///|
/// Return accepted timestamps in seconds.
pub fn wearable_timestamps(report : WearableIngestReport) -> Array[Double] {
let result = []
for sample in report.samples {
result.push(sample.timestamp_seconds)
}
result
}
///|
/// Return the average quality of accepted events.
pub fn wearable_mean_quality(report : WearableIngestReport) -> Double {
if report.samples.length() == 0 {
0.0
} else {
let values = []
for sample in report.samples {
values.push(wearable_quality_weight(sample.signal_quality))
}
mean_value(values)
}
}
///|
/// Return whether an ingestion report has enough accepted cardiac events.
pub fn wearable_ingest_is_usable(
report : WearableIngestReport,
minimum_samples : Int,
) -> Bool {
report.accepted_count >=
(if minimum_samples < 0 { 0 } else { minimum_samples }) &&
report.quality_ratio > 0.0 &&
report.duration_seconds >= 0.0 &&
report.invalid_count == 0
}
///|
/// Split accepted samples at timestamp gaps.
pub fn split_wearable_gaps(
samples : Array[WearableSample],
maximum_gap_seconds : Double,
) -> Array[Array[WearableSample]] {
let result = []
if samples.length() == 0 {
return result
}
let current = []
current.push(samples[0])
for i in 1.. Array[TelemetryWindow] {
let result = []
if samples.length() == 0 || window_seconds <= 0.0 || step_seconds <= 0.0 {
return result
}
let segments = split_wearable_gaps(samples, maximum_gap_seconds)
let mut ordinal = 0
for segment in segments {
if segment.length() == 0 {
continue
}
let start = segment[0].timestamp_seconds
let mut cursor = start
let end = segment[segment.length() - 1].timestamp_seconds
while cursor <= end {
let window_end = cursor + window_seconds
let selected = []
for sample in segment {
if sample.timestamp_seconds >= cursor &&
sample.timestamp_seconds < window_end {
selected.push(sample)
}
}
if selected.length() > 0 {
let rr = []
let qualities = []
for sample in selected {
if sample.rr_ms > 0.0 && wearable_finite(sample.rr_ms) {
rr.push(sample.rr_ms)
}
qualities.push(wearable_quality_weight(sample.signal_quality))
}
result.push({
ordinal,
start_seconds: cursor,
end_seconds: window_end,
samples: selected,
rr_intervals: rr,
mean_quality: mean_value(qualities),
gap_count: 0,
complete: cursor + window_seconds <= end + step_seconds,
})
ordinal += 1
}
cursor += step_seconds
}
}
result
}
///|
/// Return the window with the strongest quality-weighted sample count.
pub fn best_telemetry_window(
windows : Array[TelemetryWindow],
) -> TelemetryWindow? {
if windows.length() == 0 {
return None
}
let mut best = windows[0]
let mut best_score = best.mean_quality *
best.rr_intervals.length().to_double()
for window in windows {
let score = window.mean_quality * window.rr_intervals.length().to_double()
if score > best_score {
best = window
best_score = score
}
}
Some(best)
}
///|
/// Return the number of usable cardiac samples in a window.
pub fn telemetry_window_sample_count(window : TelemetryWindow) -> Int {
window.rr_intervals.length()
}
///|
/// Return the fraction of windows that contain a usable RR stream.
pub fn telemetry_window_coverage(windows : Array[TelemetryWindow]) -> Double {
if windows.length() == 0 {
0.0
} else {
let mut usable = 0
for window in windows {
if window.rr_intervals.length() > 1 && window.mean_quality > 0.0 {
usable += 1
}
}
usable.to_double() / windows.length().to_double()
}
}
///|
/// Produce a compact quality vector for downstream model tables.
pub fn wearable_ingest_feature_vector(
report : WearableIngestReport,
) -> Array[Double] {
[
report.samples.length().to_double(),
report.accepted_count.to_double(),
report.rejected_count.to_double(),
report.duplicate_count.to_double(),
report.out_of_order_count.to_double(),
report.low_quality_count.to_double(),
report.invalid_count.to_double(),
report.gap_count.to_double(),
report.duration_seconds,
report.quality_ratio,
wearable_mean_quality(report),
]
}
///|
/// Serialize a report suitable for a log line or a metrics endpoint.
pub fn wearable_ingest_csv(report : WearableIngestReport) -> String {
to_csv([
[
"accepted", "rejected", "duplicates", "out_of_order", "low_quality", "invalid",
"gaps", "duration_seconds", "quality_ratio", "complete",
],
[
report.accepted_count.to_string(),
report.rejected_count.to_string(),
report.duplicate_count.to_string(),
report.out_of_order_count.to_string(),
report.low_quality_count.to_string(),
report.invalid_count.to_string(),
report.gap_count.to_string(),
report.duration_seconds.to_string(),
report.quality_ratio.to_string(),
report.complete.to_string(),
],
])
}
///|
/// A compact state for an incremental ingest loop.
pub(all) struct IngestCursor {
mut last_timestamp_seconds : Double
mut accepted_count : Int
mut rejected_count : Int
mut gap_count : Int
mut quality_sum : Double
mut finished : Bool
} derive(FromJson, ToJson, Debug, Eq)
///|
/// Create an empty cursor for a streaming adapter.
pub fn IngestCursor::new() -> IngestCursor {
{
last_timestamp_seconds: -1.0,
accepted_count: 0,
rejected_count: 0,
gap_count: 0,
quality_sum: 0.0,
finished: false,
}
}
///|
/// Add one sample to a cursor without retaining the raw stream.
pub fn IngestCursor::push(
self : IngestCursor,
sample : WearableSample,
config : WearableIngestConfig,
) -> IngestNotice? {
if self.finished {
return Some({
index: self.accepted_count + self.rejected_count,
code: "finished_cursor",
message: "samples cannot be added after finish",
severity: "error",
disposition: Invalid,
})
}
let normalized = normalize_wearable_sample(sample, config)
if !wearable_sample_is_valid(normalized.sample, config) {
self.rejected_count += 1
Some({
index: self.accepted_count + self.rejected_count - 1,
code: "invalid_sample",
message: "sample failed cursor validation",
severity: "error",
disposition: Invalid,
})
} else if self.last_timestamp_seconds >= 0.0 &&
normalized.sample.timestamp_seconds < self.last_timestamp_seconds {
self.rejected_count += 1
Some({
index: self.accepted_count + self.rejected_count - 1,
code: "out_of_order",
message: "cursor requires monotonic timestamps",
severity: "error",
disposition: OutOfOrder,
})
} else {
if self.last_timestamp_seconds >= 0.0 &&
wearable_gap_detected(
self.last_timestamp_seconds,
normalized.sample.timestamp_seconds,
config.maximum_gap_seconds,
) {
self.gap_count += 1
}
self.last_timestamp_seconds = normalized.sample.timestamp_seconds
self.accepted_count += 1
self.quality_sum += wearable_quality_weight(
normalized.sample.signal_quality,
)
None
}
}
///|
/// Mark a cursor complete and freeze further updates.
pub fn IngestCursor::finish(self : IngestCursor) -> Unit {
self.finished = true
}
///|
/// Return the mean quality observed by a cursor.
pub fn IngestCursor::mean_quality(self : IngestCursor) -> Double {
if self.accepted_count == 0 {
0.0
} else {
self.quality_sum / self.accepted_count.to_double()
}
}
///|
/// Return a compact cursor feature vector.
pub fn IngestCursor::feature_vector(self : IngestCursor) -> Array[Double] {
[
self.accepted_count.to_double(),
self.rejected_count.to_double(),
self.gap_count.to_double(),
self.mean_quality(),
if self.finished {
1.0
} else {
0.0
},
]
}