saxofornQ42021.py (8691B)
1 #!/usr/bin/env python 2 # coding=utf-8 3 # 4 # © 2019-2022 Christoph Lohmann <20h@r-36.net> 5 # 6 # This file is published under the terms of the GPLv3. 7 # 8 9 import os 10 import sys 11 import getopt 12 import codecs 13 from datetime import datetime 14 import operator 15 16 # Return num of patients who have one occurence of some ebmcodes. 17 def ebmcodeoccurence(container, ebmcodes): 18 occurence = 0 19 for sentence in container["sentences"]: 20 found = 0 21 for field in sentence["fields"]: 22 if field[0] == 5001: 23 if field[1] in ebmcodes: 24 if found == 0: 25 occurence += 1 26 found = 1 27 return occurence 28 29 # Return sum of all occurences of some ebmcodes. 30 def ebmcodesumoccurence(container, ebmcodes): 31 occurence = 0 32 for sentence in container["sentences"]: 33 for field in sentence["fields"]: 34 if field[0] == 5001: 35 if field[1] in ebmcodes: 36 occurence += 1 37 return occurence 38 39 def printcode(codesdb, code): 40 if code in codesdb: 41 print("%s = %d" % (code, codesdb[code])) 42 else: 43 print("%s = 0" % (code)) 44 45 def printcodes(codesdb, codes): 46 for code in codes: 47 printcode(codesdb, code) 48 49 def sentence2dict(sentence): 50 rdict = {} 51 52 if not "fields" in sentence: 53 return rdict 54 55 for field in sentence["fields"]: 56 fstr = "%s" % (field[0]) 57 if not fstr in rdict: 58 rdict[fstr] = [] 59 rdict[fstr].append(field[1]) 60 61 return rdict 62 63 def parse_xdt(line): 64 length = int(line[:3]) 65 fieldid = int(line[3:7]) 66 fcontent = line[7:-2] 67 68 if length != len(line): 69 print("Invalid line: %s\n" % (line[:-2])) 70 71 return (length, fieldid, fcontent) 72 73 def usage(app): 74 app = os.path.basename(app) 75 print("usage: %s [-h] adt.con" % (app), file=sys.stderr) 76 sys.exit(1) 77 78 def main(args): 79 try: 80 opts, largs = getopt.getopt(args[1:], "h") 81 except getopt.GetoptError as err: 82 print(str(err)) 83 usage(args[0]) 84 85 for o, a in opts: 86 if o == "-h": 87 usage(args[0]) 88 else: 89 assert False, "unhandled option" 90 91 if len(largs) < 1: 92 usage(args[0]) 93 94 # Aerzte 95 besa = {} 96 # Betriebsstaette 97 rvsa = {} 98 # PVS-Hersteller 99 adt0 = {} 100 101 begin = datetime.now() 102 lines = 0 103 containers = [] 104 container = {} 105 sentence = {} 106 with codecs.open(largs[0], "r", "iso8859-15") as fd: 107 for line in fd: 108 (length, fieldid, fcontent) = parse_xdt(line) 109 lines += 1 110 111 #print((length, fieldid, fcontent)) 112 if fieldid == 8000: 113 if fcontent == "con0": 114 container["name"] = fcontent 115 container["sentences"] = [] 116 container["fields"] = [] 117 elif fcontent == "con9": 118 if sentence != {}: 119 container["sentences"].append(sentence) 120 containers.append(container) 121 container = {} 122 sentence = {} 123 elif fcontent == "adt9": 124 if sentence != {}: 125 container["sentences"].append(sentence) 126 continue 127 elif fcontent == "kad9": 128 if sentence != {}: 129 container["sentences"].append(sentence) 130 continue 131 elif fcontent == "sad9": 132 if sentence != {}: 133 container["sentences"].append(sentence) 134 continue 135 else: 136 sentence = {} 137 sentence["name"] = fcontent 138 sentence["fields"] = [] 139 container["sentences"].append(sentence) 140 141 # Filter out special data. 142 if sentence["name"] == "besa": 143 besa = sentence 144 elif sentence["name"] == "rvsa": 145 rvsa = sentence 146 elif sentence["name"] == "adt0": 147 adt0 = sentence 148 continue 149 else: 150 if "fields" in sentence: 151 sentence["fields"].append([fieldid, 152 fcontent]) 153 else: 154 container["fields"].append([fieldid, 155 fcontent]) 156 157 besa = sentence2dict(besa) 158 rvsa = sentence2dict(rvsa) 159 adt0 = sentence2dict(adt0) 160 161 ambscheine = 0 162 notfallscheine = 0 163 ueberweisungen = 0 164 belegarztscheine = 0 165 for sentence in containers[0]["sentences"]: 166 if sentence["name"] == "0101": 167 ambscheine += 1 168 elif sentence["name"] == "0104": 169 notfallscheine += 1 170 elif sentence["name"] == "0102": 171 ueberweisungen += 1 172 elif sentence["name"] == "0103": 173 belegarztscheine +=1 174 175 gesamtscheine = ambscheine + notfallscheine + ueberweisungen + \ 176 belegarztscheine 177 178 # Anonymisation dictionaries. 179 # All ICD codes, multiple codes per patient. 180 icdcodes = {} 181 # ICD codes, one per patient. 182 icdcodespp = {} 183 # All EBM codes, multiple codes per patient. 184 ebmcodes = {} 185 # EBM codes, one per patient. 186 ebmcodespp = {} 187 188 for sentence in containers[0]["sentences"]: 189 icdcodefound = 0 190 ebmcodefound = 0 191 for field in sentence["fields"]: 192 if field[0] == 5001: 193 if field[1] in ebmcodes: 194 ebmcodes[field[1]] += 1 195 else: 196 ebmcodes[field[1]] = 1 197 198 if ebmcodefound == 0: 199 if field[1] in ebmcodespp: 200 ebmcodespp[field[1]] += 1 201 else: 202 ebmcodespp[field[1]] = 1 203 else: 204 ebmcodefound = 1 205 elif field[0] == 6001: 206 if field[1] in icdcodes: 207 icdcodes[field[1]] += 1 208 else: 209 icdcodes[field[1]] = 1 210 211 if icdcodefound == 0: 212 if field[1] in icdcodespp: 213 icdcodespp[field[1]] += 1 214 else: 215 icdcodespp[field[1]] = 1 216 else: 217 icdcodefound = 1 218 219 def sortdict(d): 220 return sorted(d.items(), key=lambda kv: kv[1])[::-1] 221 222 oicdcodes = sortdict(icdcodes) 223 oebmcodes = sortdict(ebmcodes) 224 225 print("SaxoForN-Datenerhebung:") 226 print("") 227 228 print("1.) PVS") 229 pvshersteller = None 230 if "111" in adt0: 231 if "dv@data-vital.de" in adt0["111"][0]: 232 pvshersteller = "DATA VITAL" 233 print("PVS-Hersteller = %s" % (pvshersteller)) 234 print("") 235 236 print("2.) Gesamtscheine") 237 # KBV_ITA_VGEX_Datensatzbeschreibung_KVDT.pdf#S27 238 print("amb. Scheine ..... %d" % (ambscheine)) 239 print("Notfallscheine ... %d" % (notfallscheine)) 240 print("Ueberweisungen ... %d" % (ueberweisungen)) 241 print("Belegarztscheine . %d" % (belegarztscheine)) 242 print("=========================") 243 print("Gesamtscheine .... %d" % (gesamtscheine)) 244 print("") 245 246 print("3.) Grundpauschalen") 247 for grundpauschale in ["03001", "04001", "03002", "04002",\ 248 "03003", "04003", "03004", "04004", "03005",\ 249 "04005"]: 250 printcode(ebmcodespp, grundpauschale) 251 print("") 252 253 print("4.) Einweisungen") 254 # TODO: Parse BDT. 255 # In Bemerkungsfeld: 256 # Einweisungen: "KH:" 257 # Ueberweisungen: "UE:" 258 # Krankschreibung: "AU:" 259 # Transportschein: "TA:" 260 # Laborbemerkung: "UL:" 261 print("Bitte Einweisungen aus PVS heraussuchen.") 262 print("") 263 264 print("5.) COVID-19 Nachweise, PCR-Teste") 265 printcode(ebmcodespp, "88315") 266 sachsencovid19 = ["99136", "88240", "02402"] 267 print("Sachsen: %s = %d" % (sachsencovid19,\ 268 ebmcodeoccurence(containers[0], sachsencovid19))) 269 hessencovid19 = ["88240", "02402"] 270 print("Hessen: %s = %d" % (hessencovid19,\ 271 ebmcodeoccurence(containers[0], hessencovid19))) 272 print("") 273 274 print("6.) COVID-19 ICDs") 275 for covid19icd in ["U07.1", "U07.2", "U09.9", "U12.9"]: 276 printcode(icdcodes, covid19icd) 277 print("") 278 279 print("7.) Telefonsprechstunde") 280 printcode(ebmcodes, "01434") 281 print("Bitte Verschreibungen App auf Rezept heraussuchen.") 282 print("") 283 284 print("8.) Videosprechstunde") 285 videosprechstunde = ["01450", "40129", "40128", "01444",\ 286 "01442"] 287 print("EBM-Codes: %s = %d" % (videosprechstunde,\ 288 ebmcodeoccurence(containers[0],\ 289 videosprechstunde))) 290 print("Bitte Videosprechstundeanbieter heraussuchen.") 291 print("") 292 293 print("9.) Hausbesuche") 294 arzthausbesuche = ["01410", "01411", "01412", "01413", "01415"] 295 naepahausbesuche = ["03062", "03063", "38100"] 296 impfhausbesuche = ["88323", "88324"] 297 298 print("Arzthaubesuche: %s = %d" % (arzthausbesuche, 299 ebmcodesumoccurence(containers[0], arzthausbesuche))) 300 print("Naepahaubesuche: %s = %d" % (naepahausbesuche, 301 ebmcodesumoccurence(containers[0], naepahausbesuche))) 302 print("Impfhausbesuche: %s = %d" % (impfhausbesuche, 303 ebmcodesumoccurence(containers[0], impfhausbesuche))) 304 print("") 305 306 print("10.) elektronische Patientenakte") 307 print("Wird die ePA genutzt?") 308 printcode(ebmcodes, "88270") 309 print("Welche Anschaffungen besitzen Sie?") 310 print("") 311 312 print("11.) COVID-19-Impfungen") 313 biontech = ["88331A", "88331B", "88331R",\ 314 "88331G", "88331H", "88331K",\ 315 "88331V", "88331W", "88331X"] 316 printcodes(ebmcodes, biontech) 317 moderna = ["88332A", "88332B", "88332R",\ 318 "88332G", "88332H", "88332K",\ 319 "88332V", "88332W", "88332X"] 320 printcodes(ebmcodes, moderna) 321 astrazeneca = ["88333A", "88333B", "88333R",\ 322 "88333G", "88333H", "88333K",\ 323 "88333V", "88333W", "88333X"] 324 printcodes(ebmcodes, astrazeneca) 325 johnsonjohnson = ["88334", "88334R",\ 326 "88334I", "88334K",\ 327 "88334Y", "88334X"] 328 printcodes(ebmcodes, johnsonjohnson) 329 print("") 330 331 print("12.) Influenza-Impfungen") 332 influenza = ["89111", "89111S", "89112", "89112Y"] 333 printcodes(ebmcodes, influenza) 334 print("") 335 336 print("13.) Pneumokokken-Impfung") 337 pneumokokken = ["89119", "89119R",\ 338 "89120", "89120R",\ 339 "89120V", "89120X"] 340 printcodes(ebmcodes, pneumokokken) 341 print("") 342 343 return 0 344 345 if __name__ == "__main__": 346 sys.exit(main(sys.argv)) 347