# How VitalSignStore Uses Welford Running Statistics for Clinical Alerts in RuView

> Discover how VitalSignStore leverages Welford running statistics within RuView for real-time clinical alerts. Learn about seamless vital-sign monitoring and anomaly detection implemented by VitalAnomalyDetector.

- Repository: [rUv/RuView](https://github.com/ruvnet/RuView)
- Tags: how-to-guide
- Published: 2026-03-08

---

**VitalSignStore maintains a ring buffer of raw vital-sign readings while VitalAnomalyDetector applies Welford's online algorithm to compute running mean and variance for real-time z-score-based clinical alerting in the RuView monitoring system.**

The RuView project (`ruvnet/RuView`) implements contactless vital sign monitoring using WiFi CSI signals. At the core of its alerting pipeline, the system decouples data retention from statistical analysis: `VitalSignStore` handles raw history for visualization, while `VitalAnomalyDetector` leverages Welford running statistics to detect anomalies without retaining complete datasets.

## Architecture of VitalSignStore and Clinical Alert Detection

### VitalSignStore: The Raw Data Ring Buffer

Located in [`src/store.rs`](https://github.com/ruvnet/RuView/blob/main/src/store.rs), `VitalSignStore` functions as a lightweight ring buffer that retains the most recent vital-sign readings (respiratory rate and heart rate). It provides simple aggregate functions—count, mean, min/max, and valid-fraction—but **does not** perform statistical smoothing or anomaly detection itself.

This design keeps the store agnostic to specific analytics methods, allowing it to serve UI visualization and retrospective analysis while remaining reusable for diverse downstream consumers.

### VitalAnomalyDetector: Welford Statistics Engine

The `VitalAnomalyDetector` in [`src/anomaly.rs`](https://github.com/ruvnet/RuView/blob/main/src/anomaly.rs) transforms the raw stream from `VitalSignStore` into clinical alerts. For each incoming `VitalReading`, the detector:

- Pushes the reading into `VitalSignStore` to maintain history for UI visualization
- Updates two **Welford running statistics** accumulators—`rr_stats` for respiratory rate and `hr_stats` for heart rate
- Computes a **z-score** using the running mean and variance
- Triggers an `AnomalyAlert` if the z-score exceeds configurable thresholds or if hard clinical bounds are crossed (e.g., respiratory rate < 4 BPM indicating apnea)

## How Welford Running Statistics Work in RuView

The Welford algorithm provides numerically stable, low-memory statistics critical for continuous bedside monitoring. In [`src/anomaly.rs`](https://github.com/ruvnet/RuView/blob/main/src/anomaly.rs), the `WelfordStats` struct tracks three floating-point values per vital sign:

- `count`: Number of observations processed
- `mean`: Running mean of values
- `m2`: Sum of squares of differences from the current mean (used to derive variance)

When a new reading arrives, the detector updates the statistics in O(1) time:

```rust
// Based on src/anomaly.rs WelfordStats implementation
impl WelfordStats {
    pub fn update(&mut self, x: f64) {
        self.count += 1;
        let delta = x - self.mean;
        self.mean += delta / self.count as f64;
        let delta2 = x - self.mean;
        self.m2 += delta * delta2;
    }
    
    pub fn variance(&self) -> f64 {
        if self.count < 2 {
            0.0
        } else {
            self.m2 / (self.count - 1) as f64
        }
    }
}

```

This approach avoids catastrophic cancellation errors that plague naive incremental averaging, particularly when processing thousands of samples at ~1 Hz sampling rates over long monitoring sessions.

## Clinical Alert Detection Logic

The `VitalAnomalyDetector` combines Welford-derived statistics with clinical domain knowledge to generate actionable alerts. The detection pipeline evaluates two criteria:

**Statistical Outliers**: The system calculates z-scores using the running mean and standard deviation from the Welford accumulators. When `|z-score| > threshold` (typically 2.5), the detector flags the reading as statistically anomalous.

**Hard Clinical Bounds**: Regardless of variance, the system enforces absolute physiological limits. For example, respiratory rates below 4 BPM trigger immediate apnea alerts, while extreme bradycardia or tachycardia thresholds generate priority alerts.

When triggered, the detector emits `AnomalyAlert` structures containing the vital type, anomaly classification, severity clamped to [0, 1], and human-readable messages for clinician notification systems.

## Implementation Example

The following example demonstrates integrating `VitalSignStore` with `VitalAnomalyDetector` using Welford running statistics:

```rust
use wifi_densepose_vitals::{
    store::VitalSignStore,
    anomaly::{VitalAnomalyDetector, AnomalyAlert},
    types::{VitalReading, VitalEstimate, VitalStatus},
};

// Initialize 1-hour ring buffer (~3600 samples at 1 Hz)
let mut store = VitalSignStore::default_capacity();

// Detector with default Welford accumulators and z-score threshold of 2.5
let mut detector = VitalAnomalyDetector::default_config();

// Simulated CSI-derived vital sign reading
let reading = VitalReading {
    respiratory_rate: VitalEstimate {
        value_bpm: 12.0,
        confidence: 0.9,
        status: VitalStatus::Valid,
    },
    heart_rate: VitalEstimate {
        value_bpm: 78.0,
        confidence: 0.9,
        status: VitalStatus::Valid,
    },
    subcarrier_count: 56,
    signal_quality: 0.95,
    timestamp_secs: 0.0,
};

// Store raw reading for UI visualization and retrospective analysis
store.push(reading.clone());

// Run anomaly detection using Welford statistics
let alerts: Vec<AnomalyAlert> = detector.check(&reading);

for alert in alerts {
    println!(
        "[ALERT] {} – {} (severity {:.2}) – {}",
        alert.vital_type, alert.alert_type, alert.severity, alert.message
    );
}

```

To reset the Welford accumulators after patient hand-offs or calibration changes:

```rust
detector.reset();  // Clears rr_stats and hr_stats Welford accumulators
store.clear();     // Optionally clear stored readings

```

Accessing the running means for custom downstream logic:

```rust
let current_rr_mean = detector.rr_mean();  // Welford-derived respiratory rate mean
let current_hr_mean = detector.hr_mean();  // Welford-derived heart rate mean

```

## Summary

- **VitalSignStore** in [`src/store.rs`](https://github.com/ruvnet/RuView/blob/main/src/store.rs) maintains a ring buffer of raw vital-sign readings for visualization and retrospective analysis, but does not perform statistical processing.
- **VitalAnomalyDetector** in [`src/anomaly.rs`](https://github.com/ruvnet/RuView/blob/main/src/anomaly.rs) implements **Welford running statistics** via `rr_stats` and `hr_stats` accumulators to compute online mean and variance in O(1) time per sample.
- The Welford algorithm provides numerical stability and memory efficiency (three floats per vital sign), essential for continuous monitoring at ~1 Hz sampling rates.
- Clinical alerts trigger based on **z-scores** derived from Welford statistics and **hard clinical bounds** (e.g., apnea thresholds), producing `AnomalyAlert` structures for downstream notification systems.

## Frequently Asked Questions

### What is the difference between VitalSignStore and VitalAnomalyDetector in RuView?

`VitalSignStore` functions as a ring buffer that retains raw vital-sign readings for UI visualization and basic aggregation (count, min/max, valid-fraction). It operates independently of statistical methods. `VitalAnomalyDetector` consumes these readings to perform real-time statistical analysis using Welford running statistics, generating clinical alerts when anomalies are detected. This decoupling allows the store to support diverse analytics workflows while the detector focuses on memory-efficient statistical monitoring.

### Why does RuView use Welford's algorithm instead of standard averaging?

Welford's online algorithm provides **numerical stability** that naive incremental averaging lacks, particularly when processing thousands of samples over long monitoring sessions. It avoids catastrophic cancellation errors by computing variance through differences from the running mean. Additionally, Welford requires only **O(1) memory** (three floats per vital sign: count, mean, and M2) and **O(1) time** per update, making it ideal for resource-constrained, high-frequency (~1 Hz) bedside monitoring in RuView.

### How are clinical alert thresholds configured in the anomaly detector?

The `VitalAnomalyDetector` applies a two-tier threshold system. First, it calculates **z-scores** using the Welford-derived mean and standard deviation, comparing these against configurable statistical thresholds (e.g., z-score > 2.5). Second, it enforces **hard clinical bounds** independent of variance, such as triggering apnea alerts when respiratory rate falls below 4 BPM. Alerts carry severity scores clamped to [0, 1] and human-readable messages for clinician notification systems.

### Can VitalSignStore retain data for retrospective analysis while the detector uses Welford statistics?

Yes, this is the intended architecture. `VitalSignStore` maintains a complete ring buffer of `VitalReading` structures for retrospective analysis, charting, and UI visualization. Simultaneously, `VitalAnomalyDetector` processes the same stream using Welford running statistics without storing the full history, enabling real-time alerting. The decoupled design allows the store to support diverse analytics workflows while the detector focuses on memory-efficient statistical monitoring.