/
obsdef.py
147 lines (123 loc) · 4.85 KB
/
obsdef.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# %%markdown
OperationDefinition for creating a spreadsheet based approach to generate Observations
See discussion on Zulip regarding the common and simple need for a way to use ObservationDefinition as table or spreadsheet to create Observation instances based on a few 'base' profiles.
This Gist walks through creating a Spreadsheet based on my ObservationDefinition Logical Model which is a major redo of the existing one. Then using the spreadsheet to create several Observation instances which are ready to be populated with lab data.
The idea id ObservationDefinition needs to be structured simply and flat enough to be able to directly transform the stuff you need for creating a table.
the table is like a Dictionary of Observations for use and is a shortcut to creating 100s or 1000s of profiles.
The following proof of concept Python script takes this spreadsheet as an Excel spreadsheet (not a google sheet) and generates profile types (in the output console).
# %%markdown
od table proof of concept:read obs-def from a spreadsheet ('Dictionary' or 'Lbrary')
and apply to Obs Profile instance "template" which is ready to be filled with the data to create an Observation instance
run in python 3.6
Outline:
1.read row from od spreadsheets as dict
2.apply od spreadsheet data to named profile (SD)
3. write/display profile
# %%
# imports
import json, os, sys
from csv import DictReader
from pandas import read_csv
import logging
# logging.disable(logging.CRITICAL)
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.debug('Start of program')
logging.info('The logging module is working.')
# %%
# global variables and templates
in_path = '/Users/ehaas/Documents/Python/Notebooks/OD - od.csv'
sheet_name = 'od'
logging.info('source spreadsheet = {}'.format(source_spreadsheet))
outfile = 'outfile' # name of output file
# %%
#********************* get patient data **********************
# preview data from csv file )
df1 = read_csv(in_path)
df1
# %%
def getitems(): # read rows from od spreadsheets... ( row 0 = headers, row 1 = description )
with open(in_path, mode='r',encoding='utf-8-sig') as csv_file:
csv_reader = DictReader(csv_file)
return(csv_reader)
for item in getitems():
print(item)
# %%
def getobs(r):# apply od spreadsheet data to profile
obs = '''{{
"resourceType": "Observation",
"meta": {{ "profile": ["http://hl7.org/fhir/us/core/StructureDefinition/us-core-observationresults"],
}},
"status": "{status}",
"category": {{
"coding": [
{{
"system": "http://hl7.org/fhir/observation-category",
"code": "laboratory",
"display": "Laboratory"
}}
],
"text": "Laboratory"
}},
"code": {{
"coding": [
{{
"system": "http://loinc.org",
"code": "{codeCoding_0_Code}",
"display": "{codeCoding_0_Display}"
}}
],
"text": "{codeText}"
}},
"subject": {{
"reference": "Patient/example","display": "Amy Shaw"
}},
"effectiveDateTime": "{effectiveDateTime}",
"valueQuantity": {{
"value": "{resultValue}",
"unit": "{unitUnit}",
"system": "{unitCodeSystem}"
"code": "{unitCodeCode}"
}},
"referenceRange": [
{{
"low": {{
"value": {refLow},
"unit": "{unitUnit}",
"system": "{unitCodeSystem}"
"code": "{unitCodeCode}"
}},
"high": {{
"value": {refHigh},
"unit": "{unitUnit}",
"system": "{unitCodeSystem}"
"code": "{unitCodeCode}"
}},
"type": {{
"coding": [
{{
"system": "http://hl7.org/fhir/referencerange-meaning",
"code": "{refType}",
}}
],
}}
]
}}'''
new_obs = obs.format(status='{status}', effectiveDateTime='{effectiveDateTime}', resultValue='{resultValue}', **r)
return(new_obs)
# %%
# get main
def main():
logging.info('read rows from od spreadsheets')
rows = getitems()
for i, r in enumerate(rows[1:]): #skip first one
logging.info('row {} from od spreadsheets = {}'.format(i,r))
for d in r:
logging.info('{} = {}'.format(d,r[d]))
logging.info('apply od spreadsheet data to profile TODO fix decimal typing right now all as string')
new_obs = getobs(r)
logging.info('new_obs = {}'.format(new_obs))
# %%
if __name__ == '__main__':
qr_json = main()
logging.info('End of program')
When used with the sample spreadsheet, the script output the following 3 Observations profiles which a fully specified except for the actual Observation 'instance' data. I.e, dates, patient, status, actual result value, comments, dataabsentreason etc.