Coach DrépanoCoach DrépanoCrise, forme et conseils
Transparence des algorithmes

Crise, forme et conseils

Le risque de crise, la baisse de forme, la forme du jour, les alertes et « Que faire maintenant ? ».

Chaque algorithme est décrit avec ce qu’il lit, ses étapes, les valeurs qu’il utilise (avec leur emplacement dans le code), ce qu’il affiche et ses limites.

Alertes de risque de crise et limite de notificationApprentissage du modèle personnel et de la cohorteForme du jour (récupération)Lignes de base et écarts à ta normaleQue faire maintenant ?Risque de baisse de formeSignaux de la montre et sources de température et de cœurTendance à la vasoconstriction (expérimental)

← Tous les algorithmes

Alertes de risque de crise et limite de notification

Si tu l'as activée, Trévor t'écrit chaque matin vers 8 h quand ton risque de crise atteint 70 % sur des mesures fraîches. Une alerte douce facultative existe dès 40 %. Il n'envoie jamais plus d'un message d'alerte par jour, et il retient le message pendant les heures calmes.

Où tu le vois : Message du bot reçu le matin (un message neutre avec un bouton « Ouvrir » sur l'écran verrouillé, puis le contenu), suivi d'un second message « Deux conseils pour maintenant ». Les boutons « Activer l'alerte du matin (si risque ≥ 70) » et « Me prévenir dès le risque modéré (40 %) » sont dans l'écran « Mon risque de crise ». Les soignants voient aussi une ligne d'alerte « Risque de crise calculé X % » dans le tableau de bord quand le score est de 70 ou plus.

Ce que l’algorithme lit

Le calcul, étape par étape

Passage du planificateur à 8 hLe contrôle se lance quand l'heure locale du groupe de fuseau vaut8On examine les personnes qui ont des données de montreAlerte activée, fonctionactive et pas déjà alertéeaujourd'hui ?ouinonOn calcule le risqueRien n'est envoyéLe risque existe-t-il et sesmesures sont-elles fraîches?ouinonFraîches : la dernière mesuredate de 2 jours ou moins, oule score ne repose que sur ledossierLe score du jour est quandmême mémorisé, mais aucunmessage ne partLe score atteint-il 70 ?ouinonAlerte « élevé » : bois,repose-toi au chaud, appelleton équipe ou le 144 si ladouleur monteOn teste le score de 40Score de 40 à 69 et alertedouce activée ?ouinonAlerte douce : « Ton risquede crise monte un peu », riend'alarmantAucun messageMarquer la journéeLa date du jour est enregistrée comme jour alerté avant l'envoiUn seul message d'alerte par jour, doux ou élevéComposer les deux messagesMessage 1 : score, niveau, signaux séparés par despoints-virgules, gestes, consignes d'urgenceMessage 2 : les 2 premiers gestes de « Que faire maintenant ? »,avec la sécurité d'abord s'il y a un signe d'urgenceMention : fonction expérimentale, pas un avis médicalC'est la nuit chez toi ?ouinonLe message est gardé et partà la fin des heures calmes ;abandonné si le jour local achangéIl part tout de suite,derrière un message neutreavec « Ouvrir »
Logigramme : Alertes de risque de crise et limite de notification

Les valeurs utilisées

Nom dans le codeValeurRôleOù
CRISIS_ALERT_THRESHOLD70Score à partir duquel l'alerte « élevé » partsrc/trevor/wearables/service.py:511
CRISIS_SOFT_THRESHOLD40Score à partir duquel l'alerte douce part, si tu l'as activéesrc/trevor/wearables/service.py:512
heure d'envoi8 h localesLe planificateur lance les alertes de risque quand l'heure locale du groupe de fuseau vaut 8src/trevor/conversation/reminders.py:808-810
last_alert_dateune fois par jourSi la date de la dernière alerte égale la date du jour de la personne, aucun nouvel envoisrc/trevor/wearables/service.py:1257, 1272
fraîcheurdernière mesure datée d'au plus 2 joursSans mesure fraîche, aucun message. Les scores calculés sans montre (dossier seul) comptent comme fraissrc/trevor/wearables/service.py:736, 763, 1263
alertes éteintes par défautalerts_enabled faux, soft_alert fauxIl faut activer l'alerte du matin, puis séparément l'alerte doucesrc/trevor/wearables/service.py:1179-1184 ; src/trevor/navigator/reco_flow.py:52-55
nombre de messages2 au plusLe message d'alerte et le message des deux conseils (omis si aucun geste n'est disponible)src/trevor/conversation/reminders.py:1544-1551
heures calmes par défaut22 h (inclus) à 7 h (exclu), heure localeFenêtre pendant laquelle les messages proactifs sont retenus. Tu peux la régler ou la coupersrc/trevor/localtime.py:182, 214-226
QUIET_DAILYinclut crisis_alertsUne alerte retenue la nuit est abandonnée si le jour local a changé au réveilsrc/trevor/conversation/reminders.py:99-103
budget d'attentioncrisis_alerts exemptéeLa limite commune de messages proactifs par jour (3 par défaut, si la fonction est activée) ne retient ni ne compte les alertes de crisesrc/trevor/conversation/attention_budget.py:26, 44-48
mode silencieux d'étudeaucune alerte pendant une étude LRHPendant l'étude TREVOR-PILOTE, le risque est calculé et enregistré mais jamais affiché ni alertésrc/trevor/wearables/service.py:1186-1190
ligne du tableau de bordscore ≥ 70 et fraisPour les soignants : « Risque de crise calculé X % (modèle …) » avec 3 explications au plussrc/trevor/dashboard/data.py:653-655

Ce qui est affiché

Au plus un message d'alerte par jour. Alerte « élevé » (score de 70 ou plus) : « Risque de crise ce matin : X % (élevé). Signaux : … », puis des gestes (boire environ 1,5 à 2 litres, se reposer au chaud, éviter les efforts intenses) et les cas où contacter l'équipe soignante ou appeler le 144 (douleur qui monte, fièvre au seuil, essoufflement). Alerte douce (de 40 à 69, si activée) : « Ton risque de crise monte un peu : X % ce matin (modéré). Signaux : … », avec la phrase « Rien d'alarmant à ce stade ». Les deux messages se terminent par « Cette fonction est expérimentale et ne vaut pas avis médical ». Le second message donne les deux premiers gestes de « Que faire maintenant ? ».

Un exemple chiffré

Score du matin à 72 %, mesures datées d'hier, alerte du matin activée, aucune alerte envoyée aujourd'hui : le score atteint 70, le message « élevé » part, et la date du jour est enregistrée. À 8 h 30, aucun second message ne part même si le score monte à 85. Autre cas : 45 % sans alerte douce activée, aucun message. Avec l'alerte douce activée, le message doux part. Autre cas : 75 % mais mesures de 4 jours, rien ne part. Aucun résultat chiffré n'a été exécuté : les cas viennent des conditions de due_alerts.

Ce que cet algorithme ne sait pas faire

Validation. Les seuils de 70 et de 40 ont été posés par le concepteur : le code les présente comme des seuils d'alerte, et rien dans le dépôt ne les relie à des crises observées, à une sensibilité ou à un taux de fausses alertes. Le choix d'un message par jour, de l'envoi à 8 h, des heures calmes de 22 h à 7 h et de l'alerte douce éteinte par défaut relève de choix de conception du produit (limiter la fatigue d'alertes), non d'une étude. Le score lui-même hérite des limites du risque de crise. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/service.py (CRISIS_ALERT_THRESHOLD, CRISIS_SOFT_THRESHOLD, due_alerts, alerts_enabled, set_alerts, silent_mode, interpretation_source), src/trevor/conversation/reminders.py (crisis_alerts, _deliver, QUIET_DAILY, tick à 8 h), src/trevor/conversation/push_gate.py (hold_if_quiet, push_gated), src/trevor/conversation/attention_budget.py (EXEMPT), src/trevor/localtime.py (is_quiet, QUIET_DEFAULT), src/trevor/navigator/reco_flow.py (soft_alert_enabled, alert_lines), src/trevor/dashboard/data.py (wearable_alerts), data/i18n/fr.json (textCrisisAlertMessage, textCrisisAlertSoft, textCrisisAlertsEnabled, textCrisisAlertsSoftEnabled)

Apprentissage du modèle personnel et de la cohorte

Chaque nuit, Trévor peut entraîner un modèle de régression logistique sur tes propres jours, puis un modèle commun à toutes les personnes suivies. Les poids de départ viennent d'un a priori clinique, et l'entraînement ne les éloigne que si tes données le justifient. Au moment du calcul, les modèles qui ont fait leurs preuves se mélangent avec l'a priori.

Où tu le vois : Dans l'écran « Mon risque de crise », le bloc « Fiabilité du modèle » dit si le calcul part de repères cliniques, de la cohorte ou de tes données (nombre de jours, nombre d'épisodes de crise, AUROC en validation temporelle).

