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