1 """GNUmed clinical narrative business object.
2
3 """
4
5 __version__ = "$Revision: 1.45 $"
6 __author__ = "Carlos Moro <cfmoro1976@yahoo.es>, Karsten Hilbert <Karsten.Hilbert@gmx.net>"
7 __license__ = 'GPL (for details see http://gnu.org)'
8
9 import sys, logging
10
11
12 if __name__ == '__main__':
13 sys.path.insert(0, '../../')
14 from Gnumed.pycommon import gmPG2, gmExceptions, gmBusinessDBObject, gmTools
15
16 try:
17 _('dummy-no-need-to-translate-but-make-epydoc-happy')
18 except NameError:
19 _ = lambda x:x
20
21 _log = logging.getLogger('gm.emr')
22 _log.info(__version__)
23
24
25 soap_cat2l10n = {
26 's': _('soap_S').replace(u'soap_', u''),
27 'o': _('soap_O').replace(u'soap_', u''),
28 'a': _('soap_A').replace(u'soap_', u''),
29 'p': _('soap_P').replace(u'soap_', u''),
30
31 None: gmTools.u_ellipsis
32 }
33
34 soap_cat2l10n_str = {
35 's': _('soap_Subjective').replace(u'soap_', u''),
36 'o': _('soap_Objective').replace(u'soap_', u''),
37 'a': _('soap_Assessment').replace(u'soap_', u''),
38 'p': _('soap_Plan').replace(u'soap_', u''),
39 None: _('soap_Administrative').replace(u'soap_', u'')
40 }
41
42 l10n2soap_cat = {
43 _('soap_S').replace(u'soap_', u''): 's',
44 _('soap_O').replace(u'soap_', u''): 'o',
45 _('soap_A').replace(u'soap_', u''): 'a',
46 _('soap_P').replace(u'soap_', u''): 'p',
47
48 gmTools.u_ellipsis: None
49 }
50
51 -class cDiag(gmBusinessDBObject.cBusinessDBObject):
52 """Represents one real diagnosis.
53 """
54 _cmd_fetch_payload = u"select *, xmin_clin_diag, xmin_clin_narrative from clin.v_pat_diag where pk_diag=%s"
55 _cmds_store_payload = [
56 u"""update clin.clin_diag set
57 laterality=%()s,
58 laterality=%(laterality)s,
59 is_chronic=%(is_chronic)s::boolean,
60 is_active=%(is_active)s::boolean,
61 is_definite=%(is_definite)s::boolean,
62 clinically_relevant=%(clinically_relevant)s::boolean
63 where
64 pk=%(pk_diag)s and
65 xmin=%(xmin_clin_diag)s""",
66 u"""update clin.clin_narrative set
67 narrative=%(diagnosis)s
68 where
69 pk=%(pk_diag)s and
70 xmin=%(xmin_clin_narrative)s""",
71 u"""select xmin_clin_diag, xmin_clin_narrative from clin.v_pat_diag where pk_diag=%s(pk_diag)s"""
72 ]
73
74 _updatable_fields = [
75 'diagnosis',
76 'laterality',
77 'is_chronic',
78 'is_active',
79 'is_definite',
80 'clinically_relevant'
81 ]
82
84 """
85 Retrieves codes linked to this diagnosis
86 """
87 cmd = u"select code, coding_system from clin.v_codes4diag where diagnosis=%s"
88 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self._payload[self._idx['diagnosis']]]}])
89 return rows
90
91 - def add_code(self, code=None, coding_system=None):
92 """
93 Associates a code (from coding system) with this diagnosis.
94 """
95
96 cmd = u"select clin.add_coded_phrase (%(diag)s, %(code)s, %(sys)s)"
97 args = {
98 'diag': self._payload[self._idx['diagnosis']],
99 'code': code,
100 'sys': coding_system
101 }
102 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
103 return True
104
105 -class cNarrative(gmBusinessDBObject.cBusinessDBObject):
106 """Represents one clinical free text entry.
107 """
108 _cmd_fetch_payload = u"select *, xmin_clin_narrative from clin.v_pat_narrative where pk_narrative=%s"
109 _cmds_store_payload = [
110 u"""update clin.clin_narrative set
111 narrative = %(narrative)s,
112 clin_when = %(date)s,
113 soap_cat = lower(%(soap_cat)s),
114 fk_encounter = %(pk_encounter)s
115 where
116 pk=%(pk_narrative)s and
117 xmin=%(xmin_clin_narrative)s""",
118 u"""select xmin_clin_narrative from clin.v_pat_narrative where pk_narrative=%(pk_narrative)s"""
119 ]
120
121 _updatable_fields = [
122 'narrative',
123 'date',
124 'soap_cat',
125 'pk_episode',
126 'pk_encounter'
127 ]
128
129
130
131
132
134 """Retrieves codes linked to *this* narrative.
135 """
136 cmd = u"select code, xfk_coding_system from clin.coded_phrase where term=%s"
137 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self._payload[self._idx['narrative']]]}])
138 return rows
139
140 - def add_code(self, code=None, coding_system=None):
141 """
142 Associates a code (from coding system) with this narrative.
143 """
144
145 cmd = u"select clin.add_coded_phrase (%(narr)s, %(code)s, %(sys)s)"
146 args = {
147 'narr': self._payload[self._idx['narrative']],
148 'code': code,
149 'sys': coding_system
150 }
151 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
152 return True
153
180
181
182
183
184
185
186 -def search_text_across_emrs(search_term=None):
187
188 if search_term is None:
189 return []
190
191 if search_term.strip() == u'':
192 return []
193
194 cmd = u'select * from clin.v_narrative4search where narrative ~* %(term)s order by pk_patient limit 1000'
195 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'term': search_term}}], get_col_idx = False)
196
197 return rows
198
200 """Creates a new clinical narrative entry
201
202 narrative - free text clinical narrative
203 soap_cat - soap category
204 episode_id - episodes's primary key
205 encounter_id - encounter's primary key
206 """
207
208
209
210
211
212 narrative = narrative.strip()
213 if narrative == u'':
214 return (True, None)
215
216
217
218
219 cmd = u"""
220 select *, xmin_clin_narrative from clin.v_pat_narrative where
221 pk_encounter = %(enc)s
222 and pk_episode = %(epi)s
223 and soap_cat = %(soap)s
224 and narrative = %(narr)s
225 """
226 args = {
227 'enc': encounter_id,
228 'epi': episode_id,
229 'soap': soap_cat,
230 'narr': narrative
231 }
232 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
233 if len(rows) == 1:
234 narrative = cNarrative(row = {'pk_field': 'pk_narrative', 'data': rows[0], 'idx': idx})
235 return (True, narrative)
236
237
238 queries = [
239 {'cmd': u"insert into clin.clin_narrative (fk_encounter, fk_episode, narrative, soap_cat) values (%s, %s, %s, lower(%s))",
240 'args': [encounter_id, episode_id, narrative, soap_cat]
241 },
242 {'cmd': u"select currval('clin.clin_narrative_pk_seq')"}
243 ]
244 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data=True)
245
246 narrative = cNarrative(aPK_obj = rows[0][0])
247 return (True, narrative)
248
250 """Deletes a clin.clin_narrative row by it's PK."""
251 cmd = u"delete from clin.clin_narrative where pk=%s"
252 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': [narrative]}])
253 return True
254
255
256
257 if __name__ == '__main__':
258
259 from Gnumed.pycommon import gmI18N
260 gmI18N.activate_locale()
261 gmI18N.install_domain(domain = 'gnumed')
262
264 print "\nDiagnose test"
265 print "-------------"
266 diagnose = cDiag(aPK_obj=2)
267 fields = diagnose.get_fields()
268 for field in fields:
269 print field, ':', diagnose[field]
270 print "updatable:", diagnose.get_updatable_fields()
271 print "codes:", diagnose.get_codes()
272
273
274
275
277 print "\nnarrative test"
278 print "--------------"
279 narrative = cNarrative(aPK_obj=7)
280 fields = narrative.get_fields()
281 for field in fields:
282 print field, ':', narrative[field]
283 print "updatable:", narrative.get_updatable_fields()
284 print "codes:", narrative.get_codes()
285
286
287
288
289
290
291
292
293
295 results = search_text_across_emrs('cut')
296 for r in results:
297 print r
298
299
300
301 test_diag()
302 test_narrative()
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449