Ce que l’algorithme lit

Le calcul, étape par étape

Construire les jours d'entraînementLes 180 derniers jours, un vecteur d'écarts par jourL'état des traitements est reconstitué jour par jourÉtiqueter chaque jourÉtiquette = 1 si une crise a lieu ce jour-là ou l'un des 2 jourssuivantsSinon 0Assez de données pour unmodèle personnel ?ouinonAu moins 60 jours et 4 joursétiquetés crise : on entraînePas de modèle personnel : l'apriori reste en placeRégression logistique régulariséeLes poids partent de l'a priori clinique400 tours de descente de gradient, pas 0,05Rappel de chaque poids vers l'a priori (L2 = 0,5)Les jours de crise pèsent (jours calmes / jours de crise) foisplusValidation croisée par blocs de tempsAu moins 30 jours et 3 crises4 blocs contigus : chacun sert de test, les 3 autresd'entraînement (200 tours)AUROC calculée sur tous les scores de test réunisModèle personnelTes jours seulementEnregistré avec son AUROCModèle de cohorteTous les jours de toutes lespersonnes suivies, triés pardateAu moins 60 jours et 5 crisesEnregistré avec son AUROCLe modèle est-il retenu aumoment du calcul ?ouinonPersonnel : 4 crises ou pluset AUROC de 0,65 ou plus.Cohorte : 5 crises ou plus etAUROC de 0,6 ou plusLe modèle est mis de côté,sans messageMélange des modèlesA priori : poids 1Cohorte : poids min(4 ; crises / 5)Personnel : poids min(6 ; crises / 2)La somme des logits pondérés est divisée par la somme des poidsPoids amplifiés au calculChaque poids est multiplié par 1,6, sauf les protectionsLe biais ne bouge pasLe reste du calcul est décrit sur la page publique du risque decrise
Logigramme : Apprentissage du modèle personnel et de la cohorte

Les valeurs utilisées

