Package Gnumed :: Package business :: Module gmPathLab
[frames] | no frames]

Source Code for Module Gnumed.business.gmPathLab

   1  """GNUmed measurements related business objects.""" 
   2  #============================================================ 
   3  __version__ = "$Revision: 1.81 $" 
   4  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
   5  __license__ = "GPL" 
   6   
   7   
   8  import types, sys, logging, codecs, decimal 
   9   
  10  if __name__ == '__main__': 
  11          sys.path.insert(0, '../../') 
  12   
  13  from Gnumed.pycommon import gmDateTime 
  14  if __name__ == '__main__': 
  15          from Gnumed.pycommon import gmLog2 
  16          from Gnumed.pycommon import gmI18N 
  17          gmDateTime.init() 
  18  from Gnumed.pycommon import gmExceptions, gmBusinessDBObject, gmPG2, gmTools 
  19  from Gnumed.pycommon import gmDispatcher 
  20   
  21   
  22  _log = logging.getLogger('gm.lab') 
  23  _log.info(__version__) 
  24   
  25  # FIXME: use UCUM from Regenstrief Institute 
  26   
  27  #============================================================ 
28 -def _on_test_result_modified():
29 """Always relates to the active patient.""" 30 gmHooks.run_hook_script(hook = u'after_test_result_modified')
31 32 gmDispatcher.connect(_on_test_result_modified, u'test_result_mod_db') 33 34 #============================================================
35 -class cTestOrg(gmBusinessDBObject.cBusinessDBObject):
36 """Represents one test org/lab.""" 37 38 _cmd_fetch_payload = u"""SELECT *, xmin FROM clin.test_org WHERE pk = %s""" 39 40 _cmds_store_payload = [ 41 u"""UPDATE clin.test_org SET 42 internal_name = gm.nullify_empty_string(%(internal_name)s), 43 contact = gm.nullify_empty_string(%(contact)s), 44 comment = gm.nullify_empty_string(%(comment)s) 45 WHERE 46 pk = %(pk)s 47 AND 48 xmin = %(xmin)s 49 RETURNING 50 xmin 51 """ 52 ] 53 54 _updatable_fields = [ 55 u'internal_name', 56 u'contact', 57 u'comment' 58 ]
59 #------------------------------------------------------------
60 -def create_test_org(name=None):
61 cmd = u'insert into clin.test_org (internal_name) values (%(name)s) returning pk' 62 args = {'name': name.strip()} 63 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 64 return cTestOrg(aPK_obj = rows[0]['pk'])
65 #------------------------------------------------------------
66 -def get_test_orgs(order_by=u'internal_name'):
67 cmd = u'select *, xmin from clin.test_org order by %s' % order_by 68 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 69 return [ cTestOrg(row = {'pk_field': 'pk', 'data': r, 'idx': idx}) for r in rows ]
70 #============================================================
71 -class cMetaTestType(gmBusinessDBObject.cBusinessDBObject):
72 """Represents one meta test type under which actual test types can be aggregated.""" 73 74 _cmd_fetch_payload = u"""select * from clin.meta_test_type where pk = %s""" 75 76 _cmds_store_payload = [] 77 78 _updatable_fields = []
79 #------------------------------------------------------------
80 -def delete_meta_type(meta_type=None):
81 cmd = u'delete from clin.meta_test_type where pk = %(pk)s' 82 args = {'pk': meta_type} 83 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
84 #------------------------------------------------------------
85 -def get_meta_test_types():
86 cmd = u'select * from clin.meta_test_type' 87 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 88 return [ cMetaTestType(row = {'pk_field': 'pk', 'data': r, 'idx': idx}) for r in rows ]
89 #============================================================
90 -class cUnifiedTestType(gmBusinessDBObject.cBusinessDBObject):
91 """Represents one unified test type.""" 92 93 # FIXME: if we ever want to write we need to include XMIN in the view 94 _cmd_fetch_payload = u"""select * from clin.v_unified_test_types where pk_test_type = %s""" 95 96 _cmds_store_payload = [] 97 98 _updatable_fields = [] 99 #--------------------------------------------------------
100 - def get_most_recent_result(self, pk_patient=None):
101 cmd = u""" 102 SELECT pk_test_result, clin_when 103 FROM clin.v_test_results 104 WHERE 105 pk_patient = %(pat)s 106 AND 107 pk_meta_test_type = %(pkmtt)s 108 ORDER BY clin_when DESC 109 LIMIT 1 110 """ 111 args = {'pat': pk_patient, 'pkmtt': self._payload[self._idx['pk_meta_test_type']]} 112 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 113 if len(rows) == 0: 114 return None 115 return cTestResult(aPK_obj = rows[0]['pk_test_result'])
116 #============================================================
117 -class cMeasurementType(gmBusinessDBObject.cBusinessDBObject):
118 """Represents one test result type.""" 119 120 _cmd_fetch_payload = u"""select * from clin.v_test_types where pk_test_type = %s""" 121 122 _cmds_store_payload = [ 123 u"""update clin.test_type set 124 abbrev = %(abbrev)s, 125 name = %(name)s, 126 loinc = gm.nullify_empty_string(%(loinc)s), 127 code = gm.nullify_empty_string(%(code)s), 128 coding_system = gm.nullify_empty_string(%(coding_system)s), 129 comment = gm.nullify_empty_string(%(comment_type)s), 130 conversion_unit = gm.nullify_empty_string(%(conversion_unit)s), 131 fk_test_org = %(pk_test_org)s 132 where pk = %(pk_test_type)s""", 133 u"""select xmin_test_type from clin.v_test_types where pk_test_type = %(pk_test_type)s""" 134 ] 135 136 _updatable_fields = [ 137 'abbrev', 138 'name', 139 'loinc', 140 'code', 141 'coding_system', 142 'comment_type', 143 'conversion_unit', 144 'pk_test_org' 145 ] 146 #--------------------------------------------------------
147 - def __setitem__(self, attribute, value):
148 149 # find fk_test_org from name 150 if (attribute == 'fk_test_org') and (value is not None): 151 try: 152 int(value) 153 except: 154 cmd = u"select pk from clin.test_org where internal_name = %(val)s" 155 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'val': value}}]) 156 if len(rows) == 0: 157 raise ValueError('[%s]: no test org for [%s], cannot set <%s>' % (self.__class__.__name__, value, attribute)) 158 value = rows[0][0] 159 160 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
161 #--------------------------------------------------------
162 - def _get_in_use(self):
163 cmd = u'select exists(select 1 from clin.test_result where fk_type = %(pk_type)s)' 164 args = {'pk_type': self._payload[self._idx['pk_test_type']]} 165 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 166 return rows[0][0]
167 168 in_use = property(_get_in_use, lambda x:x)
169 #------------------------------------------------------------
170 -def get_measurement_types(order_by=None):
171 cmd = u'select * from clin.v_test_types %s' % gmTools.coalesce(order_by, u'', u'order by %s') 172 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 173 return [ cMeasurementType(row = {'pk_field': 'pk_test_type', 'data': r, 'idx': idx}) for r in rows ]
174 #------------------------------------------------------------
175 -def find_measurement_type(lab=None, abbrev=None, name=None):
176 177 if (abbrev is None) and (name is None): 178 raise ValueError('must have <abbrev> and/or <name> set') 179 180 where_snippets = [] 181 182 if lab is None: 183 where_snippets.append('pk_test_org is null') 184 else: 185 try: 186 int(lab) 187 where_snippets.append('pk_test_org = %(lab)s') 188 except (TypeError, ValueError): 189 where_snippets.append('pk_test_org = (select pk from clin.test_org where internal_name = %(lab)s)') 190 191 if abbrev is not None: 192 where_snippets.append('abbrev = %(abbrev)s') 193 194 if name is not None: 195 where_snippets.append('name = %(name)s') 196 197 where_clause = u' and '.join(where_snippets) 198 cmd = u"select * from clin.v_test_types where %s" % where_clause 199 args = {'lab': lab, 'abbrev': abbrev, 'name': name} 200 201 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 202 203 if len(rows) == 0: 204 return None 205 206 tt = cMeasurementType(row = {'pk_field': 'pk_test_type', 'data': rows[0], 'idx': idx}) 207 return tt
208 #------------------------------------------------------------
209 -def delete_measurement_type(measurement_type=None):
210 cmd = u'delete from clin.test_type where pk = %(pk)s' 211 args = {'pk': measurement_type} 212 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
213 #------------------------------------------------------------
214 -def create_measurement_type(lab=None, abbrev=None, unit=None, name=None):
215 """Create or get test type.""" 216 217 ttype = find_measurement_type(lab = lab, abbrev = abbrev, name = name) 218 # found ? 219 if ttype is not None: 220 return ttype 221 222 _log.debug('creating test type [%s:%s:%s:%s]', lab, abbrev, name, unit) 223 224 # not found, so create it 225 if unit is None: 226 _log.error('need <unit> to create test type: %s:%s:%s:%s' % (lab, abbrev, name, unit)) 227 raise ValueError('need <unit> to create test type') 228 229 # make query 230 cols = [] 231 val_snippets = [] 232 vals = {} 233 234 # lab 235 if lab is None: 236 lab = create_measurement_org() 237 238 cols.append('fk_test_org') 239 try: 240 vals['lab'] = int(lab) 241 val_snippets.append('%(lab)s') 242 except: 243 vals['lab'] = lab 244 val_snippets.append('(select pk from clin.test_org where internal_name = %(lab)s)') 245 246 # code 247 cols.append('abbrev') 248 val_snippets.append('%(abbrev)s') 249 vals['abbrev'] = abbrev 250 251 # unit 252 cols.append('conversion_unit') 253 val_snippets.append('%(unit)s') 254 vals['unit'] = unit 255 256 # name 257 if name is not None: 258 cols.append('name') 259 val_snippets.append('%(name)s') 260 vals['name'] = name 261 262 col_clause = u', '.join(cols) 263 val_clause = u', '.join(val_snippets) 264 queries = [ 265 {'cmd': u'insert into clin.test_type (%s) values (%s)' % (col_clause, val_clause), 'args': vals}, 266 {'cmd': u"select * from clin.v_test_types where pk_test_type = currval(pg_get_serial_sequence('clin.test_type', 'pk'))"} 267 ] 268 rows, idx = gmPG2.run_rw_queries(queries = queries, get_col_idx = True, return_data = True) 269 ttype = cMeasurementType(row = {'pk_field': 'pk_test_type', 'data': rows[0], 'idx': idx}) 270 271 return ttype
272 #------------------------------------------------------------
273 -def create_measurement_org(name=None, comment=None):
274 275 if name is None: 276 name = _('inhouse lab') 277 comment = _('auto-generated') 278 279 cmd = u'select * from clin.test_org where internal_name = %(name)s' 280 if comment is not None: 281 comment = comment.strip() 282 args = {'name': name, 'cmt': comment} 283 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 284 285 if len(rows) == 0: 286 queries = [ 287 {'cmd': u'insert into clin.test_org (fk_org, internal_name, comment) values (null, %(name)s, %(cmt)s)', 'args': args}, 288 {'cmd': u"select currval(pg_get_serial_sequence('clin.test_org', 'pk')) as pk"} 289 ] 290 else: 291 # use 1st result only, ignore if more than one 292 args['pk'] = rows[0]['pk'] 293 queries = [ 294 {'cmd': u'update clin.test_org set comment = %(cmt)s where pk = %(pk)s', 'args': args}, 295 {'cmd': u'select %(pk)s as pk', 'args': args} 296 ] 297 298 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True) 299 300 return rows[0]['pk']
301 #============================================================
302 -class cTestResult(gmBusinessDBObject.cBusinessDBObject):
303 """Represents one test result.""" 304 305 _cmd_fetch_payload = u"select * from clin.v_test_results where pk_test_result = %s" 306 307 _cmds_store_payload = [ 308 u"""update clin.test_result set 309 clin_when = %(clin_when)s, 310 narrative = nullif(trim(%(comment)s), ''), 311 val_num = %(val_num)s, 312 val_alpha = nullif(trim(%(val_alpha)s), ''), 313 val_unit = nullif(trim(%(val_unit)s), ''), 314 val_normal_min = %(val_normal_min)s, 315 val_normal_max = %(val_normal_max)s, 316 val_normal_range = nullif(trim(%(val_normal_range)s), ''), 317 val_target_min = %(val_target_min)s, 318 val_target_max = %(val_target_max)s, 319 val_target_range = nullif(trim(%(val_target_range)s), ''), 320 abnormality_indicator = nullif(trim(%(abnormality_indicator)s), ''), 321 norm_ref_group = nullif(trim(%(norm_ref_group)s), ''), 322 note_test_org = nullif(trim(%(note_test_org)s), ''), 323 material = nullif(trim(%(material)s), ''), 324 material_detail = nullif(trim(%(material_detail)s), ''), 325 fk_intended_reviewer = %(pk_intended_reviewer)s, 326 fk_encounter = %(pk_encounter)s, 327 fk_episode = %(pk_episode)s, 328 fk_type = %(pk_test_type)s, 329 fk_request = %(pk_request)s 330 where 331 pk = %(pk_test_result)s and 332 xmin = %(xmin_test_result)s""", 333 u"""select xmin_test_result from clin.v_test_results where pk_test_result = %(pk_test_result)s""" 334 ] 335 336 _updatable_fields = [ 337 'clin_when', 338 'comment', 339 'val_num', 340 'val_alpha', 341 'val_unit', 342 'val_normal_min', 343 'val_normal_max', 344 'val_normal_range', 345 'val_target_min', 346 'val_target_max', 347 'val_target_range', 348 'abnormality_indicator', 349 'norm_ref_group', 350 'note_test_org', 351 'material', 352 'material_detail', 353 'pk_intended_reviewer', 354 'pk_encounter', 355 'pk_episode', 356 'pk_test_type', 357 'pk_request' 358 ] 359 #--------------------------------------------------------
360 - def format(self, with_review=True, with_comments=True, date_format='%Y-%m-%d %H:%M'):
361 362 lines = [] 363 364 lines.append(u' %s %s (%s): %s %s%s' % ( 365 self._payload[self._idx['clin_when']].strftime(date_format), 366 self._payload[self._idx['unified_abbrev']], 367 self._payload[self._idx['unified_name']], 368 self._payload[self._idx['unified_val']], 369 self._payload[self._idx['val_unit']], 370 gmTools.coalesce(self._payload[self._idx['abnormality_indicator']], u'', u' (%s)') 371 )) 372 373 if with_comments: 374 if gmTools.coalesce(self._payload[self._idx['comment']], u'').strip() != u'': 375 lines.append(_(' Doc: %s') % self._payload[self._idx['comment']].strip()) 376 if gmTools.coalesce(self._payload[self._idx['note_test_org']], u'').strip() != u'': 377 lines.append(_(' MTA: %s') % self._payload[self._idx['note_test_org']].strip()) 378 379 if with_review: 380 if self._payload[self._idx['reviewed']]: 381 if self._payload[self._idx['is_clinically_relevant']]: 382 lines.append(u' %s %s: %s' % ( 383 self._payload[self._idx['last_reviewer']], 384 self._payload[self._idx['last_reviewed']].strftime('%Y-%m-%d %H:%M'), 385 gmTools.bool2subst ( 386 self._payload[self._idx['is_technically_abnormal']], 387 _('abnormal and relevant'), 388 _('normal but relevant') 389 ) 390 )) 391 else: 392 lines.append(_(' unreviewed')) 393 394 return lines
395 #--------------------------------------------------------
396 - def _get_reference_ranges(self):
397 398 cmd = u""" 399 select 400 distinct on (norm_ref_group_str, val_unit, val_normal_min, val_normal_max, val_normal_range, val_target_min, val_target_max, val_target_range) 401 pk_patient, 402 val_unit, 403 val_normal_min, val_normal_max, val_normal_range, 404 val_target_min, val_target_max, val_target_range, 405 norm_ref_group, 406 coalesce(norm_ref_group, '') as norm_ref_group_str 407 from 408 clin.v_test_results 409 where 410 pk_test_type = %(pk_type)s 411 """ 412 args = {'pk_type': self._payload[self._idx['pk_test_type']]} 413 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 414 return rows
415
416 - def _set_reference_ranges(self, val):
417 raise AttributeError('[%s]: reference ranges not settable') % self.__class__.__name__
418 419 reference_ranges = property(_get_reference_ranges, _set_reference_ranges) 420 #--------------------------------------------------------
421 - def set_review(self, technically_abnormal=None, clinically_relevant=None, comment=None, make_me_responsible=False):
422 423 if comment is not None: 424 comment = comment.strip() 425 426 if ((technically_abnormal is None) and 427 (clinically_relevant is None) and 428 (comment is None) and 429 (make_me_responsible is False)): 430 return True 431 432 # FIXME: this is not concurrency safe 433 if self._payload[self._idx['reviewed']]: 434 self.__change_existing_review ( 435 technically_abnormal = technically_abnormal, 436 clinically_relevant = clinically_relevant, 437 comment = comment 438 ) 439 else: 440 self.__set_new_review ( 441 technically_abnormal = technically_abnormal, 442 clinically_relevant = clinically_relevant, 443 comment = comment 444 ) 445 446 if make_me_responsible is True: 447 cmd = u"select pk from dem.staff where db_user = current_user" 448 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}]) 449 self['pk_intended_reviewer'] = rows[0][0] 450 self.save_payload() 451 else: 452 self.refetch_payload()
453 #-------------------------------------------------------- 454 # internal API 455 #--------------------------------------------------------
456 - def __set_new_review(self, technically_abnormal=None, clinically_relevant=None, comment=None):
457 """Add a review to a row. 458 459 - if technically abnormal is not provided/None it will be set 460 to True if the lab's indicator has a meaningful value 461 - if clinically relevant is not provided/None it is set to 462 whatever technically abnormal is 463 """ 464 if technically_abnormal is None: 465 technically_abnormal = False 466 if self._payload[self._idx['abnormality_indicator']] is not None: 467 if self._payload[self._idx['abnormality_indicator']].strip() != u'': 468 technically_abnormal = True 469 470 if clinically_relevant is None: 471 clinically_relevant = technically_abnormal 472 473 cmd = u""" 474 insert into clin.reviewed_test_results ( 475 fk_reviewed_row, 476 is_technically_abnormal, 477 clinically_relevant, 478 comment 479 ) values ( 480 %(pk)s, 481 %(abnormal)s, 482 %(relevant)s, 483 %(cmt)s 484 )""" 485 args = { 486 'pk': self._payload[self._idx['pk_test_result']], 487 'abnormal': technically_abnormal, 488 'relevant': clinically_relevant, 489 'cmt': comment 490 } 491 492 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
493 #--------------------------------------------------------
494 - def __change_existing_review(self, technically_abnormal=None, clinically_relevant=None, comment=None):
495 """Change a review on a row. 496 497 - if technically abnormal/clinically relevant/comment are 498 None (or empty) they are not set 499 """ 500 args = { 501 'pk_row': self._payload[self._idx['pk_test_result']], 502 'abnormal': technically_abnormal, 503 'relevant': clinically_relevant 504 } 505 506 set_parts = [] 507 508 if technically_abnormal is not None: 509 set_parts.append(u'is_technically_abnormal = %(abnormal)s') 510 511 if clinically_relevant is not None: 512 set_parts.append(u'clinically_relevant= %(relevant)s') 513 514 if comment is not None: 515 set_parts.append('comment = %(cmt)s') 516 args['cmt'] = comment 517 518 cmd = u""" 519 update clin.reviewed_test_results set 520 fk_reviewer = (select pk from dem.staff where db_user = current_user), 521 %s 522 where 523 fk_reviewed_row = %%(pk_row)s 524 """ % u',\n '.join(set_parts) 525 526 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
527 #------------------------------------------------------------
528 -def delete_test_result(result=None):
529 530 try: 531 pk = int(result) 532 except (TypeError, AttributeError): 533 pk = result['pk_test_result'] 534 535 cmd = u'delete from clin.test_result where pk = %(pk)s' 536 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}])
537 #------------------------------------------------------------
538 -def create_test_result(encounter=None, episode=None, type=None, intended_reviewer=None, val_num=None, val_alpha=None, unit=None):
539 540 cmd1 = u""" 541 insert into clin.test_result ( 542 fk_encounter, 543 fk_episode, 544 fk_type, 545 fk_intended_reviewer, 546 val_num, 547 val_alpha, 548 val_unit 549 ) values ( 550 %(enc)s, 551 %(epi)s, 552 %(type)s, 553 %(rev)s, 554 %(v_num)s, 555 %(v_alpha)s, 556 %(unit)s 557 )""" 558 559 cmd2 = u""" 560 select * 561 from 562 clin.v_test_results 563 where 564 pk_test_result = currval(pg_get_serial_sequence('clin.test_result', 'pk'))""" 565 566 args = { 567 u'enc': encounter, 568 u'epi': episode, 569 u'type': type, 570 u'rev': intended_reviewer, 571 u'v_num': val_num, 572 u'v_alpha': val_alpha, 573 u'unit': unit 574 } 575 576 rows, idx = gmPG2.run_rw_queries ( 577 queries = [ 578 {'cmd': cmd1, 'args': args}, 579 {'cmd': cmd2} 580 ], 581 return_data = True, 582 get_col_idx = True 583 ) 584 585 tr = cTestResult(row = { 586 'pk_field': 'pk_test_result', 587 'idx': idx, 588 'data': rows[0] 589 }) 590 591 return tr
592 #------------------------------------------------------------
593 -def format_test_results(results=None, output_format=u'latex'):
594 595 _log.debug(u'formatting test results into [%s]', output_format) 596 597 if output_format == u'latex': 598 return __format_test_results_latex(results = results) 599 600 msg = _('unknown test results output format [%s]') % output_format 601 _log.error(msg) 602 return msg
603 #------------------------------------------------------------
604 -def __tests2latex_minipage(results=None, width=u'1.5cm', show_time=False, show_range=True):
605 606 if len(results) == 0: 607 return u'\\begin{minipage}{%s} \\end{minipage}' % width 608 609 lines = [] 610 for t in results: 611 612 tmp = u'' 613 614 if show_time: 615 tmp += u'{\\tiny (%s)} ' % t['clin_when'].strftime('%H:%M') 616 617 tmp += u'%.8s' % t['unified_val'] 618 619 lines.append(tmp) 620 tmp = u'' 621 622 if show_range: 623 has_range = ( 624 t['unified_target_range'] is not None 625 or 626 t['unified_target_min'] is not None 627 or 628 t['unified_target_max'] is not None 629 ) 630 if has_range: 631 if t['unified_target_range'] is not None: 632 tmp += u'{\\tiny %s}' % t['unified_target_range'] 633 else: 634 tmp += u'{\\tiny %s}' % ( 635 gmTools.coalesce(t['unified_target_min'], u'- ', u'%s - '), 636 gmTools.coalesce(t['unified_target_max'], u'', u'%s') 637 ) 638 lines.append(tmp) 639 640 return u'\\begin{minipage}{%s} \\begin{flushright} %s \\end{flushright} \\end{minipage}' % (width, u' \\\\ '.join(lines))
641 #------------------------------------------------------------
642 -def __tests2latex_cell(results=None, show_time=False, show_range=True):
643 644 if len(results) == 0: 645 return u'' 646 647 lines = [] 648 for t in results: 649 650 tmp = u'' 651 652 if show_time: 653 tmp += u'\\tiny %s ' % t['clin_when'].strftime('%H:%M') 654 655 tmp += u'\\normalsize %.8s' % t['unified_val'] 656 657 lines.append(tmp) 658 tmp = u'\\tiny %s' % gmTools.coalesce(t['val_unit'], u'', u'%s:') 659 660 if not show_range: 661 lines.append(tmp) 662 continue 663 664 has_range = ( 665 t['unified_target_range'] is not None 666 or 667 t['unified_target_min'] is not None 668 or 669 t['unified_target_max'] is not None 670 ) 671 672 if not has_range: 673 lines.append(tmp) 674 continue 675 676 if t['unified_target_range'] is not None: 677 tmp += t['unified_target_range'] 678 else: 679 tmp += u'%s%s' % ( 680 gmTools.coalesce(t['unified_target_min'], u'- ', u'%s - '), 681 gmTools.coalesce(t['unified_target_max'], u'', u'%s') 682 ) 683 lines.append(tmp) 684 685 return u' \\\\ '.join(lines)
686 #------------------------------------------------------------
687 -def __format_test_results_latex(results=None):
688 689 if len(results) == 0: 690 return u'\\noindent %s' % _('No test results to format.') 691 692 # discover the columns and rows 693 dates = {} 694 tests = {} 695 grid = {} 696 for result in results: 697 # row_label = u'%s \\ \\tiny (%s)}' % (result['unified_abbrev'], result['unified_name']) 698 row_label = result['unified_abbrev'] 699 tests[row_label] = None 700 col_label = u'{\\scriptsize %s}' % result['clin_when'].strftime('%Y-%m-%d') 701 dates[col_label] = None 702 try: 703 grid[row_label] 704 except KeyError: 705 grid[row_label] = {} 706 try: 707 grid[row_label][col_label].append(result) 708 except KeyError: 709 grid[row_label][col_label] = [result] 710 711 col_labels = sorted(dates.keys(), reverse = True) 712 del dates 713 row_labels = sorted(tests.keys()) 714 del tests 715 716 col_def = len(col_labels) * u'>{\\raggedleft}p{1.7cm}|' 717 718 # format them 719 tex = u"""\\noindent %s 720 721 \\noindent \\begin{tabular}{|l|%s} 722 \\hline 723 & %s \\tabularnewline 724 \\hline 725 726 %%s \\tabularnewline 727 728 \\hline 729 730 \\end{tabular}""" % ( 731 _('Test results'), 732 col_def, 733 u' & '.join(col_labels) 734 ) 735 736 rows = [] 737 738 # loop over rows 739 for rl in row_labels: 740 cells = [rl] 741 # loop over cols per row 742 for cl in col_labels: 743 try: 744 # get tests for this (row/col) position 745 tests = grid[rl][cl] 746 except KeyError: 747 # none there, so insert empty cell 748 cells.append(u' ') 749 continue 750 751 cells.append ( 752 __tests2latex_cell ( 753 results = tests, 754 show_time = (len(tests) > 1), 755 show_range = True 756 ) 757 ) 758 759 rows.append(u' & '.join(cells)) 760 761 return tex % u' \\tabularnewline\n \\hline\n'.join(rows)
762 763 #============================================================
764 -def export_results_for_gnuplot(results=None, filename=None):
765 766 if filename is None: 767 filename = gmTools.get_unique_filename(prefix = u'gm2gpl-', suffix = '.dat') 768 769 # sort results into series by test type 770 series = {} 771 for r in results: 772 try: 773 series[r['unified_name']].append(r) 774 except KeyError: 775 series[r['unified_name']] = [r] 776 777 gp_data = codecs.open(filename, 'wb', 'utf8') 778 779 gp_data.write(u'# %s\n' % _('GNUmed test results export for Gnuplot plotting')) 780 gp_data.write(u'# -------------------------------------------------------------\n') 781 gp_data.write(u'# first line of index: test type abbreviation & name\n') 782 gp_data.write(u'#\n') 783 gp_data.write(u'# clin_when at full precision\n') 784 gp_data.write(u'# value\n') 785 gp_data.write(u'# unit\n') 786 gp_data.write(u'# unified (target or normal) range: lower bound\n') 787 gp_data.write(u'# unified (target or normal) range: upper bound\n') 788 gp_data.write(u'# normal range: lower bound\n') 789 gp_data.write(u'# normal range: upper bound\n') 790 gp_data.write(u'# target range: lower bound\n') 791 gp_data.write(u'# target range: upper bound\n') 792 gp_data.write(u'# clin_when formatted into string as x-axis tic label\n') 793 gp_data.write(u'# -------------------------------------------------------------\n') 794 795 for test_type in series.keys(): 796 if len(series[test_type]) == 0: 797 continue 798 799 r = series[test_type][0] 800 title = u'%s (%s)' % ( 801 r['unified_abbrev'], 802 r['unified_name'] 803 ) 804 gp_data.write(u'\n\n"%s" "%s"\n' % (title, title)) 805 806 prev_date = None 807 prev_year = None 808 for r in series[test_type]: 809 curr_date = r['clin_when'].strftime('%Y-%m-%d') 810 if curr_date == prev_date: 811 gp_data.write(u'\n# %s\n' % _('blank line inserted to allow for discontinued line drawing for same-day values')) 812 if r['clin_when'].year == prev_year: 813 when_template = '%b %d %H:%M' 814 else: 815 when_template = '%b %d %H:%M (%Y)' 816 prev_year = r['clin_when'].year 817 gp_data.write (u'%s %s "%s" %s %s %s %s %s %s "%s"\n' % ( 818 r['clin_when'].strftime('%Y-%m-%d_%H:%M'), 819 r['unified_val'], 820 gmTools.coalesce(r['val_unit'], u'"<?>"'), 821 gmTools.coalesce(r['unified_target_min'], u'"<?>"'), 822 gmTools.coalesce(r['unified_target_max'], u'"<?>"'), 823 gmTools.coalesce(r['val_normal_min'], u'"<?>"'), 824 gmTools.coalesce(r['val_normal_max'], u'"<?>"'), 825 gmTools.coalesce(r['val_target_min'], u'"<?>"'), 826 gmTools.coalesce(r['val_target_max'], u'"<?>"'), 827 gmDateTime.pydt_strftime ( 828 r['clin_when'], 829 format = when_template, 830 accuracy = gmDateTime.acc_minutes 831 ) 832 )) 833 prev_date = curr_date 834 835 gp_data.close() 836 837 return filename
838 #============================================================
839 -class cLabResult(gmBusinessDBObject.cBusinessDBObject):
840 """Represents one lab result.""" 841 842 _cmd_fetch_payload = """ 843 select *, xmin_test_result from v_results4lab_req 844 where pk_result=%s""" 845 _cmds_lock_rows_for_update = [ 846 """select 1 from test_result where pk=%(pk_result)s and xmin=%(xmin_test_result)s for update""" 847 ] 848 _cmds_store_payload = [ 849 """update test_result set 850 clin_when = %(val_when)s, 851 narrative = %(progress_note_result)s, 852 fk_type = %(pk_test_type)s, 853 val_num = %(val_num)s::numeric, 854 val_alpha = %(val_alpha)s, 855 val_unit = %(val_unit)s, 856 val_normal_min = %(val_normal_min)s, 857 val_normal_max = %(val_normal_max)s, 858 val_normal_range = %(val_normal_range)s, 859 val_target_min = %(val_target_min)s, 860 val_target_max = %(val_target_max)s, 861 val_target_range = %(val_target_range)s, 862 abnormality_indicator = %(abnormal)s, 863 norm_ref_group = %(ref_group)s, 864 note_provider = %(note_provider)s, 865 material = %(material)s, 866 material_detail = %(material_detail)s 867 where pk = %(pk_result)s""", 868 """select xmin_test_result from v_results4lab_req where pk_result=%(pk_result)s""" 869 ] 870 871 _updatable_fields = [ 872 'val_when', 873 'progress_note_result', 874 'val_num', 875 'val_alpha', 876 'val_unit', 877 'val_normal_min', 878 'val_normal_max', 879 'val_normal_range', 880 'val_target_min', 881 'val_target_max', 882 'val_target_range', 883 'abnormal', 884 'ref_group', 885 'note_provider', 886 'material', 887 'material_detail' 888 ] 889 #--------------------------------------------------------
890 - def __init__(self, aPK_obj=None, row=None):
891 """Instantiate. 892 893 aPK_obj as dict: 894 - patient_id 895 - when_field (see view definition) 896 - when 897 - test_type 898 - val_num 899 - val_alpha 900 - unit 901 """ 902 # instantiate from row data ? 903 if aPK_obj is None: 904 gmBusinessDBObject.cBusinessDBObject.__init__(self, row=row) 905 return 906 pk = aPK_obj 907 # find PK from row data ? 908 if type(aPK_obj) == types.DictType: 909 # sanity checks 910 if None in [aPK_obj['patient_id'], aPK_obj['when'], aPK_obj['when_field'], aPK_obj['test_type'], aPK_obj['unit']]: 911 raise gmExceptions.ConstructorError, 'parameter error: %s' % aPK_obj 912 if (aPK_obj['val_num'] is None) and (aPK_obj['val_alpha'] is None): 913 raise gmExceptions.ConstructorError, 'parameter error: val_num and val_alpha cannot both be None' 914 # get PK 915 where_snippets = [ 916 'pk_patient=%(patient_id)s', 917 'pk_test_type=%(test_type)s', 918 '%s=%%(when)s' % aPK_obj['when_field'], 919 'val_unit=%(unit)s' 920 ] 921 if aPK_obj['val_num'] is not None: 922 where_snippets.append('val_num=%(val_num)s::numeric') 923 if aPK_obj['val_alpha'] is not None: 924 where_snippets.append('val_alpha=%(val_alpha)s') 925 926 where_clause = ' and '.join(where_snippets) 927 cmd = "select pk_result from v_results4lab_req where %s" % where_clause 928 data = gmPG.run_ro_query('historica', cmd, None, aPK_obj) 929 if data is None: 930 raise gmExceptions.ConstructorError, 'error getting lab result for: %s' % aPK_obj 931 if len(data) == 0: 932 raise gmExceptions.NoSuchClinItemError, 'no lab result for: %s' % aPK_obj 933 pk = data[0][0] 934 # instantiate class 935 gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj=pk)
936 #--------------------------------------------------------
937 - def get_patient(self):
938 cmd = """ 939 select 940 %s, 941 vbp.title, 942 vbp.firstnames, 943 vbp.lastnames, 944 vbp.dob 945 from v_basic_person vbp 946 where vbp.pk_identity=%%s""" % self._payload[self._idx['pk_patient']] 947 pat = gmPG.run_ro_query('historica', cmd, None, self._payload[self._idx['pk_patient']]) 948 return pat[0]
949 #============================================================
950 -class cLabRequest(gmBusinessDBObject.cBusinessDBObject):
951 """Represents one lab request.""" 952 953 _cmd_fetch_payload = """ 954 select *, xmin_lab_request from v_lab_requests 955 where pk_request=%s""" 956 _cmds_lock_rows_for_update = [ 957 """select 1 from lab_request where pk=%(pk_request)s and xmin=%(xmin_lab_request)s for update""" 958 ] 959 _cmds_store_payload = [ 960 """update lab_request set 961 request_id=%(request_id)s, 962 lab_request_id=%(lab_request_id)s, 963 clin_when=%(sampled_when)s, 964 lab_rxd_when=%(lab_rxd_when)s, 965 results_reported_when=%(results_reported_when)s, 966 request_status=%(request_status)s, 967 is_pending=%(is_pending)s::bool, 968 narrative=%(progress_note)s 969 where pk=%(pk_request)s""", 970 """select xmin_lab_request from v_lab_requests where pk_request=%(pk_request)s""" 971 ] 972 _updatable_fields = [ 973 'request_id', 974 'lab_request_id', 975 'sampled_when', 976 'lab_rxd_when', 977 'results_reported_when', 978 'request_status', 979 'is_pending', 980 'progress_note' 981 ] 982 #--------------------------------------------------------
983 - def __init__(self, aPK_obj=None, row=None):
984 """Instantiate lab request. 985 986 The aPK_obj can be either a dict with the keys "req_id" 987 and "lab" or a simple primary key. 988 """ 989 # instantiate from row data ? 990 if aPK_obj is None: 991 gmBusinessDBObject.cBusinessDBObject.__init__(self, row=row) 992 return 993 pk = aPK_obj 994 # instantiate from "req_id" and "lab" ? 995 if type(aPK_obj) == types.DictType: 996 # sanity check 997 try: 998 aPK_obj['req_id'] 999 aPK_obj['lab'] 1000 except: 1001 _log.exception('[%s:??]: faulty <aPK_obj> structure: [%s]' % (self.__class__.__name__, aPK_obj), sys.exc_info()) 1002 raise gmExceptions.ConstructorError, '[%s:??]: cannot derive PK from [%s]' % (self.__class__.__name__, aPK_obj) 1003 # generate query 1004 where_snippets = [] 1005 vals = {} 1006 where_snippets.append('request_id=%(req_id)s') 1007 if type(aPK_obj['lab']) == types.IntType: 1008 where_snippets.append('pk_test_org=%(lab)s') 1009 else: 1010 where_snippets.append('lab_name=%(lab)s') 1011 where_clause = ' and '.join(where_snippets) 1012 cmd = "select pk_request from v_lab_requests where %s" % where_clause 1013 # get pk 1014 data = gmPG.run_ro_query('historica', cmd, None, aPK_obj) 1015 if data is None: 1016 raise gmExceptions.ConstructorError, '[%s:??]: error getting lab request for [%s]' % (self.__class__.__name__, aPK_obj) 1017 if len(data) == 0: 1018 raise gmExceptions.NoSuchClinItemError, '[%s:??]: no lab request for [%s]' % (self.__class__.__name__, aPK_obj) 1019 pk = data[0][0] 1020 # instantiate class 1021 gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj=pk)
1022 #--------------------------------------------------------
1023 - def get_patient(self):
1024 cmd = """ 1025 select vpi.pk_patient, vbp.title, vbp.firstnames, vbp.lastnames, vbp.dob 1026 from v_pat_items vpi, v_basic_person vbp 1027 where 1028 vpi.pk_item=%s 1029 and 1030 vbp.pk_identity=vpi.pk_patient""" 1031 pat = gmPG.run_ro_query('historica', cmd, None, self._payload[self._idx['pk_item']]) 1032 if pat is None: 1033 _log.error('cannot get patient for lab request [%s]' % self._payload[self._idx['pk_item']]) 1034 return None 1035 if len(pat) == 0: 1036 _log.error('no patient associated with lab request [%s]' % self._payload[self._idx['pk_item']]) 1037 return None 1038 return pat[0]
1039 #============================================================ 1040 # convenience functions 1041 #------------------------------------------------------------
1042 -def create_lab_request(lab=None, req_id=None, pat_id=None, encounter_id=None, episode_id=None):
1043 """Create or get lab request. 1044 1045 returns tuple (status, value): 1046 (True, lab request instance) 1047 (False, error message) 1048 (None, housekeeping_todo primary key) 1049 """ 1050 req = None 1051 aPK_obj = { 1052 'lab': lab, 1053 'req_id': req_id 1054 } 1055 try: 1056 req = cLabRequest (aPK_obj) 1057 except gmExceptions.NoSuchClinItemError, msg: 1058 _log.info('%s: will try to create lab request' % str(msg)) 1059 except gmExceptions.ConstructorError, msg: 1060 _log.exception(str(msg), sys.exc_info(), verbose=0) 1061 return (False, msg) 1062 # found 1063 if req is not None: 1064 db_pat = req.get_patient() 1065 if db_pat is None: 1066 _log.error('cannot cross-check patient on lab request') 1067 return (None, '') 1068 # yes but ambigous 1069 if pat_id != db_pat[0]: 1070 _log.error('lab request found for [%s:%s] but patient mismatch: expected [%s], in DB [%s]' % (lab, req_id, pat_id, db_pat)) 1071 me = '$RCSfile: gmPathLab.py,v $ $Revision: 1.81 $' 1072 to = 'user' 1073 prob = _('The lab request already exists but belongs to a different patient.') 1074 sol = _('Verify which patient this lab request really belongs to.') 1075 ctxt = _('lab [%s], request ID [%s], expected link with patient [%s], currently linked to patient [%s]') % (lab, req_id, pat_id, db_pat) 1076 cat = 'lab' 1077 status, data = gmPG.add_housekeeping_todo(me, to, prob, sol, ctxt, cat) 1078 return (None, data) 1079 return (True, req) 1080 # not found 1081 queries = [] 1082 if type(lab) is types.IntType: 1083 cmd = "insert into lab_request (fk_encounter, fk_episode, fk_test_org, request_id) values (%s, %s, %s, %s)" 1084 else: 1085 cmd = "insert into lab_request (fk_encounter, fk_episode, fk_test_org, request_id) values (%s, %s, (select pk from test_org where internal_name=%s), %s)" 1086 queries.append((cmd, [encounter_id, episode_id, str(lab), req_id])) 1087 cmd = "select currval('lab_request_pk_seq')" 1088 queries.append((cmd, [])) 1089 # insert new 1090 result, err = gmPG.run_commit('historica', queries, True) 1091 if result is None: 1092 return (False, err) 1093 try: 1094 req = cLabRequest(aPK_obj=result[0][0]) 1095 except gmExceptions.ConstructorError, msg: 1096 _log.exception(str(msg), sys.exc_info(), verbose=0) 1097 return (False, msg) 1098 return (True, req)
1099 #------------------------------------------------------------
1100 -def create_lab_result(patient_id=None, when_field=None, when=None, test_type=None, val_num=None, val_alpha=None, unit=None, encounter_id=None, request=None):
1101 tres = None 1102 data = { 1103 'patient_id': patient_id, 1104 'when_field': when_field, 1105 'when': when, 1106 'test_type': test_type, 1107 'val_num': val_num, 1108 'val_alpha': val_alpha, 1109 'unit': unit 1110 } 1111 try: 1112 tres = cLabResult(aPK_obj=data) 1113 # exists already, so fail 1114 _log.error('will not overwrite existing test result') 1115 _log.debug(str(tres)) 1116 return (None, tres) 1117 except gmExceptions.NoSuchClinItemError: 1118 _log.debug('test result not found - as expected, will create it') 1119 except gmExceptions.ConstructorError, msg: 1120 _log.exception(str(msg), sys.exc_info(), verbose=0) 1121 return (False, msg) 1122 if request is None: 1123 return (False, _('need lab request when inserting lab result')) 1124 # not found 1125 if encounter_id is None: 1126 encounter_id = request['pk_encounter'] 1127 queries = [] 1128 cmd = "insert into test_result (fk_encounter, fk_episode, fk_type, val_num, val_alpha, val_unit) values (%s, %s, %s, %s, %s, %s)" 1129 queries.append((cmd, [encounter_id, request['pk_episode'], test_type, val_num, val_alpha, unit])) 1130 cmd = "insert into lnk_result2lab_req (fk_result, fk_request) values ((select currval('test_result_pk_seq')), %s)" 1131 queries.append((cmd, [request['pk_request']])) 1132 cmd = "select currval('test_result_pk_seq')" 1133 queries.append((cmd, [])) 1134 # insert new 1135 result, err = gmPG.run_commit('historica', queries, True) 1136 if result is None: 1137 return (False, err) 1138 try: 1139 tres = cLabResult(aPK_obj=result[0][0]) 1140 except gmExceptions.ConstructorError, msg: 1141 _log.exception(str(msg), sys.exc_info(), verbose=0) 1142 return (False, msg) 1143 return (True, tres)
1144 #------------------------------------------------------------
1145 -def get_unreviewed_results(limit=50):
1146 # sanity check 1147 if limit < 1: 1148 limit = 1 1149 # retrieve one more row than needed so we know there's more available ;-) 1150 lim = limit + 1 1151 cmd = """ 1152 select pk_result 1153 from v_results4lab_req 1154 where reviewed is false 1155 order by pk_patient 1156 limit %s""" % lim 1157 rows = gmPG.run_ro_query('historica', cmd) 1158 if rows is None: 1159 _log.error('error retrieving unreviewed lab results') 1160 return (None, _('error retrieving unreviewed lab results')) 1161 if len(rows) == 0: 1162 return (False, []) 1163 # more than LIMIT rows ? 1164 if len(rows) == lim: 1165 more_avail = True 1166 # but deliver only LIMIT rows so that our assumption holds true... 1167 del rows[limit] 1168 else: 1169 more_avail = False 1170 results = [] 1171 for row in rows: 1172 try: 1173 results.append(cLabResult(aPK_obj=row[0])) 1174 except gmExceptions.ConstructorError: 1175 _log.exception('skipping unreviewed lab result [%s]' % row[0], sys.exc_info(), verbose=0) 1176 return (more_avail, results)
1177 #------------------------------------------------------------
1178 -def get_pending_requests(limit=250):
1179 lim = limit + 1 1180 cmd = "select pk from lab_request where is_pending is true limit %s" % lim 1181 rows = gmPG.run_ro_query('historica', cmd) 1182 if rows is None: 1183 _log.error('error retrieving pending lab requests') 1184 return (None, None) 1185 if len(rows) == 0: 1186 return (False, []) 1187 results = [] 1188 # more than LIMIT rows ? 1189 if len(rows) == lim: 1190 too_many = True 1191 # but deliver only LIMIT rows so that our assumption holds true... 1192 del rows[limit] 1193 else: 1194 too_many = False 1195 requests = [] 1196 for row in rows: 1197 try: 1198 requests.append(cLabRequest(aPK_obj=row[0])) 1199 except gmExceptions.ConstructorError: 1200 _log.exception('skipping pending lab request [%s]' % row[0], sys.exc_info(), verbose=0) 1201 return (too_many, requests)
1202 #------------------------------------------------------------
1203 -def get_next_request_ID(lab=None, incrementor_func=None):
1204 """Get logically next request ID for given lab. 1205 1206 - lab either test_org PK or test_org.internal_name 1207 - incrementor_func: 1208 - if not supplied the next ID is guessed 1209 - if supplied it is applied to the most recently used ID 1210 """ 1211 if type(lab) == types.IntType: 1212 lab_snippet = 'vlr.fk_test_org=%s' 1213 else: 1214 lab_snippet = 'vlr.lab_name=%s' 1215 lab = str(lab) 1216 cmd = """ 1217 select request_id 1218 from lab_request lr0 1219 where lr0.clin_when = ( 1220 select max(vlr.sampled_when) 1221 from v_lab_requests vlr 1222 where %s 1223 )""" % lab_snippet 1224 rows = gmPG.run_ro_query('historica', cmd, None, lab) 1225 if rows is None: 1226 _log.warning('error getting most recently used request ID for lab [%s]' % lab) 1227 return '' 1228 if len(rows) == 0: 1229 return '' 1230 most_recent = rows[0][0] 1231 # apply supplied incrementor 1232 if incrementor_func is not None: 1233 try: 1234 next = incrementor_func(most_recent) 1235 except TypeError: 1236 _log.error('cannot call incrementor function [%s]' % str(incrementor_func)) 1237 return most_recent 1238 return next 1239 # try to be smart ourselves 1240 for pos in range(len(most_recent)): 1241 header = most_recent[:pos] 1242 trailer = most_recent[pos:] 1243 try: 1244 return '%s%s' % (header, str(int(trailer) + 1)) 1245 except ValueError: 1246 header = most_recent[:-1] 1247 trailer = most_recent[-1:] 1248 return '%s%s' % (header, chr(ord(trailer) + 1))
1249 #============================================================
1250 -def calculate_bmi(mass=None, height=None, age=None):
1251 """Calculate BMI. 1252 1253 mass: kg 1254 height: cm 1255 age: not yet used 1256 1257 returns: 1258 (True/False, data) 1259 True: data = (bmi, lower_normal, upper_normal) 1260 False: data = error message 1261 """ 1262 converted, mass = gmTools.input2decimal(mass) 1263 if not converted: 1264 return False, u'mass: cannot convert <%s> to Decimal' % mass 1265 1266 converted, height = gmTools.input2decimal(height) 1267 if not converted: 1268 return False, u'height: cannot convert <%s> to Decimal' % height 1269 1270 approx_surface = (height / decimal.Decimal(100))**2 1271 bmi = mass / approx_surface 1272 1273 print mass, height, '->', approx_surface, '->', bmi 1274 1275 lower_normal_mass = 20.0 * approx_surface 1276 upper_normal_mass = 25.0 * approx_surface 1277 1278 return True, (bmi, lower_normal_mass, upper_normal_mass)
1279 #============================================================ 1280 # main - unit testing 1281 #------------------------------------------------------------ 1282 if __name__ == '__main__': 1283 1284 if len(sys.argv) < 2: 1285 sys.exit() 1286 1287 if sys.argv[1] != 'test': 1288 sys.exit() 1289 1290 import time 1291 1292 gmI18N.activate_locale() 1293 gmI18N.install_domain() 1294 1295 #------------------------------------------
1296 - def test_create_test_result():
1297 tr = create_test_result ( 1298 encounter = 1, 1299 episode = 1, 1300 type = 1, 1301 intended_reviewer = 1, 1302 val_num = '12', 1303 val_alpha=None, 1304 unit = 'mg/dl' 1305 ) 1306 print tr 1307 return tr
1308 #------------------------------------------
1309 - def test_delete_test_result():
1310 tr = test_create_test_result() 1311 delete_test_result(tr)
1312 #------------------------------------------
1313 - def test_result():
1314 r = cTestResult(aPK_obj=1) 1315 print r 1316 print r.reference_ranges
1317 #------------------------------------------
1318 - def test_lab_result():
1319 print "test_result()" 1320 # lab_result = cLabResult(aPK_obj=4) 1321 data = { 1322 'patient_id': 12, 1323 'when_field': 'val_when', 1324 'when': '2000-09-17 18:23:00+02', 1325 'test_type': 9, 1326 'val_num': 17.3, 1327 'val_alpha': None, 1328 'unit': 'mg/l' 1329 } 1330 lab_result = cLabResult(aPK_obj=data) 1331 print lab_result 1332 fields = lab_result.get_fields() 1333 for field in fields: 1334 print field, ':', lab_result[field] 1335 print "updatable:", lab_result.get_updatable_fields() 1336 print time.time() 1337 print lab_result.get_patient() 1338 print time.time()
1339 #------------------------------------------
1340 - def test_request():
1341 print "test_request()" 1342 try: 1343 # lab_req = cLabRequest(aPK_obj=1) 1344 # lab_req = cLabRequest(req_id='EML#SC937-0176-CEC#11', lab=2) 1345 data = { 1346 'req_id': 'EML#SC937-0176-CEC#11', 1347 'lab': 'Enterprise Main Lab' 1348 } 1349 lab_req = cLabRequest(aPK_obj=data) 1350 except gmExceptions.ConstructorError, msg: 1351 print "no such lab request:", msg 1352 return 1353 print lab_req 1354 fields = lab_req.get_fields() 1355 for field in fields: 1356 print field, ':', lab_req[field] 1357 print "updatable:", lab_req.get_updatable_fields() 1358 print time.time() 1359 print lab_req.get_patient() 1360 print time.time()
1361 #--------------------------------------------------------
1362 - def test_unreviewed():
1363 data = get_unreviewed_results() 1364 for result in data: 1365 print result
1366 #--------------------------------------------------------
1367 - def test_pending():
1368 data = get_pending_requests() 1369 for result in data: 1370 print result
1371 #--------------------------------------------------------
1372 - def test_create_measurement_type():
1373 print create_measurement_type ( 1374 lab = None, 1375 abbrev = u'tBZ2', 1376 unit = u'mg%', 1377 name = 'BZ (test 2)' 1378 )
1379 #--------------------------------------------------------
1380 - def test_meta_test_type():
1381 mtt = cMetaTestType(aPK_obj = 1) 1382 print mtt 1383 print get_meta_test_types()
1384 #--------------------------------------------------------
1385 - def test_test_type():
1386 tt = cMeasurementType(aPK_obj = 1) 1387 print tt 1388 print get_measurement_types()
1389 #--------------------------------------------------------
1390 - def test_format_test_results():
1391 results = [ 1392 cTestResult(aPK_obj=1), 1393 cTestResult(aPK_obj=2), 1394 cTestResult(aPK_obj=3) 1395 # cTestResult(aPK_obj=4) 1396 ] 1397 print format_test_results(results = results)
1398 #--------------------------------------------------------
1399 - def test_calculate_bmi():
1400 done, data = calculate_bmi(mass = sys.argv[2], height = sys.argv[3]) 1401 bmi, low, high = data 1402 1403 print "BMI:", bmi 1404 print "low:", low, "kg" 1405 print "hi :", high, "kg"
1406 1407 #-------------------------------------------------------- 1408 1409 #test_result() 1410 #test_create_test_result() 1411 #test_delete_test_result() 1412 #test_create_measurement_type() 1413 #test_lab_result() 1414 #test_request() 1415 #test_create_result() 1416 #test_unreviewed() 1417 #test_pending() 1418 #test_meta_test_type() 1419 #test_test_type() 1420 #test_format_test_results() 1421 test_calculate_bmi() 1422 1423 #============================================================ 1424