Technische Informationen ======================== Das Addin dient zur Umformatierung von Laborwerten in Arztbriefen. Es analysiert die Ausgabe von Lauris in der Zentralen Arztbriefablage, die typischerweise so aussieht: [20.06.2015 16:46:00] Klinische Chemie: Natrium: 139 [135 - 145] mmol/l;  Kalium: 5.2 [3.5 - 5] mmol/l;  Calcium: 2.4 [2.0 - 2.7] mmol/l;  anorg. Phosphat: 0.58 [0.87 - 1.45] mmol/l;  Calcium-Phosphat-Produkt: 1.39 [<= 4.4] mmol²/l²;  Glucose: 112 [74 - 106] mg/dl;  glomerul. Filtrationsr. CKD-EP: 42 ml/min /1,73qm;  glomerul. Filtrationsr. (MDRD): 42 ml/min /1,73qm;  Creatinin: 1.84 [0 - 1.17] mg/dl;  Harnstoff: 54.3 [10 - 50] mg/dl;  Harnsäure: 4.6 [3.4 - 7] mg/dl;  Gesamt-Bilirubin: 0.7 [0.1 - 1.2] mg/dl;  GOT (ASAT): 303.0 [<= 50] U/l;  GPT (ALAT): 508.0 [<= 50] U/l;  GGT: 489.0 [<= 60] U/l;  Alk. Phosphatase: 56 [40 - 130] U/l;  Lactat Dehydrogenase: 320 [<= 250] U/l;  CK gesamt: 52 [<= 190] U/l;  Amylase: 62 [<= 110] U/l;  Cholesterin: 120 [130 - 220] mg/dl;  Triglyceride: 94 [74 - 172] mg/dl;  LDL - Cholesterin: 56 [0 - 150] mg/dl;  HDL - Cholesterin: 45 [>= 35] mg/dl;  Eisen: 215 [59 - 158] µg/dl;  Gesamt-Eiweiss: 5.7 [6.6 - 8.7] g/dl;  Albumin: 4.0 [3.5 - 5.5] g/dl; Gerinnung: Niedermol. Heparin (Anti-Xa): 0.99 U/ml; Und so weiter, es gibt noch mehr Variationen. ## Programmteile Im Sinne einer _separation of concerns_ ist die Programmlogik in folgende Teile aufgeteilt: - __Labor-Modell:__ Im Namensraum `zaaReloaded2.LabModel` sind Klassen gruppiert, die einen Laborwert abbilden (`zaaReloaded2.LabModel.LabItem`), die die Laborwerte eines Auftrags (der zu einem bestimmten Zeitpunkt eingelesen wurde) sammeln (`zaaReloaded2.LabModel.TimePoint`), und schließlich eine Klasse `zaaReloaded2.LabModel.Laboratory`, die die Aufträge (`TimePoint`s) sammelt. Jeder Laborwert kann mit Hilfe eines Wörterbuchs (s.u.) einen kanonischen Namen erhalten (z.B. "Na" für "Natrium"), über den dieser Wert dann angesprochen wird. Die einzelnen Aufträge/Zeitpunkte werden über `DateTime`-Strukturen angesprochen. - __Import:__ Im Namensraum `zaaReloaded2.Importer` befindet sich eine Interface-Definition (`zaaReloaded2.Importer.IImporter`), die zentrale Eigenschaften von Importer-Klassen definiert. Der Namensraum `zaaReloaded2.Importer.ZaaImporter` enthält Klassen, die den Import einer Lauris-Ausgabe aus einem ZAA-Arztbrief erledigen. - __Formatierung und Ausgabe:__ Der Namensraum `zaaReloaded2.Formatter` versammelt Klassen, die vom Benutzer eingegebene Steuerbefehle auswerten und die Formatierung der Laborwerte erledigen. Durch die Verwendung von Steuerbefehlen können leicht verschiedene Ausgabeformate erstellt werden, z.B. eines für die Station und eines für die Ambulanz. Zur Formatierung und Ausgabe existieren verschiedene Klassen, die die Klassen des Labor-Modells (`zaaReloaded2.LabModel`) umschließen und um entsprechende Funktionalitäten erweitern. ## Parsen der Lauris-Ausgabe Die Lauris-Ausgabe wird in folgende Einheiten aufgetrennt: - __Datumsblöcke:__ Die Klasse `zaaReloaded2.Models.TimePoint` enthält alles, was unterhalb der Datumszeile `[20.06.2015 16:46:00]` steht. - __Kategorieblöcke:__ Die Klasse `zaaReloaded2.Models.LaurisParagraph` analysiert einen ganzen Laborblock wie z.B. `Klinische Chemie` oder `Gerinnung` und trennt ihn anhand der Semikolons, um daraus eine Sammlung von `LabItems` zu bilden. - __Parameter:__ Die Klasse `zaaReloaded2.Models.LabItem` analysiert einen einzelnen Parameter-String der Form `Natrium: 138 [135 - 145] mmol/l` usw. und stellt die einzelnen Bestandteile in strukturierter Form zur Verfügung. ## Kanonische Namen, Materialarten, Thesauri Die Bezeichnungen für einzelne Parameter und Einheiten sind bei Lauris teilweise etwas unglücklich. Beispielsweise wird `glomerul. Filtrationsr. CKD-EP` wohl kaum im klinischen Alltag verwendet, und auch `Lactat Dehydrogenase` ist etwas ungewöhnlich, weil alle immer `LDH` sagen und schreiben. Die Einheit `ml/min /1,73qm` enthält ein Leerzeichen zuviel und das veraltete "qm" und sollte besser `ml/min/1,73 m²` geschrieben werden. Aus diesem Grunde werden anpassbare Thesauri verwendet, die Parameternamen in "kanonische" (CanonicalName) und Lauris-Einheiten in wirklichkeitsnähere, typographisch korrekte Einheiten übersetzen: - `zaaReloaded2.Thesaurus.Parameters` - `zaaReloaded2.Thesaurus.Units` Beide Thesaurus-Typen laden zunächst eingebaute Default-Werte aus der Assembly und suchen dann nach Anpassungen auf Benutzerebene. ### Material Im Thesaurus `Parameters` wird für jeden Parameter neben dem Kanonischen Namen auch hinterlegt, aus welchem Material er bestimmt wird. Beim Parsen der Lauris-Ausgabe wird festgelegt, um welches Material es sich handelt. Auf diese Weise wird ermöglicht, bei der späteren Ausgabe mit einfacher Notation z.B. zwischen Serum-Natrium (`S-Na`) und Urin-Natrium (`U-Na`) bzw. Sammelurin-Natrium (`SU-Na`) zu unterscheiden. Die Materialien sind in der Enumeration `zaaReloaded2.Models.Materials` definiert. ### Textdateien zur Konfiguration Um Anpassungen zu erleichtern und nicht jedes Mal eine neue Version der Binärdateien zu erfordern, werden für die Thesauri einfache Textdateien verwendet. - Datensätze in Zeilen - Felder in durch Leerzeichen getrennten Zeilen - Leerzeichen in Werten erfordern Anführungstriche (Bsp. s.u.) - Drei Trennstriche `---` markieren ein leeres Feld. - Alles nach einer Raute `#` wird ignoriert - Leere Zeilen werden ignoriert ### Parameters Der Thesaurus `Parameters` wird aus einer Textdatei folgenden Formats generiert: # LAURIS-NAME "KANONISCHER NAME" MATERIAL "IMMER REFERENZBEREICH" "Lactat Dehydrogenase" LDH S "Cystatin C" --- S X "glomerul. Filtrationsr. CKD-EP" "eGFR (CKD-EPI)" S Das Feld `MATERIAL` muß ein Material-Kürzel enthalten (zu Materialien siehe oben). Die Material-Kürzel sind fest einprogrammiert (s.o.). Wenn kein Material angegeben ist (in der Spalte also gar nichts steht oder `---`), wird _Serum_ angenommen, weil das das häufigste ist. Wenn `IMMER REFERENZBEREICH` leer ist, wird "nein" angenommen. Alles andere wie z.B. `X` bedeutet "ja". Die drei Trennstriche `---` in der Zeile "Cystacin C" bedeuten, daß zaaReloaded2 den Lauris-Namen als kanonischen Namen verwenden soll. ### Units Der Thesaurus `Units` wird aus einer Textdatei folgenden Formats generiert: # LAURIS-EINHEIT "KANONISCHE EINHEIT" ml/min /1,73qm ml/min/1,73 m² Wenn eine Lauris-Einheit nicht in dieser Tabelle enthalten ist, wird sie so, wie sie ist, für die Ausgabe von zaaReloaded2 verwendet. ## Referenzbereiche Wenn bei jedem Laborparameter die Referenzbereiche angegeben werden, wird die Ausgabe unübersichtlich -- siehe Lauris. Viele Laborparameter haben Standard-Referenzbereiche, die sich zwischen den Laboren nicht oder nur geringfügig unterscheiden (bspw. Hämoglobin). zaaReloaded2 kann so konfiguriert werden, daß Referenzbereiche entweder nie, nur bei gesondert markierten Parametern, bei gesondert markierten oder nicht-normalen Parametern oder immer mit ausgegeben werden: - nie - besondere Parameter (z.B. Cystatin C, wo viele den Referenzbereich nicht kennen dürften) - besondere Parameter + nicht-normale Parameter - immer Die Markierung besonderer Parameter erfolgt in der Textdatei, aus der das `zaaReloaded2.Thesaurus.Parameters` generiert wird (s.o.). ## Serialisierung Um das Stil-Repositorium (`zaaReloaded2.Controller.SettingsRepository`) in den Assembly-Properties speichern zu können und für den Im- und Export von Stilen werden die in .NET eingebauten Serialisierungs-Strukturen genutzt. Weil es mit der Verwendung eines `XmlSerializer`s Probleme gab, weil der `XmlSerializer` nicht mit Interface-Eigenschaften umgehen kann, wurde zunächst für alle Klassen, die serialisiert werden müssen (`SettingsRepository`, `zaaReloaded2.Controller.Settings` und die von `zaaReloaded2.Controller.Elements.ElementBase` abgeleiteten Klassen) das Interface `ISerializable` implementiert. Das hat aber auch nicht dazu geführt, daß der `XmlSerializer` die Klassen serialisierte, so daß jetzt der `SoapFormatter` verwendet wird. Der stört sich nicht an Interface-Eigenschaften und produziert auch XML, wenngleich im etwas komplizierten [SOAP][]-Format. Um das `SettingsRepository` in den Assembly-Properties zu persistieren, muß das serialisierte XML noch in einen Base64-kodierten String umgewandelt werden, damit das SOAP-XML nicht mit dem XML der Assembly-Properties ins Gehege kommt (siehe `zaaReloaded2.Controller.SettingsRepository.Load()` und `zaaReloaded2.Controller.SettingsRepository.Store()`). [SOAP]: http://de.wikipedia.org/wiki/SOAP