Nom dans le codeValeurRôleOù
jours d'entraînement180Historique relu pour entraîner (training_rows, days=180)src/trevor/wearables/service.py:617
seuil de douleur de crisepain_intensity ≥ 7Un jour est étiqueté crise quand la douleur déclarée du suivi atteint 7/10, ou si une hospitalisation est déclaréesrc/trevor/wearables/service.py:553
observation de conversationintensité ≥ 7 et mot parmi crise, urgence, hospital, cvo, vasoUne observation de conversation compte comme crise si son intensité est de 7 ou plus et si son texte contient un de ces motssrc/trevor/wearables/service.py:513, 568-572
journal des criseschaque jour d'un épisode déclaréChaque jour entre le début et la fin d'un épisode déclaré (jusqu'à aujourd'hui si en cours) est une crise certainesrc/trevor/wearables/service.py:573-587
HORIZON_DAYS2Le jour est positif si une crise survient aujourd'hui, demain ou après-demain (boucle de 0 à 2 jours inclus)src/trevor/wearables/crisis.py:123, 413-419
minimum du modèle personnel60 jours et 4 crisesEn dessous, train_user ne produit riensrc/trevor/wearables/service.py:662
minimum du modèle de cohorte60 jours et 5 crisesEn dessous, train_cohort ne produit riensrc/trevor/wearables/service.py:677
l20,5Force du rappel de chaque poids vers sa valeur a priori (le biais n'est pas rappelé)src/trevor/wearables/crisis.py:433, 453
epochs / lr400 tours ; pas 0,05 (200 tours en validation)Descente de gradient sur l'ensemble des jours, sans bibliothèque externesrc/trevor/wearables/crisis.py:433, 482
pos_weight(jours sans crise) / (jours de crise)Les jours de crise comptent davantage dans le gradient pour compenser leur raretésrc/trevor/wearables/crisis.py:442-448
validation croisée4 blocs, au moins 30 jours et 3 crisesBlocs temporels contigus ; sans ces minimums, l'AUROC reste videsrc/trevor/wearables/crisis.py:470-485
seuil d'usage du modèle personneln_events ≥ 4 et AUROC ≥ 0,65Sans AUROC calculée, le modèle n'est pas retenusrc/trevor/wearables/crisis.py:508
seuil d'usage du modèle de cohorten_events ≥ 5 et AUROC ≥ 0,6Seuil d'AUROC de la cohorte, plus bas que celui du modèle personnelsrc/trevor/wearables/crisis.py:506
poids de mélangea priori 1 ; cohorte min(4 ; crises/5) ; personnel min(6 ; crises/2)Plus il y a de crises observées, plus le modèle pèse, jusqu'à un plafondsrc/trevor/wearables/crisis.py:505-509
RISK_GAIN1,6Multiplicateur appliqué à tous les poids du calcul, sauf hu_protect, dmt_other, tx_recent et tx_protectsrc/trevor/wearables/crisis.py:494-500
PRIOR_BIAS−2,2Environ 10 % de risque de base quand tout est normalsrc/trevor/wearables/crisis.py:120
RISK_MAX0,99Le risque ne dépasse jamais 99 %src/trevor/wearables/crisis.py:493

Les poids

Un poids positif augmente le résultat, un poids négatif le diminue.

SignalPoidsOù
Douleur déclarée récente (a priori)+0,9src/trevor/wearables/crisis.py:83
Fièvre déclarée (a priori)+0,8src/trevor/wearables/crisis.py:90
Difficultés à respirer déclarées (a priori)+1,0src/trevor/wearables/crisis.py:90
SpO2 sous 92 % (a priori)+0,8src/trevor/wearables/crisis.py:83
SpO2 vs ta normale (a priori)−0,6src/trevor/wearables/crisis.py:81
FC repos vs ta normale (a priori)+0,55src/trevor/wearables/crisis.py:81
HRV vs ta normale (a priori)−0,45src/trevor/wearables/crisis.py:81
Crise dans les 7 derniers jours (a priori)+0,6src/trevor/wearables/crisis.py:83
Transfusion récente (a priori, non amplifié)−3,0src/trevor/wearables/crisis.py:78
Transfusion qui tient encore (a priori, non amplifié)−2,0src/trevor/wearables/crisis.py:78
Effet de la transfusion qui s'estompe (a priori)+1,4src/trevor/wearables/crisis.py:78
Transfusion en retard (a priori)+0,8src/trevor/wearables/crisis.py:93
Creux d'oxygène de la nuit en valeur absolue (a priori)+0,7src/trevor/wearables/crisis.py:97
Hémoglobine basse (a priori)+0,5src/trevor/wearables/crisis.py:93

Ce qui est affiché

Deux modèles enregistrés (le tien et celui de la cohorte), chacun avec ses poids, son biais, son nombre de jours, son nombre de crises et son AUROC en validation croisée temporelle. Au moment du calcul, la liste des modèles retenus et leurs poids de mélange. L'écran affiche l'origine du calcul : « repères cliniques » (a priori seul), « ajusté sur la cohorte » ou « ajusté sur tes données », avec jours, épisodes et AUROC.

Un exemple chiffré

Un modèle personnel avec 8 crises et une AUROC de 0,70, et un modèle de cohorte avec 10 crises et une AUROC de 0,62. Les deux passent leur seuil (4 crises et 0,65 ; 5 crises et 0,6). Les poids de mélange sont a priori 1,0, cohorte min(4 ; 10/5) = 2,0 et personnel min(6 ; 8/2) = 4,0, soit une part de 4/7 pour le modèle personnel. Si l'AUROC personnelle n'était que de 0,60, le modèle personnel serait écarté et seuls l'a priori (1,0) et la cohorte (2,0) resteraient. Vérifié en exécutant blend() du dépôt (résultat : prior 1.0, cohort 2.0, personal 4.0).

Ce que cet algorithme ne sait pas faire

Validation. Les poids de départ (a priori) sont posés d'après la littérature et le jugement du concepteur, et le code le dit : poids « modestes », associations et non causalité, « non validé, à revoir avec les crises observées ». Le gain de 1,6 a été calibré sur un cas rapporté, et le code précise qu'il est « à revoir avec les crises réellement observées (cohorte, étude 1) ». Les poids personnels et de cohorte sont appris sur les données, régularisés vers l'a priori. Les seuils d'usage (AUROC de 0,65 pour toi, 0,6 pour la cohorte, 4 et 5 crises minimum) sont arbitraires : rien dans le dépôt ne les justifie par une étude. Le texte d'en-tête du code et la page publique parlent d'un seuil de 0,65 pour les deux, mais le code applique 0,6 à la cohorte. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/crisis.py (build_features, train_logistic, auc_score, evaluate_blocked, blend, amplified, PRIOR_WEIGHTS), src/trevor/wearables/service.py (day_records, training_rows, _treatment_history, train_user, train_cohort, train_everyone, _stored_model)

Forme du jour (récupération)

La forme du jour est un repère de récupération sur 100, à la manière d'un score d'Oura. Trévor affiche tel quel le score que donne ton appareil quand il existe. Sinon il calcule le sien à partir de ton sommeil, de ta variabilité cardiaque (HRV) et de ton cœur au repos, comparés à ta normale.

Où tu le vois : Écran « Ma forme du jour » (commande /forme, ou Ma santé > Forme, risque, hémoglobine), tuile « Forme du jour » de Ma santé, écran Mesures et estimations, écran Ma santé de la montre. Le texte donne un pourcentage, un niveau (bonne, moyenne, basse), la source (score de l'appareil ou estimation Trévor), jusqu'à 2 facteurs, un conseil du jour et la mention que ce n'est pas un avis médical.

Ce que l’algorithme lit

Le calcul, étape par étape

Prendre les 35 derniers joursSérie quotidienne triée par dateOn part du jour le plus récent et on remonteL'appareil donne-t-il unscore ce jour-là ?ouinonScore arrondi et borné de 0 à100, source « device »Trévor calcule son proprescore (étapes suivantes)Le calcul est-il possible ?ouinonInterprétation activée, aumoins 2 des 3 mesures du jouravec une ligne de base, aumoins 7 jours avantOn essaie le jour précédent,et ainsi de suiteÉcart de chaque mesure à ta normalez robuste (médiane et MAD des 30 jours précédents), borné à ±2Sommeil et HRV : haut = mieuxFC au repos : le z est inversé (haut = moins bien)Sans mesure du sommeil, la nuit déclarée la remplace : bonne +1,moyenne 0, mauvaise −1Moyenne pondéréeSommeil 0,40 ; HRV 0,35 ; FC repos 0,25Seules les mesures présentes comptent : les poids sont ramenés à 1score = 50 + moyenne × 15, borné de 0 à 100Score calculé de plus de 2jours ?ouinonIl n'est pas affichéIl est retenu et marqué «frais »Niveau et facteurs66 ou plus : bonne. De 40 à 65 : moyenne. Moins de 40 : basseFacteurs : la nuit déclarée si elle a pesé, puis les 2 mesuresdont l'écart est le plus grand en valeur absolue (au moins 0,5)AffichagePourcentage, niveau, source, facteurs, conseil du niveau,avertissementSeule une forme « fraîche » (2 jours ou moins) s'affiche
Logigramme : Forme du jour (récupération)

Les valeurs utilisées

Nom dans le codeValeurRôleOù
WEIGHTSsommeil 0,40 ; HRV 0,35 ; FC repos 0,25Poids des trois composantes du score calculé (somme 1)src/trevor/wearables/readiness.py:27
BASELINE_DAYS30Jours précédents qui forment la ligne de basesrc/trevor/wearables/readiness.py:23
FRESH_DAYS2Âge maximal d'un score calculé pour être affiché ; un score d'appareil plus ancien reste affiché mais non « frais »src/trevor/wearables/readiness.py:24, 88
séries lues35 joursLongueur de la série passée à compute_readinesssrc/trevor/wearables/service.py:1199
bornes du z−2 à +2Chaque écart est limité à ±2 avant la moyennesrc/trevor/wearables/readiness.py:86
pente du score50 + moyenne × 15Une moyenne de +2 donne 80 ; −2 donne 20src/trevor/wearables/readiness.py:87
niveau bon / moyen / bas≥ 66 / 40 à 65 / < 40Seuils des niveauxsrc/trevor/wearables/readiness.py:36-37
nombre minimal de composantes2Avec moins de deux mesures ce jour-là, le jour est écarté (corrigé en 2.200.2 : avant, un jour sans mesure donnait 50 %)src/trevor/wearables/readiness.py:55-57, 83
MIN_BASELINE7Jours minimaux avant le jour choisi, et valeurs minimales par mesuresrc/trevor/wearables/crisis.py:122
SELF_SLEEP_Zbonne +1,0 ; moyenne 0,0 ; mauvaise −1,0Valeur donnée à la nuit déclarée quand la montre n'a pas mesuré le sommeilsrc/trevor/navigator/sleep.py:26
seuil d'affichage d'un facteur|z| ≥ 0,5, 2 facteurs au plusUn facteur plus faible n'est pas nommésrc/trevor/wearables/readiness.py:96-101

Les poids

Un poids positif augmente le résultat, un poids négatif le diminue.

SignalPoidsOù
Sommeil plus long que ta normale+0,40src/trevor/wearables/readiness.py:27
HRV plus haute que ta normale+0,35src/trevor/wearables/readiness.py:27
FC au repos plus basse que ta normale+0,25src/trevor/wearables/readiness.py:27, 80

Ce qui est affiché

Un score de 0 à 100 (en pourcentage), un niveau (bonne à partir de 66, moyenne de 40 à 65, basse sous 40), une source (« device » ou « computed »), jusqu'à 2 facteurs en phrases (par exemple « Nuit plus courte que d'habitude », « Ton cœur au repos est un peu élevé »), la date et l'indication « frais ». Le conseil dépend du niveau : bonne (belle forme, garde tes bons réflexes), moyenne (à ton rythme, hydrate-toi, garde de la marge), basse (repose-toi, hydrate-toi, ménage tes efforts, évite le froid). Le texte précise que ce n'est pas un avis médical et ne remplace ni ton ressenti ni ton équipe de soins. Quand rien ne s'affiche, une phrase donne la cause : pas de montre, mode silencieux, avertissement à accepter, moins de 7 jours de référence, mesures trop anciennes ou trop peu nombreuses.

Un exemple chiffré

Vingt jours de référence : sommeil autour de 430 min (médiane 430, dispersion 30 par le plancher), HRV médiane 51,5 (dispersion 4), FC au repos médiane 60,5 (dispersion 2). Aujourd'hui : sommeil 360 min, HRV 44, FC 65. Les z sont −2,33 (borné −2), −1,875 et +2,25 pour la FC, inversé en −2,25 (borné −2). La moyenne pondérée vaut (0,40 × −2 + 0,35 × −1,875 + 0,25 × −2) / 1 = −1,96. Score = 50 + (−1,96 × 15) = 20,7, arrondi à 21 : niveau bas. Les deux facteurs affichés sont le sommeil (|z| 2,33) puis la FC (|z| 2,25) : « Nuit plus courte que d'habitude » et « Ton cœur au repos est un peu élevé ». Résultat vérifié en exécutant compute_readiness du dépôt.

Ce que cet algorithme ne sait pas faire

Validation. La méthode est inspirée des indicateurs de récupération du commerce (le code cite Oura et Body Battery de Garmin comme modèles), mais le calcul de Trévor est propre à Trévor. Les poids (0,40 ; 0,35 ; 0,25), la pente (15), les seuils de niveau (66 et 40) et les bornes ±2 sont posés sans étude de validation dans le dépôt. Le code précise que c'est un indicateur de forme et de récupération, « jamais un avis médical ni un prédicteur de crise ». Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/readiness.py (compute_readiness, _usable, _level, WEIGHTS, DRIVER_LABEL), src/trevor/wearables/service.py (readiness_today), src/trevor/conversation/wearables_screen.py (_readiness_lines, screen_readiness), src/trevor/lifecourse/health_view.py (_form_reason, _form_tile, EMPTY_NOTE), src/trevor/signals.py (build), src/trevor/wearables/watch_summary.py (_health), data/i18n/fr.json (textReadiness*)

Lignes de base et écarts à ta normale

Trévor compare chaque mesure de ta montre ou de ta bague à ce qui est habituel pour toi, et non à une norme générale. Pour cela il calcule une médiane et un écart absolu médian (MAD) sur tes jours précédents, puis transforme l'écart du jour en z-score robuste et en tendance sur 3 jours. Ces écarts sont la matière première du risque de crise, du risque de baisse de forme et de la forme du jour.

Où tu le vois : Jamais affiché sous forme de chiffre brut. Les écarts apparaissent dans les phrases des écrans « Mon risque de crise » et « Ma forme du jour » (par exemple « Ton sommeil est plus court que d'habitude »), dans la liste des signaux qui pèsent le plus, et dans la phrase qui explique pourquoi une forme du jour manque.

Ce que l’algorithme lit

Le calcul, étape par étape

Rassembler les joursUn enregistrement par jour : mesures de la montre, douleur, crise,déclarationsLes jours sont triés par dateAu moins 7 jours avant cejour ?ouinonOn calcule les écarts de cejourLe jour est ignoré : aucunécart, aucun scoreFenêtre de référenceLes 30 enregistrements précédents (sans le jour lui-même)Pour chaque mesure : on garde les valeurs présentesAu moins 7 valeurs pourcette mesure ?ouinonMédiane et dispersion robustecalculéesPas de ligne de base pourcette mesure : son écart vaut0 (neutre)Médiane et MADmédiane = valeur du milieu des jours de référenceMAD = médiane des distances à cette médianedispersion = 1,4826 × MAD, jamais sous un plancher propre à lamesurez-score du jourz = (valeur du jour − médiane) / dispersionz borné entre −4 et +4Mesure absente aujourd'hui : z = 0Tendance sur 3 joursMoyenne des 3 derniers jours(aujourd'hui compris) de la FCrepos, de la HRV, du sommeilet de la respirationComparée à la même ligne debaseRepères simplesDouleur récente = plus fortedouleur des 3 derniers jours /10Crise dans les 7 joursprécédents : 0 ou 1SpO2 sous 92 % : 0 ou 1Température cutanée de +0,5 °Cou plus : 0 ou 1Nuit : mêmes calculs, sur tes nuitsOxygène moyen, creux, temps sous 90 %, chutes par heure,efficacité, réveils, sommeil profond, heure de coucherComparés à tes nuits des 30 jours précédents, au moins 7 nuitsmesuréesLe creux d'oxygène absolu (sous 90 %) compte même sans ligne debaseRésultat : un vecteur d'écartsCe vecteur part vers le risque de crise et le risque de baisse deformeLa forme du jour refait le même calcul pour 3 mesures
Logigramme : Lignes de base et écarts à ta normale

Les valeurs utilisées

Nom dans le codeValeurRôleOù
BASELINE_DAYS30Nombre d'enregistrements précédents qui forment la ligne de basesrc/trevor/wearables/crisis.py:121
MIN_BASELINE7Valeurs minimales d'une mesure pour calculer sa médiane, et enregistrements minimaux avant un jour pour qu'il ait des écartssrc/trevor/wearables/crisis.py:122
clip (borne du z-score)4,0Un écart ne compte jamais plus de 4 dispersions, dans un sens comme dans l'autresrc/trevor/wearables/crisis.py:179
facteur MAD1,4826Convertit le MAD en équivalent d'écart-type pour une distribution normalesrc/trevor/wearables/crisis.py:176
MIN_SD FC repos2,0 bpmPlancher de dispersion : évite qu'une ligne de base très stable transforme un petit écart en alertesrc/trevor/wearables/crisis.py:164
MIN_SD HRV4,0 msPlancher de dispersion de la variabilité cardiaquesrc/trevor/wearables/crisis.py:164
MIN_SD SpO20,7 pointPlancher de dispersion de la saturation en oxygènesrc/trevor/wearables/crisis.py:164
MIN_SD sommeil30 minPlancher de dispersion de la durée de sommeilsrc/trevor/wearables/crisis.py:164
MIN_SD pas1000 pasPlancher de dispersion de l'activitésrc/trevor/wearables/crisis.py:164
MIN_SD température, stress, respiration, bruit0,15 °C ; 5 ; 1,0 /min ; 5 dBPlanchers de dispersion des autres mesures du joursrc/trevor/wearables/crisis.py:164-165
MIN_SD FC la plus basse de la nuit2,0Plancher de dispersion de la fréquence cardiaque minimale nocturnesrc/trevor/wearables/crisis_signaux.py:19
MIN_SD nuitsoxygène moyen 0,7 ; creux 1,5 ; temps sous 90 % 1,0 ; chutes/h 2,0 ; efficacité 3,0 ; réveils 10 ; profond 12 ; coucher 30 minPlanchers de dispersion des mesures de nuitsrc/trevor/wearables/crisis.py:166-167
dispersion par défaut1,0Plancher utilisé pour une mesure absente de la table MIN_SDsrc/trevor/wearables/crisis.py:176
température sans ligne de basez = écart / 0,25, plafonné à 4Quand la température n'a pas assez de nuits de référence, l'écart fourni par l'appareil est divisé par 0,25 °Csrc/trevor/wearables/crisis.py:382
douleur récentemax des 3 derniers jours / 10Plus forte douleur déclarée sur aujourd'hui et les 2 jours précédentssrc/trevor/wearables/crisis.py:397-398
crisis_last71 si une crise dans les 7 enregistrements précédentsRepère binaire de crise récentesrc/trevor/wearables/crisis.py:399
pain_days70,5 par jour de douleur de 3/10 ou plus, maximum 2Jours de douleur dans les 7 derniers enregistrements, aujourd'hui comprissrc/trevor/wearables/crisis.py:306-308
low_spo2SpO2 du jour < 92Repère binaire de saturation bassesrc/trevor/wearables/crisis.py:401
fever_flagécart de température ≥ 0,5Repère binaire de signe de fièvresrc/trevor/wearables/crisis.py:402
DROP_Z−1,5Une nuit est « en baisse » quand son oxygène moyen est au moins 1,5 dispersion sous ta normalesrc/trevor/wearables/crisis.py:189
ABS_LOW_NIGHT92Moyenne nocturne sous laquelle une nuit compte comme basse, sans ligne de base nécessairesrc/trevor/wearables/crisis.py:190
NADIR_ABS_REF / NADIR_ABS_STEP90 ; 4Sous 90 % de creux, la sévérité monte d'un point par tranche de 4 points (86 % : 1, 82 % : 2, 78 % : 3), plafond 3, moitié si la mesure est de qualité faiblesrc/trevor/wearables/crisis.py:186-187, 311-318
tolérance de coucher0,5 h, plafond 4L'irrégularité de l'heure de coucher compte à partir d'une demi-heure d'écart à ton heure habituellesrc/trevor/wearables/crisis.py:234

Ce qui est affiché

Un dictionnaire de caractéristiques par jour : z-scores bornés de −4 à +4 (FC repos, HRV, SpO2, sommeil, pas, température, stress, respiration, bruit, FC minimale de nuit), tendances sur 3 jours (FC repos, HRV, sommeil, respiration), douleur récente, jours de douleur, crise récente, SpO2 basse, signe de fièvre et caractéristiques de nuit. Un z positif veut dire « au-dessus de ta normale ». Le sens favorable ou défavorable n'est donné que plus loin, par les poids des modèles.

Un exemple chiffré

Huit jours de FC au repos : 60, 61, 59, 62, 60, 58, 61, 60. La médiane est 60. Les distances à 60 sont 0, 1, 1, 2, 0, 2, 1, 0, dont la médiane (le MAD) est 1. 1,4826 × 1 = 1,48 est sous le plancher de 2,0 bpm, donc la dispersion vaut 2,0. Un jour à 66 bpm donne z = (66 − 60) / 2,0 = +3,0. Un jour à 68 bpm donne +4,0, valeur maximale, et un jour à 75 bpm donne aussi +4,0. Résultat vérifié en exécutant _robust et _z du dépôt (médiane 60,0, dispersion 2,0, z de 68 bpm = 4,0).

Ce que cet algorithme ne sait pas faire

Validation. La méthode (médiane, MAD, z-score robuste) est une technique statistique classique, et le code dit s'inspirer d'approches publiées sur montres et drépanocytose, dont Sanius Health, sans citer d'étude précise. Les valeurs choisies sont posées sans étude de calibration : fenêtre de 30 jours, minimum de 7 valeurs, bornes à 4, planchers de dispersion (2 bpm, 4 ms, 0,7 point de SpO2, 30 min, 1000 pas) et seuils absolus (SpO2 92 %, +0,5 °C). Aucun document du dépôt ne montre qu'elles ont été comparées à des crises observées. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/crisis.py (_robust, _z, MIN_SD, build_features, night_features, nadir_abs, pain_days), src/trevor/wearables/crisis_signaux.py (features), src/trevor/wearables/readiness.py (même méthode pour 3 mesures)

Que faire maintenant ?

Quand ton risque de crise monte, que ta forme est moyenne ou mauvaise, ou qu'une douleur commence, Trévor te propose de 3 à 5 gestes concrets. Il commence toujours par la consigne de sécurité s'il voit un signe d'urgence, puis il met en avant les gestes qui t'ont déjà aidé, les repères généraux, et enfin ce que d'autres personnes observent si leur nombre est suffisant. Ce sont des gestes d'auto-soin généraux, jamais une dose de médicament.

Où tu le vois : Écran « Que faire maintenant ? » (commande /quefaire ou /action, bouton proposé dès 40 % de risque), cartes de l'application compagnon (GET /api/phone/reco), et les deux premiers gestes dans le second message de l'alerte du matin. Chaque geste a une raison (« Pourquoi »), parfois une preuve (« Chez toi » ou « Parmi des personnes qui utilisent Trévor »), et un bouton « Je l'ai fait ».

Ce que l’algorithme lit

Le calcul, étape par étape

Rassembler le contexteScore et niveau du risque, forme, douleur, signes, plan, gestespassésUne lecture qui échoue laisse simplement la case videPourquoi proposer l'écran ?ouinonRisque de 40 ou plus, formemoyenne ou mauvaise, oudouleur de 3/10 ou plusL'écran reste ouvert à lademande, avec des repères dujourUn signe d'urgence ?ouinonPremière carte : contacte tonéquipe soignante maintenant,sinon le numéro d'urgence.Elle passe avant tout, quelque soit le scoreSi l'oxygène de nuit est basplusieurs nuits : carte «contacte ton équipe de soinsdans les prochains jours »Ordre des gestes générauxDouleur de 3/10 ou plus : eau, repos au chaud, chaleur locale,antalgique du plan, respirationRisque élevé : eau, repos, éviter le froid et l'effort, antalgiquedu planForme moyenne ou mauvaise : repos, sommeil, eau, repasRisque modéré, sinon repères du jourAjustementsNuit fragmentée : repos et sommeil passent en têteSensation de froid : repos, éviter le froid et chaleur passentdevantOxygène : seulement s'il est prévu à ton plan ET si la situationressemble à une crise (risque élevé, douleur de 3 ou plus, formebasse)« Prévenir un proche » omis si tout va bienPour toi (2 au plus)Un geste que tu as noté aumoins 5 fois5 lendemains mesurés et 10autres joursDouleur plus basse d'au moins1 point (forme plus haute d'aumoins 8) et corrélation derang dans le même sensAutres personnes (1 au plus)Au moins 20 personnes et 5 pargesteÉcart médian de douleur d'aumoins 0,5 pointJamais l'oxygèneComposer la listeSécurité, puis « pour toi », puis repères généraux, puis autrespersonnesAu plus 5 gestes, au moins 1 repère général (2 hors urgence) resteaffichéBoucle « Ça va mieux ? »« Je l'ai fait » note le geste2 heures plus tard, une question « Ça va mieux ? » part, horsheures calmes« Moins bien » avec une douleur qui monte mène à l'écran d'urgence
Logigramme : Que faire maintenant ?

Les valeurs utilisées

Nom dans le codeValeurRôleOù
RISK_MODERATE40Score à partir duquel « Que faire maintenant ? » se propose, et niveau « modéré » côté gestessrc/trevor/navigator/reco.py:52
LEVEL_OF_SCORE70 élevé ; 40 modéré ; sinon faibleSeuils de niveau utilisés ici pour ordonner les gestes. Ils diffèrent de ceux de l'écran du risque (30 et 60)src/trevor/navigator/reco.py:263-269
FEVER_C38,3 °C (lu dans data/emergency_thresholds.json)Température mesurée qui compte comme fièvre à signalersrc/trevor/navigator/reco.py:53
SPO2_LOW92Une saturation mesurée de 92 % ou moins (dans les 2 derniers jours) déclenche la consigne de sécurité. Le code précise : mesure bruitée, seuil à valider cliniquementsrc/trevor/navigator/reco.py:54 ; src/trevor/navigator/reco_flow.py:124-136, 232
PAIN_ONSET3Douleur de 3/10 ou plus : « une douleur commence »src/trevor/navigator/reco.py:55
MIN_ACTIONS / MAX_ACTIONS3 ; 5Nombre de gestes montrés (5 au plus ; le minimum n'est pas appliqué dans le code)src/trevor/navigator/reco.py:48-49, 162-190
MAX_PERSONAL / MAX_PEERS2 ; 1Gestes « pour toi » et « autres personnes » au plussrc/trevor/navigator/reco.py:50-51
RISING_POINTS / RISING_MIN_LEVEL2 points ; 4/10Douleur qui monte malgré le traitement : une prise d'antalgique de secours dans les 24 h ET une douleur notée d'au moins 4/10 qui dépasse de 2 points ou plus la plus basse des 24 hsrc/trevor/navigator/reco_flow.py:28-29, 108-118
MIN_USES / MIN_PAIRED / MIN_USUAL5 ; 5 ; 10Utilisations du geste, lendemains mesurés et autres jours mesurés nécessaires avant de parler d'un effet « pour toi »src/trevor/navigator/reco.py:57-59
NOTABLE_PAIN / NOTABLE_FORM1 point ; 8 pointsÉcart minimal favorable de douleur (0 à 10) ou de forme (0 à 100) du lendemain face à la moyenne des autres jourssrc/trevor/navigator/reco.py:60-61
PEER_MIN_DIFF0,5 pointÉcart médian de douleur pour présenter un geste des autres personnes comme associé à moins de douleursrc/trevor/navigator/reco.py:62
DEFAULT_MIN_PEOPLE / MIN_PER_GESTURE20 ; 5Personnes minimales pour montrer ce que d'autres observent, et par gestesrc/trevor/navigator/reco_peers.py:27-28
FOLLOWUP_DELAY / FOLLOWUP_STALE / ASKED_VALID2 h ; 8 h ; 12 hDélai avant « Ça va mieux ? », durée avant abandon de la question en attente, durée de validité de la réponsesrc/trevor/navigator/reco_flow.py:23-25
eau1,5 à 2 litres par jourRepère d'hydratation affiché dans le geste « eau » et dans l'alerte (converti dans l'unité préférée de la personne)src/trevor/navigator/reco.py:17-18 ; src/trevor/units.py:523

Ce qui est affiché

Une liste de 5 gestes au plus. Chaque geste porte une source : « securite » (consigne d'urgence ou équipe de soins), « perso » (« Chez toi »), « plan » (« Ton plan » : antalgique de secours, oxygène prévu), « general » (repère général) ou « autres ». Gestes du catalogue : urgence, équipe de soins la nuit, eau, repos au chaud, éviter le froid, éviter l'effort intense, éviter l'alcool, chaleur locale, respiration et relaxation, antalgique du plan (sans dose), antalgique prêt, oxygène du plan, sommeil, repas réguliers, prévenir un proche. L'écran se termine par « Ces gestes ne remplacent pas ton équipe soignante. Si tu te sens moins bien, contacte-la. » Il faut appeler le 144 sans attendre en cas de signe grave.

Un exemple chiffré

Contexte : score 75 (élevé), forme moyenne, douleur 4/10, fièvre déclarée, plan avec antalgique de secours nommé, sans oxygène. La fièvre est un signe d'urgence, donc la première carte est la consigne de sécurité. Il reste 4 places. Comme la douleur est de 3 ou plus, l'ordre est eau, repos au chaud, chaleur locale, antalgique du plan, puis la respiration. Résultat de reco.build : urgence (securite), eau (general), repos au chaud (general), chaleur (general), antalgique du plan (plan). Deuxième cas : score 45 (modéré), forme bonne, aucune douleur, aucun signe : eau, repos au chaud, éviter le froid, sommeil, repas réguliers. Vérifié en exécutant reco.build du dépôt.

Ce que cet algorithme ne sait pas faire

Validation. Les gestes sont des repères généraux d'auto-soin choisis avec le patient-administrateur (le code le dit : « ordre décidé avec le patient-administrateur »). Le code cite une règle de sécurité (carte de soins du projet : oxygène seulement si SpO2 sous 95 % ou sous la base, pas d'oxygène systématique) mais aucune étude. Les seuils (40, 70, 3/10, 38,3 °C, 92 %, 5, 10, 1 point, 8 points, 20 personnes) sont posés sans étude de validation dans le dépôt. La fièvre de 38,3 °C est lue dans la table des seuils d'urgence du projet. Les effets « pour toi » et « autres personnes » sont des associations observées, présentées comme telles. Ce n'est pas un dispositif médical validé et ce n'est pas un avis médical.

Code : src/trevor/navigator/reco.py (build, _general_order, emergency_signs, personal_effects, gesture_effect, favourable, level_of, triggered, form_of_mood, worst_form), src/trevor/navigator/reco_flow.py (context_for, compute, present, pain_rising, plan_of, record_done, alert_lines, api_payload), src/trevor/navigator/reco_peers.py (aggregate, peer_actions), src/trevor/conversation/reco_screen.py, src/trevor/conversation/reminders.py (crisis_alerts : deuxième message), data/i18n/fr.json (textReco*)

Risque de baisse de forme

Le risque de baisse de forme est un second score, plus doux et plus fréquent que le risque de crise. Il estime la probabilité d'un fléchissement de ton quotidien (sommeil, énergie, douleur) dans les 48 heures. Il sert à agir tôt, par exemple avec du repos, de l'hydratation et un rythme plus calme, avant une éventuelle crise.

Où tu le vois : Dans le message du bot « Mon risque de crise » (écran Ma montre), juste sous le risque de crise : une ligne « Risque de baisse de forme : X % · niveau » avec une icône verte, orange ou rouge, une phrase d'explication, puis une puce par signal qui pèse. Aucun autre écran, ni l'application, ni la montre, ni le tableau de bord n'affichent ce score (le code ne l'envoie qu'à ce message).

Ce que l’algorithme lit

Le calcul, étape par étape

Récupérer les signaux du jourCe sont les mêmes signaux que ceux du risque de criseCalculés une seule fois, puis donnés aux deux scoresLe risque de criseexiste-t-il pour toi ?ouinonLe risque de baisse de formeest calculé juste aprèsAucun des deux scores n'estcalculé (maladie sansprédiction de crise, ou aucunfacteur exploitable)Atténuer les signaux d'avant une transfusionSi une transfusion est récente, oxygène de nuit, SpO2,hémoglobine, retard de transfusion, crise et jours de douleur des7 derniers jours sont réduitsRéduction = 60 % × e^(−jours / 6), jusqu'à 21 joursAdditionner les poidslogit = −1,4 + somme (poids × signal)24 signaux seulement entrent dans la sommeLes poids sont fixes, jamais appris, jamais multipliés par 1,6Convertir en pourcentageprobabilité = 1 / (1 + e^(−logit))score = probabilité × 100, arrondiPas de plafond de 99 % ni de plafond après transfusionQuel niveau ?ouinonMoins de 30 : faible (vert).De 30 à 59 : modéré (orange).60 ou plus : élevé (rouge)Le niveau est toujours l'undes troisChoisir les 4 explicationsContribution de chaque signal = poids × valeurOn garde celles dont la valeur absolue atteint 0,15Les 4 plus fortes, par valeur absolue décroissanteÉcrire les phrasesContribution positive : phrase du sens défavorable (« Ton sommeilest plus court que d'habitude »)Contribution négative : phrase du sens favorablePuis : « cela fait monter » ou « cela fait baisser ton risque debaisse de forme »
Logigramme : Risque de baisse de forme

Les valeurs utilisées

Nom dans le codeValeurRôleOù
FORM_BIAS−1,4Point de départ du calcul : un jour où tous les signaux sont à 0 donne 20 % (1 / (1 + e^1,4) = 0,198), contre environ 10 % pour la crisesrc/trevor/wearables/crisis.py:605
seuil modéréscore ≥ 30Les seuils sont écrits en dur dans form_risk, avec les mêmes valeurs que le risque de crisesrc/trevor/wearables/crisis.py:615
seuil élevéscore ≥ 60Niveau « élevé »src/trevor/wearables/crisis.py:615
seuil d'affichage d'une contribution0,15Un signal dont |poids × valeur| est sous 0,15 n'est pas expliquésrc/trevor/wearables/crisis.py:616
nombre d'explications4Au plus quatre signaux affichéssrc/trevor/wearables/crisis.py:617
STALE_SHARE0,6Part effacée des signaux d'avant la transfusion le jour même (× e^(−jours/6) ensuite)src/trevor/wearables/crisis.py:529
clés atténuées après transfusionz_spo2, z_spo2_night, low_spo2, night_nadir, night_nadir_abs, night_abs_low, night_time_low, night_odi, night_drop_streak, hb_low, transfusion_overdue, crisis_last7, pain_days7Parmi elles, seules z_spo2, hb_low, transfusion_overdue, crisis_last7, pain_days7 et night_abs_low pèsent dans la baisse de formesrc/trevor/wearables/crisis.py:524-528
TX_RECENT_DAYS / TX_RECENT_WINDOW6 jours ; 21 jourstx_recent = e^(−jours/6) pendant 21 jours après la transfusion, puis 0src/trevor/wearables/crisis.py:270-271, 292-293
hold_days5 jours par culot, de 14 à 56 jours ; 28 sans nombre de culotsDurée de tenue de la transfusion, qui règle tx_protect et tx_losssrc/trevor/wearables/crisis.py:268-279
hb_low(9,5 − Hb) / 2, entre 0 et 4Hémoglobine sous 9,5 g/dL ; 7,5 g/dL donne 1src/trevor/wearables/crisis.py:651-660
transfusion_overdueretard (fraction d'intervalle) × 2, entre 0 et 4Seulement pour une personne en programme transfusionnelsrc/trevor/wearables/crisis.py:658-659
cold_ambient(10 °C − tmin) / 10, entre 0 et 4Froid sous 10 °Csrc/trevor/wearables/crisis.py:104, 251
heat_ambient(tmax − 28 °C) / 6, entre 0 et 4Chaleur au-dessus de 28 °Csrc/trevor/wearables/crisis.py:105, 252
air_pm25(PM2.5 − 15) / 15, entre 0 et 4Particules fines au-dessus de la ligne directrice de l'OMS (15 µg/m³ sur 24 h)src/trevor/wearables/crisis.py:107, 255

Les poids

Un poids positif augmente le résultat, un poids négatif le diminue.

SignalPoidsOù
Douleur déclarée récente (plus forte des 3 derniers jours / 10)+0,8src/trevor/wearables/crisis.py:599
Effet de la dernière transfusion qui s'estompe+0,8src/trevor/wearables/crisis.py:602
Sommeil plus court que ta normale (z négatif)−0,6src/trevor/wearables/crisis.py:597
Activité plus faible que ta normale (z négatif)−0,5src/trevor/wearables/crisis.py:597
Hémoglobine basse+0,5src/trevor/wearables/crisis.py:599
Stress mesuré plus élevé que ta normale+0,45src/trevor/wearables/crisis.py:597
HRV plus basse que ta normale (z négatif)−0,4src/trevor/wearables/crisis.py:597
FC au repos plus rapide que ta normale+0,4src/trevor/wearables/crisis.py:597
Crise dans les 7 derniers jours+0,4src/trevor/wearables/crisis.py:599
Jours de douleur dans la semaine (0 à 2)+0,4src/trevor/wearables/crisis.py:600
Sommeil sur 3 jours (z négatif)−0,35src/trevor/wearables/crisis.py:598
Retard de transfusion+0,35src/trevor/wearables/crisis.py:599
SpO2 vs ta normale (z négatif)−0,3src/trevor/wearables/crisis.py:597
Hydroxyurée suivie de façon irrégulière+0,3src/trevor/wearables/crisis.py:602
Nuits de suite avec un oxygène bas (0 à 4)+0,25src/trevor/wearables/crisis.py:600
Température cutanée vs ta normale+0,2src/trevor/wearables/crisis.py:597
HRV sur 3 jours (z négatif) ; FC repos sur 3 jours−0,2 ; +0,2src/trevor/wearables/crisis.py:598
Froid extérieur ; chaleur extérieure ; PM2.5+0,2 chacunsrc/trevor/wearables/crisis.py:603
Hydroxyurée prise régulièrement−0,2src/trevor/wearables/crisis.py:602
Transfusion récente ; transfusion qui tient encore−1,5 chacunsrc/trevor/wearables/crisis.py:601

Ce qui est affiché

Un pourcentage de 0 à 100, un niveau et jusqu'à 4 explications. Niveaux : faible sous 30 % (icône verte), modéré de 30 à 59 % (orange), élevé à partir de 60 % (rouge). Le bot écrit « Risque de baisse de forme : X % · niveau », puis « Un fléchissement possible de ta forme (sommeil, énergie, douleur) dans les 48 h, plus léger qu'une crise », puis une puce par explication, par exemple « Ton sommeil est plus court que d'habitude : cela fait monter ton risque de baisse de forme. ». Le sens des signaux pour la forme se lit dans les poids : un z de sommeil négatif multiplié par −0,6 donne une contribution positive.

Un exemple chiffré

Sans aucun écart, tous les signaux valent 0 et le score est de 20 % (niveau faible). Prenons une journée où le sommeil est à −2 dispersions, l'activité à −1,5, la HRV à −1, la FC au repos à +1, le stress à +1 et la douleur récente à 0,5 (5/10). Le logit vaut −1,4 + 1,2 (sommeil) + 0,75 (pas) + 0,4 (HRV) + 0,4 (FC) + 0,45 (stress) + 0,4 (douleur) = 2,2. La probabilité est 1 / (1 + e^−2,2) = 0,90, soit 90 % (niveau élevé). Les quatre explications retenues sont le sommeil (1,2), les pas (0,75), le stress (0,45), puis la HRV (0,4), qui égale la FC et la douleur à 0,4 et passe devant dans l'ordre du tableau des poids. Résultat obtenu en exécutant form_risk du dépôt (score 90, niveau élevé, contributions z_sleep 1,2 ; z_steps 0,75 ; z_stress 0,45 ; z_hrv 0,4).

Ce que cet algorithme ne sait pas faire

Validation. Les poids sont un a priori posé par le concepteur : le code les décrit comme « poids d'a priori, transparents », sans citer de source ni de comparaison avec des observations. Le signe de chaque poids suit un raisonnement clinique plausible (moins de sommeil, moins d'activité, HRV plus basse, cœur plus rapide, stress, douleur et anémie qui reviennent poussent le score vers le haut), mais aucune valeur n'a été ajustée sur des données. Le niveau de base (−1,4) et les seuils de 30 et 60 sont arbitraires. Aucune étude interne ni externe n'est citée pour ce score dans le code ou dans les documents du dépôt. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/crisis.py (FORM_WEIGHTS, FORM_BIAS, form_risk, after_transfusion, explain, reason_label, EXPLAIN_UP, EXPLAIN_DOWN, FEATURE_LABELS), src/trevor/wearables/service.py (crisis_risk, lignes 793-796 ; crisis_text, lignes 1019-1025), data/i18n/fr.json (textCrisisFormHead)

Signaux de la montre et sources de température et de cœur

Trévor lit trois familles de signaux issus de la montre, de la bague ou de fichiers. Les signaux factuels sont des repères simples (SpO2 sous 92 %, FC au repos 10 bpm plus haute, sommeil court, etc.) affichés avec leur date. Trois caractéristiques de température et de cœur entrent dans le risque de crise avec des poids modestes, et le module des signaux compare température et cœur à ta ligne de base pour ses propres écrans.

Où tu le vois : Les signaux factuels apparaissent dans le résumé de la montre (« Mes 7 derniers jours ») et dans le tableau de bord des soignants sous la forme « Objet connecté : SpO2 nocturne 91 % ». Les trois caractéristiques du risque se lisent dans les phrases du risque de crise, avec en dessous la ligne « d'où viennent la température et le cœur » (source, type, méthode, qualité). L'écran Signaux montre la température et le cœur face à ta ligne de base.

Ce que l’algorithme lit

Le calcul, étape par étape

Signaux factuels (7 derniers jours)Calculés seulement si l'interprétation est activéeLigne de base = les 30 jours avant ces 7 jours, au moins 5 valeursUn signal par jour concernéOxygène et cœurSpO2 nocturne sous 92 %FC au repos au moins 10 bpmau-dessus de la médianeHRV au moins 25 % sous lamédianeTempérature, respiration,sommeilTempérature cutanée +0,5 °C ouplusFréquence respiratoire 20/minou plusMoins de 5 h de sommeil 3nuits de suite (une nuit sous2 h est ignorée)Entrer dans le risque de crise : 3 caractéristiquesz_night_hr : FC la plus basse de la nuit contre ta ligne de basetemp_nights : nuits d'affilée (4 au plus) avec un écart de peaud'au moins 0,3 °Ctemp_hr_coupling : produit prudent de la hausse de température etde la hausse de FC, de 0 à 3Donnée absente ?ouinonLa caractéristique vaut 0 :le modèle garde soncomportement d'avantElle est multipliée par sonpoids a priori (0,3 ; 0,25 ;0,3), puis par 1,6Compléter les jours mesurés avec les autres sourcesLa FC minimale de nuit et l'écart de peau importés complètent unjour déjà mesuré par la montreIls ne remplacent jamais une valeur déjà présente de la montreIls ne créent pas de jourMontrer l'origineQuand la température ou le cœur pèsent dans le risque, on listejusqu'à 6 sources : source, type, méthode, qualitéFenêtre de 7 jours
Logigramme : Signaux de la montre et sources de température et de cœur

Les valeurs utilisées

Nom dans le codeValeurRôleOù
SpO2 nocturne basse< 92Seuil courant d'alerte des oxymètres grand public, selon le codesrc/trevor/wearables/service.py:486
FC repos haute≥ médiane des 30 jours précédents + 10 bpm (au moins 5 valeurs)Signal de cœur au repos plus rapidesrc/trevor/wearables/service.py:488
HRV basse≤ 0,75 × médiane (au moins 5 valeurs)Baisse de 25 % ou plussrc/trevor/wearables/service.py:490
température cutanée hauteécart ≥ +0,5 °CSignal de fièvre possible (bague Oura, selon le code)src/trevor/wearables/service.py:492
fréquence respiratoire haute≥ 20 par minuteSeuil usuel de polypnée chez l'adulte, selon le codesrc/trevor/wearables/service.py:494
sommeil court< 5 h trois nuits de suite ; une nuit < 2 h est ignoréeUne nuit de moins de 2 h est probablement un appareil non portésrc/trevor/wearables/service.py:497-506
ELEVATED_TEMP_DELTA0,3 °CSeuil d'écart de la peau pour compter une nuit élevée dans temp_nights (même valeur que dans data/signaux_sources.json)src/trevor/wearables/crisis_signaux.py:20
MAX_NIGHTS4Plafond du nombre de nuits d'affilée comptéessrc/trevor/wearables/crisis_signaux.py:21
temp_hr_couplingmin(3 ; max(0 ; z_temp)) × min(3 ; max(0 ; z FC repos, z FC nuit)) / 3Calculé si au moins une nuit de peau élevée ou un z de température positif ; sinon 0src/trevor/wearables/crisis_signaux.py:62-63
NEW_PRIOR_WEIGHTSz_night_hr 0,3 ; temp_nights 0,25 ; temp_hr_coupling 0,3Poids a priori dans le risque de crise (multipliés ensuite par 1,6)src/trevor/wearables/crisis_signaux.py:18
baseline du module signauxfenêtre 30 jours ; 3 nuits minimum ; +0,3 °C ; +8 bpm ; MAD plancher 3 bpm ; tachycardie de repos 100 bpm ; saut de repos 20 bpmValeurs du module Signaux pour ses propres écrans. Elles ne servent pas au score de risquedata/signaux_sources.json (baseline) ; src/trevor/signaux/baseline.py:15-24
fièvre mesuréeseuil de la table d'urgence (38,3 °C), thermomètre seulementLa température de peau d'un capteur ne déclenche jamais l'urgence seulesrc/trevor/signaux/temperature.py:1-9, 32-34

Les poids

Un poids positif augmente le résultat, un poids négatif le diminue.

SignalPoidsOù
FC la plus basse de la nuit vs ta normale+0,3src/trevor/wearables/crisis_signaux.py:18
Température de peau haute plusieurs nuits+0,25src/trevor/wearables/crisis_signaux.py:18
Température et FC qui montent ensemble+0,3src/trevor/wearables/crisis_signaux.py:18
Température cutanée vs ta normale (risque de crise)+0,5src/trevor/wearables/crisis.py:81
Signe de fièvre (écart de peau ≥ 0,5 °C)+0,9src/trevor/wearables/crisis.py:83
Respiration vs ta normale+0,4src/trevor/wearables/crisis.py:85

Ce qui est affiché

Pour les signaux factuels : une liste de lignes datées, par exemple « SpO2 nocturne 91 % », « FC repos 72 bpm (référence 60) », « HRV 38 ms (référence 52, baisse de 25 % ou plus) », « Température cutanée +0,6 °C », « Fréquence respiratoire 21 /min », « Moins de 5 h de sommeil 3 nuits de suite », du plus récent au plus ancien. Pour le risque de crise : trois nombres (z de la FC la plus basse de la nuit, nuits d'affilée de 0 à 4, couplage de 0 à 3) qui s'ajoutent au calcul, et la liste des sources (jusqu'à 6). Pour l'écran Signaux : les écarts à ta normale de la température et du cœur. Les ECG n'entrent pas dans le score : ils déclenchent seulement des messages d'orientation.

Un exemple chiffré

FC au repos : médiane des 30 jours précédents à 60 bpm. Un jour à 70 bpm donne le signal « FC repos 70 bpm (référence 60) », car 70 ≥ 60 + 10. Un jour à 69 bpm n'en donne pas. Pour le couplage, avec un z de température de +2 et un z de FC de nuit de +3 : min(3 ; 2) × min(3 ; 3) / 3 = 2. Contribution au risque de crise avant amplification : 0,3 × 2 = 0,6 ; après le gain de 1,6 : 0,96 sur l'échelle du modèle. Calcul fait à la main à partir des formules du code, non exécuté.

Ce que cet algorithme ne sait pas faire

Validation. Les seuils des signaux factuels sont des repères courants que le code cite sans référence : SpO2 de 92 % (seuil des oxymètres grand public), polypnée à 20 par minute (scores d'alerte précoce), baisse de la HRV de 25 %. Les poids des trois caractéristiques de température et de cœur (0,3 ; 0,25 ; 0,3) sont des a priori « modestes » : le code les décrit comme des « associations plausibles, non validées par une étude sur la drépanocytose », documentées dans docs/SIGNAUX_TEMPERATURE_COEUR_ECG.md, et ils se réajustent sur les données de la personne puis de la cohorte. Le seuil de 0,3 °C et ceux du module Signaux sont posés sans étude de calibration. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/service.py (signals, summary, day_records, crisis_risk), src/trevor/wearables/crisis_signaux.py (night_streak, features, NEW_PRIOR_WEIGHTS), src/trevor/signaux/service.py (crisis_extras, crisis_sources, crisis_sources_text, build), src/trevor/signaux/baseline.py (against_baseline, consecutive_elevated, robust), src/trevor/signaux/temperature.py (analyse, is_fever), src/trevor/signaux/heart.py (analyse), src/trevor/signals.py (vue « Mesures et estimations »), data/signaux_sources.json (baseline)

Tendance à la vasoconstriction (expérimental)

Cet indice indicatif repère une peau qui se refroidit plus que d'habitude pendant la nuit, signe possible de vasoconstriction. Il compare ta température de peau, ton cœur au repos, ta HRV, ton oxygène et ta respiration à tes 14 jours précédents. Il reste silencieux quand la mesure est fragile, et il n'est calculé que si tu as donné ton accord.

Où tu le vois : Au poignet (écran Ma santé de la montre), sous forme de codes seulement (état, niveau, noms des facteurs, qualité), et comme un facteur « Peau qui se refroidit (expérimental) » dans les explications du risque de crise quand il pèse. Aucune valeur de santé n'est affichée par cet indice.

Ce que l’algorithme lit

Le calcul, étape par étape

Accord donné et indicateuractivé ?ouinonOn lit les 16 derniers joursde la montreRien n'est calculé : lefacteur vaut 0 dans le risqueQualité de la mesure (14 jours)Un jour est exploitable avec au moins 2 mesures utiles et unsommeil d'au moins 2 h s'il est connuBonne : 10 jours exploitables ou plus et un des deux derniersjours exploitableMoyenne : 6 à 9 jours dans les mêmes conditions. SinoninsuffisanteQualité insuffisante, oujour non exploitable ?ouinonÉtat « silence » : aucuneconclusionOn continue avec le jourd'aujourd'hui, ou d'hier àdéfautLa peau s'est-elle refroidie?ouinonFacteur « temp » : baissed'au moins 0,3 °C et d'aumoins 1 dispersion face à lamédiane des 14 joursprécédents (au moins 5valeurs)État « calme », aucun facteurretenuAutres facteurs (si la peau s'est refroidie)Cœur : +5 bpm et au moins 1 dispersionHRV : au plus 75 % de la médianeSpO2 : −1,5 point et au moins 1 dispersionRespiration : +2 par minute et au moins 1 dispersionAu moins 2 facteurs etqualité « bonne » ?ouinonÉtat « nette », niveau 2État « légère », niveau 1 (lapeau seule suffit)Entrer dans le risque de criseValeur 0, 1 ou 2 selon le niveau ; 0 pour silence et calmePoids a priori +0,2, multiplié par 1,6 : +0,32 par niveauJamais appris à l'entraînement : 0 dans les jours d'entraînement
Logigramme : Tendance à la vasoconstriction (expérimental)

Les valeurs utilisées

Nom dans le codeValeurRôleOù
BASE_DAYS14Jours précédents qui forment la base de comparaison (médiane)src/trevor/wearables/vasoconstriction.py:33
MIN_BASE5Valeurs minimales dans la base, pour chaque mesuresrc/trevor/wearables/vasoconstriction.py:34
TEMP_DROP_C0,3 °CBaisse de la peau face à la médiane (en plus d'au moins 1 dispersion)src/trevor/wearables/vasoconstriction.py:35
TEMP_MIN_SD0,15 °CPlancher de dispersion de la températuresrc/trevor/wearables/vasoconstriction.py:36
HR_RISE_BPM / HR_MIN_SD5 bpm ; 2 bpmHausse du cœur au repos et plancher de dispersionsrc/trevor/wearables/vasoconstriction.py:37-38
HRV_RATIO0,75HRV au plus 75 % de la médiane (25 % sous elle)src/trevor/wearables/vasoconstriction.py:39
SPO2_DROP1,5 pointBaisse de l'oxygène sous la base (plancher de dispersion 0,7)src/trevor/wearables/vasoconstriction.py:40, 113
RESP_RISE2 par minuteHausse de la fréquence respiratoire (plancher de dispersion 1,0)src/trevor/wearables/vasoconstriction.py:41, 115
Z_MIN1,0Chaque écart doit aussi atteindre une dispersion robustesrc/trevor/wearables/vasoconstriction.py:42
WINDOW_DAYS / GOOD_DAYS / MEDIUM_DAYS14 ; 10 ; 6Jours exploitables pour juger la qualité de la mesuresrc/trevor/wearables/mesure.py:16-20
MIN_NIGHT_COVERAGE_MIN120Un sommeil connu de moins de 2 h rend le jour inexploitablesrc/trevor/wearables/mesure.py:17, 30
poids dans le risque de crise+0,2 (× 1,6 = +0,32 par niveau)Poids modeste : le code parle d'association décrite (Mohan 1998, Veluswamy 2020), pas d'une prédiction validéesrc/trevor/wearables/crisis.py:92
consentementctx_vasoconstriction_enabled et accord « Mon contexte »Sans l'un des deux, le résultat est vide (None) et le facteur vaut 0src/trevor/wearables/vasoconstriction.py:134-141

Les poids

Un poids positif augmente le résultat, un poids négatif le diminue.

SignalPoidsOù
Peau qui se refroidit (niveau 0, 1 ou 2)+0,2src/trevor/wearables/crisis.py:92

Ce qui est affiché

Un résultat avec un état (silence, calme, légère ou nette), un niveau de 0 à 2, les noms des facteurs présents (temp, hr, hrv, spo2, resp), la qualité de la mesure (bonne, moyenne, insuffisante) et le nombre de jours exploitables. Seules les étiquettes sortent, jamais une valeur de santé ni une série, et rien n'est journalisé. Pour le risque de crise, seul le niveau compte : 0 pour silence et calme, 1 pour légère, 2 pour nette. Dans l'application et à la montre, les codes sont silent, calm, slight et clear.

Un exemple chiffré

Quatorze jours de référence : peau autour de 34,0 °C, cœur au repos 58 à 59 bpm, HRV 50 à 52, SpO2 96, respiration 14, sommeil 420 min. Aujourd'hui : peau 33,5 °C et cœur 66 bpm. La peau a baissé de 0,5 °C (au moins 0,3) et de plus d'une dispersion, et le cœur monte de plus de 5 bpm : deux facteurs (temp, hr) avec une qualité bonne, donc état « nette », niveau 2, soit +0,64 sur l'échelle du modèle (2 × 0,32). Si le cœur reste à 59 bpm, seul « temp » est présent : état « légère », niveau 1. Résultat vérifié en exécutant compute() du dépôt (nette, niveau 2, facteurs temp et hr ; légère, niveau 1, facteur temp).

Ce que cet algorithme ne sait pas faire

Validation. L'indice est expérimental et indicatif, et le code le dit : « ni un diagnostic ni une mesure médicale ». Il s'appuie sur des associations décrites dans trois références que le code cite : Mohan J et al., Clin Sci 1998;94(2):111-120 (vasoconstriction réflexe plus forte au refroidissement léger dans la drépanocytose SS) ; Veluswamy S et al., Blood 2020 (dysautonomie vasculaire avec stimuli thermiques) ; Vuong C et al., Front Digit Health 2023 (FC et pas d'une montre associés à la douleur, petite étude, prédiction de crise non établie). Ces études portent sur des tests de refroidissement contrôlés ou de petits échantillons, pas sur une peau de poignet pendant la nuit. Les seuils (0,3 °C, 5 bpm, 75 %, 1,5 point, 2 par minute) sont posés sans étude de calibration. La validation médicale est en attente (docs/VALIDATION_MEDICALE_EN_ATTENTE.md, M-F1). Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/vasoconstriction.py (compute, level_feature, for_user), src/trevor/wearables/mesure.py (assess, usable), src/trevor/wearables/service.py (_vaso_feature), src/trevor/wearables/crisis.py (PRIOR_WEIGHTS vasoconstriction), src/trevor/wearables/watch_summary.py (_vasoconstriction)

Important. Ces calculs orientent, ils ne posent aucun diagnostic et ne remplacent pas l'avis de l'équipe soignante. En cas de douleur forte, de fièvre ou d'essoufflement, il faut appeler le 144 sans attendre.