Slide 1

Slide 1 text

Predict Datalogger médical pour le CHRU du Brest

Slide 2

Slide 2 text

Auteurs ▪ Pierre Papin Développeur hardware et software chez SenX ▪ Arnaud Moré Stagiaire ingénieur à l’ENIB, pour le CHRU 2

Slide 3

Slide 3 text

Introduction 1 3

Slide 4

Slide 4 text

L’idée Patients en réanimation chirurgicale La pression intracrânienne est le facteur important pouvant causer des lésions cérébrales irréversibles. La forme de la courbe reflète une pathologie. Idée : la forme des courbes de pression intracrânienne, déterminerait l’issue autant que la valeur absolue de la pression. 4

Slide 5

Slide 5 text

Dataset cible Pour valider cette hypothèse, il faut un jeu de données : PIC, AP, enregistrés à 100Hz en continu. PtO2, température, enregistrés toutes les minutes. Caractéristiques du patient. Traitements administrés au patient. 5

Slide 6

Slide 6 text

Hardware 2 6

Slide 7

Slide 7 text

Mon rêve ! Utiliser un protocole médical ouvert, standard, permettant de streamer les données en temps réel ! HL7, poussé par Philips, est un protocole abominable permettant de transférer des waveforms. Il est possible de l’utiliser, mais il faut des mois de développement. Et les petits appareils ultra spécialisés pour la PIC et la PtO2 ne sont pas compatibles. 7

Slide 8

Slide 8 text

La réalité PtO2 et température monitorés par Integra Licox. Cet appareil a une sortie USB prévue pour un module type FTDI (USB->RS232) La documentation du protocole est disponible. 8

Slide 9

Slide 9 text

La réalité La PIC est monitorée par un Sophysa Pressio2 Cet appareil a une sortie mini usb reconnue comme un port série par l’hôte. Le protocole est disponible. 9

Slide 10

Slide 10 text

La réalité AP monitorée par un super moniteur Edwards Life Science. Il y a un port ethernet, mais rien de prévu pour streamer les données. Après activation de l’option, il y a une option pour exporter les données au format csv avec un point toutes les 5 secondes… 10

Slide 11

Slide 11 text

Et à l’hôpital ? À l'hôpital, le poste de soin regroupe toutes les données patients des chambres du service. C’est une solution vendue par Philips, qui permet de visualiser à distance les courbes (basse résolution) des appareils Philips. Donc, au pied du lit, on connecte le plus d’appareils possible à une centrale Philips, par des liaisons… analogiques ! Philips peut aussi stocker les données… en blob binaire dans une base SQL. 11

Slide 12

Slide 12 text

Deux liaisons séries et … Le moniteur Edwards Life Science dispose d’une seconde sortie analogique que je peux utiliser. Elle respecte le standard(*) médical, à savoir une jauge de contrainte émulée dont la sortie est calibrée à : 20,5µV /mmHg 12

Slide 13

Slide 13 text

Architecture Hardware 13

Slide 14

Slide 14 text

Solution AP Création d’un hardware spécifique pour convertir l’AP en un protocole série. 14 Acquisition de la pression artérielle, sortie sur un protocole série via un arduino nano. + Watchdog hardware pour le Rpi. RTC pour le raspberry

Slide 15

Slide 15 text

Intégration 15

Slide 16

Slide 16 text

Intégration 16

Slide 17

Slide 17 text

Logiciel embarqué 3 17

Slide 18

Slide 18 text

Modélisation et données de santé Éviter de stocker des données de santé en zone HDS ! Séparer les données brutes des données confidentielles, en faisant le lien par un changement de patient : PIC, AP, enregistrés à 100Hz en continu. PtO2, température, enregistrés toutes les minutes. Caractéristiques du patient. Traitements administrés au patient. 18 time series, label = numéro de série du datalogger Confidentiel, reste géré par le CHRU

Slide 19

Slide 19 text

Modélisation et données de santé PIC, AP, enregistrés à 100Hz en continu. PtO2, température, enregistrés toutes les minutes. Une GTS contenant un nom de patient aléatoire Le nom de patient aléatoire est noté dans les données cliniques. Caractéristiques du patient. Traitements administrés au patient. 19 time series, label = numéro de série du datalogger Confidentiel, reste géré par le CHRU

