Skip to content

Commit 65cfa64

Browse files
committed
updated to export CMS JSON
dual pass process. ToDo: - fix claims sections - fix Emergency Contact - fix immunizations - fix labs Fixed: - Dates to ISO format YYYYMMDD - Header section writes PRE Section from SEG_DEF - Address block is a packaged dict
1 parent 922a894 commit 65cfa64

File tree

6 files changed

+1314
-241
lines changed

6 files changed

+1314
-241
lines changed
File renamed without changes.

bluebutton/bbp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666

6767
if outtype == "CMSFILE":
6868
demodict = cms_file_read(infile)
69-
result = write_file(demodict, outfile)
69+
outdict = parse_lines(demodict)
70+
result = write_file(outdict, outfile)
7071

7172
except():
7273
print "An unexpected error occurred. Here is the post-mortem:"

bluebutton/cms_parser.py

Lines changed: 89 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
import json
1414
import re
1515
import os, sys
16-
from datetime import datetime, date, timedelta
1716

1817
import collections
18+
from cms_parser_utilities import *
1919

2020

2121
from file_def_cms import SEG_DEF
22+
from cms_parser_utilities import *
2223

2324
# divider = "--------------------------------"
2425
divider = "----------"
@@ -149,9 +150,96 @@ def cms_file_read(inPath):
149150
#print blank_ln, "skipped"
150151

151152
#print f_lines
153+
#print ""
154+
152155

153156
return f_lines
154157

158+
def parse_lines(ln_list):
159+
# Receive list created in cms_file_read
160+
# Build the final Json dict
161+
# Use SEG_DEF to control JSON construction
162+
163+
# set variables
164+
DBUG = False
165+
166+
ln = {}
167+
ln_ctrl = {}
168+
169+
k = ""
170+
v = ""
171+
lk_up = ""
172+
current_segment = ""
173+
174+
match_ln = [None, None, None, None, None, None, None, None, None, None]
175+
176+
segment_dict = collections.OrderedDict()
177+
out_dict = collections.OrderedDict()
178+
# Set starting point in list
179+
i = 0
180+
181+
# while i <= 30: #(len(ln_list)-1):
182+
while i <= (len(ln_list) - 1):
183+
# process each line in the list until end of list
184+
185+
ln = get_line_dict(ln_list,i)
186+
187+
line = ln["line"].split(":")
188+
if len(line) > 1:
189+
# Assign line[0] to k and format as headlessCamel
190+
k = headlessCamel(line[0])
191+
v = line[1].lstrip()
192+
v = v.rstrip()
193+
194+
if DBUG:
195+
print i, "ln:", ln, "k:", k, "v:", v
196+
197+
# lookup ln in SEG_DEF
198+
lk_up = headlessCamel(ln["line"])
199+
if find_segment(lk_up):
200+
201+
ln_ctrl = get_segment(lk_up)
202+
if DBUG:
203+
print i, "ln_ctrl-match:", ln_ctrl
204+
205+
# We found a match in SEG_DEF
206+
# So we use SEG_DEF to tailor how we write the line and
207+
# section since a SEG_DEF typically defines special processing
208+
209+
210+
current_segment = ln_ctrl["name"]
211+
212+
print "================"
213+
print "Match:", match_ln
214+
print "ln-ctrl:", ln_ctrl
215+
print "================"
216+
217+
i, sub_seg, seg_name = process_segment(i, ln_ctrl, match_ln, ln["level"], ln_list)
218+
219+
print "segment returned", seg_name, ":", sub_seg
220+
#print "-------------"
221+
#print "Returned with ctr-i:", i
222+
#print "segment_dict:", segment_dict
223+
#print "-------------"
224+
out_dict[seg_name] = sub_seg
225+
226+
# if DBUG:
227+
# print "Out:", current_segment, " =", out_dict[current_segment]
228+
229+
else:
230+
# No special instructions
231+
# assume writing a string split on ":"
232+
233+
print "Other - i:", i, "ln:", ln
234+
out_dict[current_segment] = {k: v}
235+
236+
# increment line counter
237+
i += 1
238+
239+
if DBUG:
240+
print "End of list "
241+
242+
return out_dict
155243

