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