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