156244
def cms_file_parse2(inPath):
157245
# Parse a CMS BlueButton file (inPath)
@@ -556,115 +644,15 @@ def cms_file_parse(inPath):
556644
return items
557645

558646

559-
def headlessCamel(In_put):
560-
# Use this to format field names:
561-
# Convert words to title format and remove spaces
562-
# Remove underscores
563-
# Make first character lower case
564-
# result result
565-
566-
Camel = ''.join(x for x in In_put.title() if not x.isspace())
567-
Camel = Camel.replace('_', '')
568-
result = Camel[0].lower() + Camel[1:len(Camel)]
569-
570-
# print "headlessCamel:", result
571-
return result
572647

573648
def set_header_line(hl):
574649
# flip header_line value. received as hl (True or False)
575650

576651
return (not hl)
577652

578653

579-
def write_segment(itm, sgmnt, sgmnt_dict, ln_list, multi):
580-
# Write the segment to items dict
581-
# print "Writing Segment:", sgmnt
582-
# print "Adding:", sgmnt_dict
583-
584-
# print "============================"
585-
# print "Writing Seg:",sgmnt
586-
# print "============================"
587-
# print "Writing dict:"
588-
# print sgmnt_dict
589-
# print "============================"
590-
if multi:
591-
ln_list.append(sgmnt_dict)
592-
print "Multi List:", ln_list
593-
itm[sgmnt] = ln_list
594-
else:
595-
itm[sgmnt] = sgmnt_dict
596-
597-
return itm, sgmnt_dict, ln_list
598-
599-
600-
def get_segment(title):
601-
602-
result = {}
603-
# cycle through the seg dictionary to match against title
604-
for ky in SEG_DEF:
605-
if title in ky["match"]:
606-
result = ky
607-
break
608-
609-
return result
610-
611-
def find_segment(title):
612-
613-
result = False
614-
for ky in SEG_DEF:
615-
# print k
616-
if title in ky["match"]:
617-
# print "Match: %s : %s" % (title, ky['key'])
618-
result = True
619-
break
620-
621-
return result
622-
623-
def parse_time(t):
624-
# convert time to json format
625-
t = t.strip()
626-
time_value = datetime.strptime(t, "%m/%d/%Y %I:%M %p")
627-
# print time_value
628-
return_value = time_value.strftime("%Y%m%d%H%M%S+0500")
629-
630-
# print return_value
631-
return return_value
632-
633-
def segment_prefill(seg):
634-
# Receive the Segment information for a header line
635-
# get the seg["pre"] and iterate through the dict
636-
# assigning to segment_dict
637-
# First we reset the segment_dict as an OrderedDict
638-
segment_dict = collections.OrderedDict()
639654

640-
# print seg
641655

642-
current_segment = seg["name"]
643-
if "pre" in seg:
644-
pre = seg["pre"]
645-
# print pre
646-
for pi, pv in pre.iteritems():
647-
# print pi,":" ,pv
648-
segment_dict[pi] = pv
649-
650-
return current_segment, segment_dict
651-
652-
def set_source(current_source, key, value):
653-
# Set the source of the data
654-
655-
if key.upper() == "SOURCE":
656-
result = ""
657-
# print "Found Source: [%s:%s]" % (key,value)
658-
if value.upper() == "SELF-ENTERED":
659-
result = "patient"
660-
elif value.upper() == "MYMEDICARE.GOV":
661-
result = "MyMedicare.gov"
662-
else:
663-
result = value.upper()
664-
# print "[%s]" % result
665-
return result
666-
else:
667-
return current_source
668656

669657
def multi_item(seg):
670658
# check for "multi" in seg dict

0 commit comments

Comments
 (0)