import numpy as np from dataclasses import dataclass from typing import List, Dict @dataclass class WearableReading: hrv_ms: float # Heart Rate Variability in milliseconds sleep_hrs: float # Sleep duration in hours rhr_bpm: int # Resting Heart Rate in bpm steps: int # Daily step count class BurnoutBiomarker: BASELINES = {"hrv": 55, "sleep": 7.5, "rhr": 62, "steps": 8000} WEIGHTS = {"hrv": 0.35, "sleep": 0.25, "rhr": 0.25, "steps": 0.15} def personalise(self, user_readings: List[WearableReading]): """Override population baselines with user's own 30-day avg.""" if len(user_readings) >= 30: self.BASELINES["hrv"] = np.mean([r.hrv_ms for r in user_readings]) self.BASELINES["sleep"] = np.mean([r.sleep_hrs for r in user_readings]) self.BASELINES["rhr"] = np.mean([r.rhr_bpm for r in user_readings]) self.BASELINES["steps"] = np.mean([r.steps for r in user_readings]) def score_day(self, r: WearableReading) -> Dict: signals = { "hrv" : (self.BASELINES["hrv"] - r.hrv_ms) / self.BASELINES["hrv"], "sleep": (self.BASELINES["sleep"] - r.sleep_hrs) / self.BASELINES["sleep"], "rhr" : (r.rhr_bpm - self.BASELINES["rhr"]) / self.BASELINES["rhr"], "steps": (self.BASELINES["steps"] - r.steps) / self.BASELINES["steps"], } raw = sum(self.WEIGHTS[k] * max(0, v) for k,v in signals.items()) risk = round(min(100, raw * 100), 1) return {"risk": risk, "signals": signals} def rolling_risk(self, days: List[WearableReading]) -> float: return round(np.mean([self.score_day(d)["risk"] for d in days[-7:]]), 1) def interpret(self, score: float) -> str: if score >= 70: return "High — escalate to clinician" if score >= 45: return "Moderate — recommend check-in" return "Low — continue monitoring"
import fitbit, json, xml.etree.ElementTree as ET class FitbitConnector: def __init__(self, access_token: str): self.client = fitbit.Fitbit(access_token=access_token) def get_today(self) -> dict: hrv = self.client.intraday_time_series('activities/heart', detail_level='1min') sleep = self.client.get_sleep(date='today') steps = self.client.activities()['summary']['steps'] return {"hrv": hrv, "sleep": sleep["summary"]["totalTimeInBed"]/60, "steps": steps} class AppleHealthConnector: def parse_export(self, xml_path: str) -> list: tree = ET.parse(xml_path) records = tree.getroot().findall("Record") hrv_records = [r for r in records if r.get("type") == "HKQuantityTypeIdentifierHeartRateVariabilitySDNN"] return [{"value": float(r.get("value")), "date": r.get("startDate")} for r in hrv_records] # Option 3: WESAD academic dataset (free, validated) # archive.ics.uci.edu/dataset/465/wesad def load_wesad(subject_id: int) -> list: import pickle with open(f"WESAD/S{subject_id}/S{subject_id}.pkl", "rb") as f: data = pickle.load(f, encoding="latin1") return data["signal"]["wrist"]
VitalMind is a digital biomarker platform that detects early burnout risk using wearable signals — before a person consciously feels it.
It combines heart rate variability, sleep quality, resting heart rate and activity data into a single personalised risk score, updated daily.
Unlike population-based apps, VitalMind compares you against your own 30-day baseline — making it accurate for each individual.