Slide 20

Slide 20 text

Modélisation et données de santé Sur l’IHM, il y a bouton “nouveau patient” 20

Slide 21

Slide 21 text

Fonctionnalités annexes Un bouton “nouveau patient” crée un point dans une GTS (type STRING). Utilisation théorique : création d’un nouveau patient à chaque nouveau patient. En pratique : ça dépend si le médecin/infirmier est formé… Un bouton “soins en cours” crée un point dans une GTS (true). Utilisation théorique : l’infirmière appui sur le bouton avant de “remuer” le patient (ce qui perturbe fortement les courbes de pression) En pratique : … … parfois avant, parfois après, parfois jamais. 21

Slide 22

Slide 22 text

Architecture 22 IHM Python + Kivy Collecte des liaisons série Java Warp 10 API api/v0/exec api/v0/exec 1 3 2 Warp 10 (SAAS) 4

Slide 23

Slide 23 text

1/ Collecte vers Warp 10 L’applicatif de collecte génère le WarpScript suivant: 23 <' 1654596856720463// AP{} 34.1 =1654596892170438// 35.2 =1654596892180438// 35.6 (...) '> @predict/storeData

Slide 24

Slide 24 text

2/ Affichage temps réel Pour chaque appareil, l’IHM python+kivy interroge une API: curl http://localhost:12345/api/LicoxPtO2/1/ # {"lastValue":0,"freshValue":true,"serialIsConnected":true} Pour ces requêtes régulières, pycurl préférable à request. 24

Slide 25

Slide 25 text

3/ Gestion du pseudo de patient L’IHM peut créer un patient, ou afficher le patient en cours, en interrogeant Warp 10 directement. r = requests.post(WARP10_ENDPOINT, data=""" @predict/currentPatient """, timeout=5) if (r.status_code == 200): lastPatient = r.json()[0] Pour plus de souplesse dans la gestion du code, utilisation d’une macro. 25

Slide 26

Slide 26 text

4/ Synchro SAAS Modèle classique 26

Slide 27

Slide 27 text

4/ Synchro SAAS Warp 10 : les endpoints sont exposés. Chaque datalogger écrit dans la base grâce à son token. 27

Slide 28

Slide 28 text

4/ Synchro SAAS, concrètement L’instance Warp 10 sur chaque datalogger, va essayer toutes les minutes de recopier les GTS locales vers l’instance Warp 10 SAAS. Un seul WarpScript suffit, placé dans /opt/warp10/warpscript/predict/60000/ 28

Slide 29

Slide 29 text

4/ Synchro SAAS, concrètement ▪ Chercher T = timestamp de la dernière synchronisation réussie (FETCH) ▪ Récupérer les GTS entre T et T + 8h (FETCH) ▪ Compresser et sérialiser les données (WRAP) ▪ Construire un WarpScript contenant les données sérialisées, le token d’ écriture, et les instructions pour décompresser et UPDATE les données ▪ Exécuter ce WarpScript sur l’instance Warp 10 distante (REXECZ) ▪ Si succès, écrire T+8h en valeur de la dernière synchro réussie (UPDATE) Pour tracer la dernière synchro réussie, utilisation d’une GTS nommée “upload”, par exemple. 29

Slide 30

Slide 30 text

Disque et suppression des données Sur le datalogger, utilisation d’une carte SD industrielle donnée pour 30k cycle d’écriture. LevelDB est agressif pour les cartes SD. Les suppressions régulières entraînent des compactions durant lesquelles il faut réécrire beaucoup de fichiers. Solution : plugin “leveldb” de Warp 10. 30

Slide 31

Slide 31 text

Disque et suppression des données Tous les jours, supprimer les données de plus de 30 jours. Un seul WarpScript suffit, placé dans /opt/warp10/warpscript/predict/86400000/ 30 d 'historylength' STORE NOW $historylength - 'deletestopTS' STORE 'read' @predict/localToken '~.*' {} $deletestopTS 100000 @senx/leveldb/purge L’utilisation du plugin “leveldb” permet de supprimer directement les fichiers .sst, sans nécessité d’attendre une compaction. 31 😄

Slide 32

Slide 32 text

Espace disque disponible (sur carte SD 16go) 32

