saxoforn

SaxoForN data extraction tool
git clone git://arztpraxis-lohmann.de/saxoforn
Log | Files | Refs | LICENSE

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