Slide 33

Slide 33 text

2 ans plus tard… 4 33

Slide 34

Slide 34 text

10 milliards de points 34

Slide 35

Slide 35 text

Performances en lecture en BDD 300 000 à 1 000 000 de points par seconde Pour relire 10 milliards de points : ~5 heures Bien, mais largement perfectible, grâce aux HFiles ! 35

Slide 36

Slide 36 text

HFiles ? Les History Files, ou HFiles, sont des conteneurs de stockage à très haute densité qui peuvent contenir des centaines de milliards de points de mesure provenant de millions de séries. ▪ Format spécifique Warp 10. ▪ Lecteur gratuit, générateur sous licence. ▪ Input format Spark inclus dans le lecteur. Le contenu de l’étude tient dans un fichier de 13go, soit 1.3 datapoints par octet (sans aucune altération). 36

Slide 37

Slide 37 text

HFile, comment ça marche ? 37 { 'token' 'MyReadToken' 'selector' '~.*{}' 'end' NOW 'timespan' 100 d // encoder to encoder macro. cannot change class and labels here, but can COMPACT 'macro' <% {} ->GTS COMPACT %> 'path' 'file257' //'checksums' false // extra checksum for file for hdfs filesystem 'secret' 'myhfstoresecret' } HFDUMP La création des fichiers peut être automatisée depuis Warp 10.

Slide 38

Slide 38 text

HFile, lecture 38 { 'store' 'predictraw' 'token' $hfToken 'class' '~.*' 'labels' {} 'end' $end 'timespan' $timespan // 'count' 100 // you can limit 'lineage' 'hf' // add a "hf" attribute with list of hfiles the data come from } HFFETCH ->GTS HFFETCH peut être remplacé par FETCH. ~ 10 millions de points par seconde en lecture par thread, selon le hardware.

Slide 39

Slide 39 text

Recommandation pour HFile Le fichier HFile va contenir un encodeur de possiblement 1 milliard de points pour la pression artérielle de chaque datalogger. Chaque lecture va donc nécessiter de charger l’encodeur entier et le décompresser. Il faut donc BEAUCOUP de ram si on fait un seul fichier HFile avec quelques GTS de 1 milliards de points. Pour Predict, on a choisi de découper en 1 HFile / jour (500 fichiers). 39 java.lang.OutOfMemoryError: Java heap space

Slide 40

Slide 40 text

Config d’Arnaud Faute d’avoir un cluster hadoop au CHRU… Un laptop, 16go de RAM Warp 10 avec : - extension HFStore - plugin Jupyter Jupyter + python 40

Slide 41

Slide 41 text

Exploitation des données 5 41

Slide 42

Slide 42 text

Exploration des données : courbe PA 42 Calibration Saturation Bruit Arythmie

Slide 43

Slide 43 text

Profil matriciel 43

Slide 44

Slide 44 text

Résultat profil matriciel 44

Slide 45

Slide 45 text

Exploration des données : courbe PIC 45

Slide 46

Slide 46 text

Reste des données 46 Changement de patient mal placé Changement de patient correct

Slide 47

Slide 47 text

Exploration des données : temps d’exécution 47 Quelques chiffres : ▪ 1 seconde pour fetch 1 journée de data ( + 8 millions de points ) ▪ Profil matriciel assez lourd : ~20 secondes pour traiter 5 minutes de données, 12 threads en parallèle (~ 20 secondes par heure de data) ▪ Nettoyage de la PIC beaucoup plus rapide, quelques secondes par période de 5 minutes

Slide 48

Slide 48 text

Analyse de forme de la courbe 48

Slide 49

Slide 49 text

Analyse de forme de la courbe 49 Entraînement : 2500 images classifiées : -2000 pour l’entraînement -250 de validation -250 de test Moins de 10 % d’erreurs Généralisation : Sur 7500 images prises aléatoirement 1: 547 2: 530 3: 198 4: 763 5: 544 6: 663 7: 494 8: 525 9: 996 10: 336 11: 1116 12: 902

Slide 50

Slide 50 text

Résultat de l’analyse de la forme 50

Slide 51

Slide 51 text

Résultat de l’analyse de la forme 51

Slide 52

Slide 52 text

IHM 52

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text