コード例 #1
0
    def get_EDC(self, lmp=None, nullipara=True):

        result = cClinicalResult(_('unknown EDC'))
        result.formula_name = u'EDC (Mittendorf 1990)'
        result.formula_source = u'Mittendorf, R. et al., "The length of uncomplicated human gestation," OB/GYN, Vol. 75, No., 6 June, 1990, pp. 907-932.'

        if lmp is None:
            result.message = _('EDC: unknown LMP')
            return result

        result.variables['LMP'] = lmp
        result.variables['nullipara'] = nullipara
        if nullipara:
            result.variables['parity_offset'] = 15  # days
        else:
            result.variables['parity_offset'] = 10  # days

        now = gmDateTime.pydt_now_here()
        if lmp > now:
            result.warnings.append(_(u'LMP in the future'))

        if self.__patient is None:
            result.warnings.append(_(u'cannot run sanity checks, no patient'))
        else:
            if self.__patient['dob'] is None:
                result.warnings.append(_(u'cannot run sanity checks, no DOB'))
            else:
                years, months, days, hours, minutes, seconds = gmDateTime.calculate_apparent_age(
                    start=self.__patient['dob'])
                # 5 years -- Myth ?
                # http://www.mirror.co.uk/news/uk-news/top-10-crazy-amazing-and-world-789842
                if years < 10:
                    result.warnings.append(
                        _(u'patient less than 10 years old'))
            if self.__patient['gender'] in [None, u'm']:
                result.warnings.append(
                    _(u'atypical gender for pregnancy: %s') %
                    self.__patient.gender_string)
            if self.__patient['deceased'] is not None:
                result.warnings.append(_(u'patient already passed away'))

        if lmp.month > 3:
            edc_month = lmp.month - 3
            edc_year = lmp.year + 1
        else:
            edc_month = lmp.month + 9
            edc_year = lmp.year

        result.numeric_value = gmDateTime.pydt_replace(
            dt=lmp, year=edc_year, month=edc_month,
            strict=False) + pydt.timedelta(
                days=result.variables['parity_offset'])

        result.message = _('EDC: %s') % gmDateTime.pydt_strftime(
            result.numeric_value, format='%Y %b %d')
        result.date_valid = now

        _log.debug(u'%s' % result)

        return result
コード例 #2
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
    def _get_egfr(self):

        # < 18 ?
        Schwartz = self.eGFR_Schwartz
        if Schwartz.numeric_value is not None:
            return Schwartz

        # this logic is based on "KVH aktuell 2/2014 Seite 10-15"
        # expect normal GFR
        CKD = self.eGFR_CKD_EPI
        if CKD.numeric_value is not None:
            if CKD.numeric_value > self.d(60):
                return CKD

        # CKD at or below 60
        if self.__patient['dob'] is None:
            return CKD  # no method will work, so return CKD anyway

        CG = self.eGFR_Cockcroft_Gault
        MDRD = self.eGFR_MDRD_short
        age = None
        if age is None:
            try:
                age = CKD.variables['age@crea']
            except KeyError:
                _log.warning('CKD-EPI: no age@crea')
        if age is None:
            try:
                age = CG.variables['age@crea']
            except KeyError:
                _log.warning('CG: no age@crea')
        if age is None:
            try:
                age = MDRD.variables['age@crea']
            except KeyError:
                _log.warning('MDRD: no age@crea')
        if age is None:
            age = gmDateTime.calculate_apparent_age(
                start=self.__patient['dob'])[0]

        # geriatric ?
        if age > self.d(65):
            if CG.numeric_value is not None:
                return CG

        # non-geriatric or CG not computable
        if MDRD.numeric_value is None:
            if (CKD.numeric_value is not None) or (CG.numeric_value is None):
                return CKD
            return CG

        if MDRD.numeric_value > self.d(60):
            if CKD.numeric_value is not None:
                # probably normal after all (>60) -> use CKD-EPI
                return CKD

        return MDRD
コード例 #3
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_egfr(self):

		# < 18 ?
		Schwartz = self.eGFR_Schwartz
		if Schwartz.numeric_value is not None:
			return Schwartz

		# this logic is based on "KVH aktuell 2/2014 Seite 10-15"
		# expect normal GFR
		CKD = self.eGFR_CKD_EPI
		if CKD.numeric_value is not None:
			if CKD.numeric_value > self.d(60):
				return CKD

		# CKD at or below 60
		if self.__patient['dob'] is None:
			return CKD			# no method will work, so return CKD anyway

		CG = self.eGFR_Cockcroft_Gault
		MDRD = self.eGFR_MDRD_short
		age = None
		if age is None:
			try:
				age = CKD.variables['age@crea']
			except KeyError:
				_log.warning('CKD-EPI: no age@crea')
		if age is None:
			try:
				age = CG.variables['age@crea']
			except KeyError:
				_log.warning('CG: no age@crea')
		if age is None:
			try:
				age = MDRD.variables['age@crea']
			except KeyError:
				_log.warning('MDRD: no age@crea')
		if age is None:
			age = gmDateTime.calculate_apparent_age(start = self.__patient['dob'])[0]

		# geriatric ?
		if age > self.d(65):
			if CG.numeric_value is not None:
				return CG

		# non-geriatric or CG not computable
		if MDRD.numeric_value is None:
			if (CKD.numeric_value is not None) or (CG.numeric_value is None):
				return CKD
			return CG

		if MDRD.numeric_value > self.d(60):
			if CKD.numeric_value is not None:
				# probably normal after all (>60) -> use CKD-EPI
				return CKD

		return MDRD
コード例 #4
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def get_EDC(self, lmp=None, nullipara=True):

		result = cClinicalResult(_('unknown EDC'))
		result.formula_name = 'EDC (Mittendorf 1990)'
		result.formula_source = 'Mittendorf, R. et al., "The length of uncomplicated human gestation," OB/GYN, Vol. 75, No., 6 June, 1990, pp. 907-932.'

		if lmp is None:
			result.message = _('EDC: unknown LMP')
			return result

		result.variables['LMP'] = lmp
		result.variables['nullipara'] = nullipara
		if nullipara:
			result.variables['parity_offset'] = 15		# days
		else:
			result.variables['parity_offset'] = 10		# days

		now = gmDateTime.pydt_now_here()
		if lmp > now:
			result.warnings.append(_('LMP in the future'))

		if self.__patient is None:
			result.warnings.append(_('cannot run sanity checks, no patient'))
		else:
			if self.__patient['dob'] is None:
				result.warnings.append(_('cannot run sanity checks, no DOB'))
			else:
				years, months, days, hours, minutes, seconds = gmDateTime.calculate_apparent_age(start = self.__patient['dob'])
				# 5 years -- Myth ?
				# http://www.mirror.co.uk/news/uk-news/top-10-crazy-amazing-and-world-789842
				if years < 10:
					result.warnings.append(_('patient less than 10 years old'))
			if self.__patient['gender'] in [None, 'm']:
				result.warnings.append(_('atypical gender for pregnancy: %s') % self.__patient.gender_string)
			if self.__patient['deceased'] is not None:
				result.warnings.append(_('patient already passed away'))

		if lmp.month > 3:
			edc_month = lmp.month - 3
			edc_year = lmp.year + 1
		else:
			edc_month = lmp.month + 9
			edc_year = lmp.year

		result.numeric_value = gmDateTime.pydt_replace(dt = lmp, year = edc_year, month = edc_month, strict = False) + pydt.timedelta(days = result.variables['parity_offset'])

		result.message = _('EDC: %s') % gmDateTime.pydt_strftime (
			result.numeric_value,
			format = '%Y %b %d'
		)
		result.date_valid = now

		_log.debug('%s' % result)

		return result
コード例 #5
0
    def _get_gfr_cockcroft_gault(self):

        try:
            return self.__cache['cockcroft_gault']
        except KeyError:
            pass

        result = cClinicalResult(_('unknown Cockcroft-Gault'))
        result.formula_name = u'eGFR from Cockcroft-Gault'
        result.formula_source = u'8/2014: http://en.wikipedia.org/Renal_function'
        result.hints.append(_('best @ age >65'))

        if self.__patient is None:
            result.message = _('Cockcroft-Gault: no patient')
            return result

        if self.__patient['dob'] is None:
            result.message = _('Cockcroft-Gault: no DOB (no age)')
            return result

        # 1) gender
        from Gnumed.business.gmPerson import map_gender2mf
        result.variables['gender'] = self.__patient['gender']
        result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
        if result.variables['gender_mf'] not in ['m', 'f']:
            result.message = _('Cockcroft-Gault: neither male nor female')
            return result

        # 2) creatinine
        result.variables[
            'serum_crea'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_creatinine_quantity, no_of_results=1)
        if result.variables['serum_crea'] is None:
            result.message = _(
                'Cockcroft-Gault: serum creatinine value not found (LOINC: %s)'
            ) % gmLOINC.LOINC_creatinine_quantity
            return result
        if result.variables['serum_crea']['val_num'] is None:
            result.message = _('Cockcroft-Gault: creatinine value not numeric')
            return result
        result.variables['serum_crea_val'] = self.d(
            result.variables['serum_crea']['val_num'])
        if result.variables['serum_crea']['val_unit'] in [u'mg/dl', u'mg/dL']:
            result.variables['unit_multiplier'] = self.d(72)
            if result.variables['gender_mf'] == 'm':
                result.variables['gender_multiplier'] = self.d('1')
            else:  #result.variables['gender_mf'] == 'f'
                result.variables['gender_multiplier'] = self.d('0.85')
        elif result.variables['serum_crea']['val_unit'] in [
                u'µmol/L', u'µmol/l'
        ]:
            result.variables['unit_multiplier'] = self.d(1)
            if result.variables['gender_mf'] == 'm':
                result.variables['gender_multiplier'] = self.d('1.23')
            else:  #result.variables['gender_mf'] == 'f'
                result.variables['gender_multiplier'] = self.d('1.04')
        else:
            result.message = _(
                'Cockcroft-Gault: unknown serum creatinine unit (%s)'
            ) % result.variables['serum_crea']['val_unit']
            return result

        # 3) age (at creatinine evaluation)
        result.variables['dob'] = self.__patient['dob']
        result.variables['age@crea'] = self.d(
            gmDateTime.calculate_apparent_age(
                start=result.variables['dob'],
                end=result.variables['serum_crea']['clin_when'])[0])
        if (result.variables['age@crea'] < 18):
            result.message = _(
                'Cockcroft-Gault: formula does not apply at age [%s] (17 < age)'
            ) % result.variables['age@crea']
            return result

        result.variables[
            'weight'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_weight, no_of_results=1)
        if result.variables['weight'] is None:
            result.message = _('Cockcroft-Gault: weight not found')
            return result
        if result.variables['weight']['val_num'] is None:
            result.message = _('Cockcroft-Gault: weight not numeric')
            return result
        if result.variables['weight']['val_unit'] == u'kg':
            result.variables['weight_kg'] = self.d(
                result.variables['weight']['val_num'])
        elif result.variables['weight']['val_unit'] == u'g':
            result.variables['weight_kg'] = self.d(
                result.variables['weight']['val_num'] / self.d(1000))
        else:
            result.message = _('Cockcroft-Gault: weight not in kg or g')
            return result

        # calculate
        result.numeric_value = ((
         (140 - result.variables['age@crea']) * result.variables['weight_kg'] * result.variables['gender_multiplier']) \
           /								\
         (result.variables['unit_multiplier'] * result.variables['serum_crea_val'])
        )
        result.unit = u'ml/min'  #/1.73m²

        result.message = _('eGFR(CG): %.1f %s (%s)') % (
            result.numeric_value, result.unit,
            gmDateTime.pydt_strftime(
                result.variables['serum_crea']['clin_when'],
                format='%Y %b %d'))
        result.date_valid = result.variables['serum_crea']['clin_when']

        self.__cache['cockroft_gault'] = result
        _log.debug(u'%s' % result)

        return result
コード例 #6
0
    def _get_gfr_ckd_epi(self):

        try:
            return self.__cache['CKD-EPI']
        except KeyError:
            pass

        result = cClinicalResult(_('unknown CKD-EPI'))
        result.formula_name = u'eGFR from CKD-EPI'
        result.formula_source = u'8/2014: http://en.wikipedia.org/Renal_function'
        result.hints.append(_('best @ GFR > 60 ml/min'))

        if self.__patient is None:
            result.message = _('CKD-EPI: no patient')
            return result

        if self.__patient['dob'] is None:
            result.message = _('CKD-EPI: no DOB (no age)')
            return result

        # 1) gender
        from Gnumed.business.gmPerson import map_gender2mf
        result.variables['gender'] = self.__patient['gender']
        result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
        if result.variables['gender_mf'] == 'm':
            result.variables['gender_multiplier'] = self.d(1)
            result.variables['k:gender_divisor'] = self.d('0.9')
            result.variables['a:gender_power'] = self.d('-0.411')
        elif result.variables['gender_mf'] == 'f':
            result.variables['gender_multiplier'] = self.d('1.018')
            result.variables['k:gender_divisor'] = self.d('0.7')
            result.variables['a:gender_power'] = self.d('-0.329')
        else:
            result.message = _('CKD-EPI: neither male nor female')
            return result

        # 2) creatinine
        result.variables[
            'serum_crea'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_creatinine_quantity, no_of_results=1)
        if result.variables['serum_crea'] is None:
            result.message = _(
                'CKD-EPI: serum creatinine value not found (LOINC: %s)'
            ) % gmLOINC.LOINC_creatinine_quantity
            return result
        if result.variables['serum_crea']['val_num'] is None:
            result.message = _('CKD-EPI: creatinine value not numeric')
            return result
        result.variables['serum_crea_val'] = self.d(
            result.variables['serum_crea']['val_num'])
        if result.variables['serum_crea']['val_unit'] in [u'mg/dl', u'mg/dL']:
            result.variables['serum_crea_val'] = self.d(
                result.variables['serum_crea']['val_num'])
        elif result.variables['serum_crea']['val_unit'] in [
                u'µmol/L', u'µmol/l'
        ]:
            result.variables['serum_crea_val'] = self.d(
                result.variables['serum_crea']['val_num']) / self.d('88.4')
        else:
            result.message = _('CKD-EPI: unknown serum creatinine unit (%s)'
                               ) % result.variables['serum_crea']['val_unit']
            return result

        # 3) age (at creatinine evaluation)
        result.variables['dob'] = self.__patient['dob']
        result.variables['age@crea'] = self.d(
            gmDateTime.calculate_apparent_age(
                start=result.variables['dob'],
                end=result.variables['serum_crea']['clin_when'])[0])
        #		if (result.variables['age@crea'] > 84) or (result.variables['age@crea'] < 18):
        #			result.message = _('CKD-EPI: formula does not apply at age [%s] (17 < age < 85)') % result.variables['age@crea']
        #			return result

        # 4) ethnicity
        result.variables['ethnicity_multiplier'] = self.d(1)  # non-black
        result.warnings.append(
            _('ethnicity: GNUmed does not know patient ethnicity, ignoring correction factor of 1.519 for "black"'
              ))

        # calculate
        result.numeric_value = (
         self.d(141) * \
         pow(min((result.variables['serum_crea_val'] / result.variables['k:gender_divisor']), self.d(1)), result.variables['a:gender_power']) * \
         pow(max((result.variables['serum_crea_val'] / result.variables['k:gender_divisor']), self.d(1)), self.d('-1.209')) * \
         pow(self.d('0.993'), result.variables['age@crea']) * \
         result.variables['gender_multiplier'] * \
         result.variables['ethnicity_multiplier']
        )
        result.unit = u'ml/min/1.73m²'

        result.message = _('eGFR(CKD-EPI): %.1f %s (%s)') % (
            result.numeric_value, result.unit,
            gmDateTime.pydt_strftime(
                result.variables['serum_crea']['clin_when'],
                format='%Y %b %d'))
        result.date_valid = result.variables['serum_crea']['clin_when']

        self.__cache['CKD-EPI'] = result
        _log.debug(u'%s' % result)

        return result
コード例 #7
0
    def _get_gfr_mdrd_short(self):

        try:
            return self.__cache['MDRD_short']
        except KeyError:
            pass

        result = cClinicalResult(_('unknown MDRD (4 vars/IDMS)'))
        result.formula_name = u'eGFR from 4-variables IDMS-MDRD'
        result.formula_source = u'1/2013: http://en.wikipedia.org/Renal_function / http://www.ganfyd.org/index.php?title=Estimated_glomerular_filtration_rate (NHS)'
        result.hints.append(_('best @ 30 < GFR < 60 ml/min'))

        if self.__patient is None:
            result.message = _('MDRD (4 vars/IDMS): no patient')
            return result

        if self.__patient['dob'] is None:
            result.message = _('MDRD (4 vars/IDMS): no DOB (no age)')
            return result

        # 1) gender
        from Gnumed.business.gmPerson import map_gender2mf
        result.variables['gender'] = self.__patient['gender']
        result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
        if result.variables['gender_mf'] == 'm':
            result.variables['gender_multiplier'] = self.d(1)
        elif result.variables['gender_mf'] == 'f':
            result.variables['gender_multiplier'] = self.d('0.742')
        else:
            result.message = _('MDRD (4 vars/IDMS): neither male nor female')
            return result

        # 2) creatinine
        result.variables[
            'serum_crea'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_creatinine_quantity, no_of_results=1)
        if result.variables['serum_crea'] is None:
            result.message = _(
                'MDRD (4 vars/IDMS): serum creatinine value not found (LOINC: %s)'
            ) % gmLOINC.LOINC_creatinine_quantity
            return result
        if result.variables['serum_crea']['val_num'] is None:
            result.message = _(
                'MDRD (4 vars/IDMS): creatinine value not numeric')
            return result
        result.variables['serum_crea_val'] = self.d(
            result.variables['serum_crea']['val_num'])
        if result.variables['serum_crea']['val_unit'] in [u'mg/dl', u'mg/dL']:
            result.variables['unit_multiplier'] = self.d(175)  # older: 186
        elif result.variables['serum_crea']['val_unit'] in [
                u'µmol/L', u'µmol/l'
        ]:
            result.variables['unit_multiplier'] = self.d(30849)  # older: 32788
        else:
            result.message = _(
                'MDRD (4 vars/IDMS): unknown serum creatinine unit (%s)'
            ) % result.variables['serum_crea']['val_unit']
            return result

        # 3) age (at creatinine evaluation)
        result.variables['dob'] = self.__patient['dob']
        result.variables['age@crea'] = self.d(
            gmDateTime.calculate_apparent_age(
                start=result.variables['dob'],
                end=result.variables['serum_crea']['clin_when'])[0])
        if (result.variables['age@crea'] > 84) or (result.variables['age@crea']
                                                   < 18):
            result.message = _(
                'MDRD (4 vars/IDMS): formula does not apply at age [%s] (17 < age < 85)'
            ) % result.variables['age@crea']
            return result

        # 4) ethnicity
        result.variables['ethnicity_multiplier'] = self.d(1)  # non-black
        result.warnings.append(
            _('ethnicity: GNUmed does not know patient ethnicity, ignoring correction factor'
              ))

        # calculate
        result.numeric_value =  result.variables['unit_multiplier'] * \
         pow(result.variables['serum_crea_val'], self.d('-1.154')) * \
         pow(result.variables['age@crea'], self.d('-0.203')) * \
         result.variables['ethnicity_multiplier'] * \
         result.variables['gender_multiplier']
        result.unit = u'ml/min/1.73m²'

        BSA = self.body_surface_area
        result.sub_results.append(BSA)
        if BSA.numeric_value is None:
            result.warnings.append(
                _(u'NOT corrected for non-average body surface (average = 1.73m²)'
                  ))
        else:
            result.variables['BSA'] = BSA.numeric_value
            result_numeric_value = result.numeric_value / BSA.numeric_value

        result.message = _('eGFR(MDRD): %.1f %s (%s) [4-vars, IDMS]') % (
            result.numeric_value, result.unit,
            gmDateTime.pydt_strftime(
                result.variables['serum_crea']['clin_when'],
                format='%Y %b %d'))
        result.date_valid = result.variables['serum_crea']['clin_when']

        self.__cache['MDRD_short'] = result
        _log.debug(u'%s' % result)

        return result
コード例 #8
0
ファイル: gmTopPanel.py プロジェクト: weeksjm/gnumed
    def __update_age_label(self):

        # no patient
        if not self.curr_pat.connected:
            self._LBL_age.SetLabel(_('<Age>'))
            self._LBL_age.SetToolTip(_('no patient selected'))
            return

        # gender is always known
        tt = _('Gender: %s (%s) - %s\n') % (self.curr_pat.gender_symbol,
                                            gmTools.coalesce(
                                                self.curr_pat['gender'], '?'),
                                            self.curr_pat.gender_string)

        # dob is not known
        if self.curr_pat['dob'] is None:
            age = '%s  %s' % (self.curr_pat.gender_symbol,
                              self.curr_pat.get_formatted_dob())
            self._LBL_age.SetLabel(age)
            self._LBL_age.SetToolTip(tt)
            return

        tt += _('Born: %s\n') % self.curr_pat.get_formatted_dob(
            format='%d %b %Y')

        # patient is dead
        if self.curr_pat['deceased'] is not None:
            tt += _('Died: %s\n') % gmDateTime.pydt_strftime(
                self.curr_pat['deceased'], '%d %b %Y')
            tt += _('At age: %s\n') % self.curr_pat['medical_age']
            age = '%s  %s - %s (%s)' % (
                self.curr_pat.gender_symbol,
                self.curr_pat.get_formatted_dob(format='%d %b %Y'),
                gmDateTime.pydt_strftime(
                    self.curr_pat['deceased'],
                    '%d %b %Y'), self.curr_pat['medical_age'])
            if self.curr_pat['dob_is_estimated']:
                tt += _(' (date of birth and age are estimated)\n')
            self._LBL_age.SetLabel(age)
            self._LBL_age.SetToolTip(tt)
            return

        # patient alive
        now = gmDateTime.pydt_now_here()

        # patient birthday ?
        if self.curr_pat.get_formatted_dob(
                format='%m-%d',
                honor_estimation=False) == now.strftime('%m-%d'):
            template = _('%(sex)s  %(dob)s (%(age)s today !)')
            tt += _("\nToday is the patient's birthday !\n\n")
            tt += _('Age: %s\n') % self.curr_pat['medical_age']
        else:
            tt += _('Age: %s, birthday:\n') % self.curr_pat['medical_age']
            if self.curr_pat.current_birthday_passed is True:
                template = '%(sex)s  %(dob)s%(l_arr)s (%(age)s)'
                tt += ' ' + _('last: %s ago (this year)'
                              ) % gmDateTime.format_apparent_age_medically(
                                  age=gmDateTime.calculate_apparent_age(
                                      start=self.curr_pat.birthday_this_year,
                                      end=now)) + '\n'
                tt += ' ' + _(
                    'next: in %s (next year)'
                ) % gmDateTime.format_apparent_age_medically(
                    age=gmDateTime.calculate_apparent_age(
                        start=now,
                        end=self.curr_pat.birthday_next_year)) + '\n'
            elif self.curr_pat.current_birthday_passed is False:
                template = '%(sex)s  %(r_arr)s%(dob)s (%(age)s)'
                tt += ' ' + _(
                    'next: in %s (this year)'
                ) % gmDateTime.format_apparent_age_medically(
                    age=gmDateTime.calculate_apparent_age(
                        start=now,
                        end=self.curr_pat.birthday_this_year)) + '\n'
                tt += ' ' + _('last: %s ago (last year)'
                              ) % gmDateTime.format_apparent_age_medically(
                                  age=gmDateTime.calculate_apparent_age(
                                      start=self.curr_pat.birthday_last_year,
                                      end=now)) + '\n'
            else:  # None, unknown
                template = '%(sex)s  %(dob)s (%(age)s)'

        # FIXME: if the age is below, say, 2 hours we should fire
        # a timer here that updates the age in increments of 1 minute ... :-)
        age = template % {
            'sex': self.curr_pat.gender_symbol,
            'dob': self.curr_pat.get_formatted_dob(format='%d %b %Y'),
            'age': self.curr_pat['medical_age'],
            'r_arr': gmTools.u_arrow2right,
            'l_arr': gmTools.u_left_arrow
        }

        # Easter Egg ;-)
        if self.curr_pat['lastnames'] == 'Leibner':
            if self.curr_pat['firstnames'] == 'Steffi':
                if self.curr_pat['preferred'] == 'Wildfang':
                    age = '%s %s' % (gmTools.u_black_heart, age)

        if self.curr_pat['dob_is_estimated']:
            tt += _(' (date of birth and age are estimated)\n')

        self._LBL_age.SetLabel(age)
        self._LBL_age.SetToolTip(tt)
コード例 #9
0
ファイル: gmTopPanel.py プロジェクト: sk/gnumed
	def __update_age_label(self):

		# no patient
		if not self.curr_pat.connected:
			self._LBL_age.SetLabel(_('<Age>'))
			self._LBL_age.SetToolTipString(_('no patient selected'))
			return

		# gender is always known
		tt = _(u'Gender: %s (%s) - %s\n') % (
			self.curr_pat.gender_symbol,
			gmTools.coalesce(self.curr_pat[u'gender'], u'?'),
			self.curr_pat.gender_string
		)

		# dob is not known
		if self.curr_pat['dob'] is None:
			age = u'%s  %s' % (
				self.curr_pat.gender_symbol,
				self.curr_pat.get_formatted_dob()
			)
			self._LBL_age.SetLabel(age)
			self._LBL_age.SetToolTipString(tt)
			return

		tt += _('Born: %s\n') % self.curr_pat.get_formatted_dob(format = '%d %b %Y', encoding = gmI18N.get_encoding())

		# patient is dead
		if self.curr_pat['deceased'] is not None:
			tt += _('Died: %s\n') % gmDateTime.pydt_strftime(self.curr_pat['deceased'], '%d %b %Y')
			tt += _('At age: %s\n') % self.curr_pat['medical_age']
			age = u'%s  %s - %s (%s)' % (
				self.curr_pat.gender_symbol,
				self.curr_pat.get_formatted_dob(format = '%d %b %Y', encoding = gmI18N.get_encoding()),
				gmDateTime.pydt_strftime(self.curr_pat['deceased'], '%d %b %Y'),
				self.curr_pat['medical_age']
			)
			if self.curr_pat['dob_is_estimated']:
				tt += _(' (date of birth and age are estimated)\n')
			self._LBL_age.SetLabel(age)
			self._LBL_age.SetToolTipString(tt)
			return

		# patient alive
		now = gmDateTime.pydt_now_here()

		# patient birthday ?
		if self.curr_pat.get_formatted_dob(format = '%m-%d') == now.strftime('%m-%d'):
			template = _('%(sex)s  %(dob)s (%(age)s today !)')
			tt += _("\nToday is the patient's birthday !\n\n")
		else:
			if self.curr_pat.current_birthday_passed():
				template = u'%(sex)s  %(dob)s%(l_arr)s (%(age)s)'
				tt += _(u'Birthday: %s ago\n') % gmDateTime.format_apparent_age_medically (
					age = gmDateTime.calculate_apparent_age(start = self.curr_pat.birthday_this_year, end = now)
				)
			else:
				template = u'%(sex)s  %(r_arr)s%(dob)s (%(age)s)'
				tt += _(u'Birthday: in %s\n') % gmDateTime.format_apparent_age_medically (
					age = gmDateTime.calculate_apparent_age(start = now, end = self.curr_pat.birthday_this_year)
				)

		tt += _('Age: %s\n') % self.curr_pat['medical_age']

		# FIXME: if the age is below, say, 2 hours we should fire
		# a timer here that updates the age in increments of 1 minute ... :-)
		age = template % {
			u'sex': self.curr_pat.gender_symbol,
			u'dob': self.curr_pat.get_formatted_dob(format = '%d %b %Y', encoding = gmI18N.get_encoding()),
			u'age': self.curr_pat['medical_age'],
			u'r_arr': gmTools.u_right_arrow,
			u'l_arr': gmTools.u_left_arrow
		}

		# Easter Egg ;-)
		if self.curr_pat['lastnames'] == u'Leibner':
			if self.curr_pat['firstnames'] == u'Steffi':
				if self.curr_pat['preferred'] == u'Wildfang':
					age = u'%s %s' % (gmTools.u_black_heart, age)

		if self.curr_pat['dob_is_estimated']:
			tt += _(' (date of birth and age are estimated)\n')

		self._LBL_age.SetLabel(age)
		self._LBL_age.SetToolTipString(tt)
コード例 #10
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_gfr_schwartz(self):

		try:
			return self.__cache['gfr_schwartz']
		except KeyError:
			pass

		result = cClinicalResult(_('unknown eGFR (Schwartz)'))
		result.formula_name = 'eGFR from updated Schwartz "bedside" formula (age < 19yrs)'
		result.formula_source = '1/2013: http://en.wikipedia.org/Renal_function / http://www.ganfyd.org/index.php?title=Estimated_glomerular_filtration_rate (NHS) / doi 10.1681/ASN.2008030287 / doi: 10.2215/CJN.01640309'
		result.hints.append(_('only applies @ age <18'))

		if self.__patient is None:
			result.message = _('eGFR (Schwartz): no patient')
			return result

		if self.__patient['dob'] is None:
			result.message = _('eGFR (Schwartz): DOB needed for age')
			return result

		result.variables['dob'] = self.__patient['dob']

		# creatinine
		result.variables['serum_crea'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_creatinine_quantity, no_of_results = 1)
		if result.variables['serum_crea'] is None:
			result.message = _('eGFR (Schwartz): serum creatinine value not found (LOINC: %s') % gmLOINC.LOINC_creatinine_quantity
			return result
		if result.variables['serum_crea']['val_num'] is None:
			result.message = _('eGFR (Schwartz): creatinine value not numeric')
			return result
		result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num'])
		if result.variables['serum_crea']['val_unit'] in ['mg/dl', 'mg/dL']:
			result.variables['unit_multiplier'] = self.d(1)
		elif result.variables['serum_crea']['val_unit'] in ['µmol/L', 'µmol/l']:
			result.variables['unit_multiplier'] = self.d('0.00113')
		else:
			result.message = _('eGFR (Schwartz): unknown serum creatinine unit (%s)') % result.variables['serum_crea']['val_unit']
			return result

		# age
		result.variables['age@crea'] = self.d (
			gmDateTime.calculate_apparent_age (
				start = result.variables['dob'],
				end = result.variables['serum_crea']['clin_when']
			)[0]
		)
		if result.variables['age@crea'] > 17:
			result.message = _('eGFR (Schwartz): formula does not apply at age [%s] (age must be <18)') % result.variables['age@crea']
			return result

		# age-dependant constant
		if result.variables['age@crea'] < 1:
			# first year pre-term: k = 0.33
			# first year full-term: k = (0.45)		0.41 (updated)
			result.variables['constant_for_age'] = self.d('0.41')
			result.warnings.append(_('eGFR (Schwartz): not known whether pre-term birth, applying full-term formula'))
		else:
			result.variables['constant_for_age'] = self.d('0.41')

		# height
		result.variables['height'] = self.__patient.emr.get_result_at_timestamp (
			timestamp = result.variables['serum_crea']['clin_when'],
			loinc = gmLOINC.LOINC_height,
			tolerance_interval = '7 days'
		)
		if result.variables['height'] is None:
			result.message = _('eGFR (Schwartz): height not found')
			return result
		if result.variables['height']['val_num'] is None:
			result.message = _('eGFR (Schwartz): height not numeric')
			return result
		if result.variables['height']['val_unit'] == 'cm':
			result.variables['height_cm'] = self.d(result.variables['height']['val_num'])
		elif result.variables['height']['val_unit'] == 'mm':
			result.variables['height_cm'] = self.d(result.variables['height']['val_num'] / self.d(10))
		elif result.variables['height']['val_unit'] == 'm':
			result.variables['height_cm'] = self.d(result.variables['height']['val_num'] * 100)
		else:
			result.message = _('eGFR (Schwartz): height not in m, cm, or mm')
			return result

		# calculate
		result.numeric_value = (
			result.variables['constant_for_age'] * result.variables['height_cm']
		) / (
			result.variables['unit_multiplier'] * result.variables['serum_crea_val']
		)
		result.unit = 'ml/min/1.73m²'

		result.message = _('eGFR (Schwartz): %.1f %s (%s)') % (
			result.numeric_value,
			result.unit,
			gmDateTime.pydt_strftime (
				result.variables['serum_crea']['clin_when'],
				format = '%Y %b %d'
			)
		)
		result.date_valid = result.variables['serum_crea']['clin_when']

		self.__cache['gfr_schwartz'] = result
		_log.debug('%s' % result)

		return result
コード例 #11
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_gfr_cockcroft_gault(self):

		try:
			return self.__cache['cockcroft_gault']
		except KeyError:
			pass

		result = cClinicalResult(_('unknown Cockcroft-Gault'))
		result.formula_name = 'eGFR from Cockcroft-Gault'
		result.formula_source = '8/2014: http://en.wikipedia.org/Renal_function'
		result.hints.append(_('best @ age >65'))

		if self.__patient is None:
			result.message = _('Cockcroft-Gault: no patient')
			return result

		if self.__patient['dob'] is None:
			result.message = _('Cockcroft-Gault: no DOB (no age)')
			return result

		# 1) gender
		from Gnumed.business.gmPerson import map_gender2mf
		result.variables['gender'] = self.__patient['gender']
		result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
		if result.variables['gender_mf'] not in ['m', 'f']:
			result.message = _('Cockcroft-Gault: neither male nor female')
			return result

		# 2) creatinine
		result.variables['serum_crea'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_creatinine_quantity, no_of_results = 1)
		if result.variables['serum_crea'] is None:
			result.message = _('Cockcroft-Gault: serum creatinine value not found (LOINC: %s)') % gmLOINC.LOINC_creatinine_quantity
			return result
		if result.variables['serum_crea']['val_num'] is None:
			result.message = _('Cockcroft-Gault: creatinine value not numeric')
			return result
		result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num'])
		if result.variables['serum_crea']['val_unit'] in ['mg/dl', 'mg/dL']:
			result.variables['unit_multiplier'] = self.d(72)
			if result.variables['gender_mf'] == 'm':
				result.variables['gender_multiplier'] = self.d('1')
			else: #result.variables['gender_mf'] == 'f'
				result.variables['gender_multiplier'] = self.d('0.85')
		elif result.variables['serum_crea']['val_unit'] in ['µmol/L', 'µmol/l']:
			result.variables['unit_multiplier'] = self.d(1)
			if result.variables['gender_mf'] == 'm':
				result.variables['gender_multiplier'] = self.d('1.23')
			else: #result.variables['gender_mf'] == 'f'
				result.variables['gender_multiplier'] = self.d('1.04')
		else:
			result.message = _('Cockcroft-Gault: unknown serum creatinine unit (%s)') % result.variables['serum_crea']['val_unit']
			return result

		# 3) age (at creatinine evaluation)
		result.variables['dob'] = self.__patient['dob']
		result.variables['age@crea'] = self.d (
			gmDateTime.calculate_apparent_age (
				start = result.variables['dob'],
				end = result.variables['serum_crea']['clin_when']
			)[0]
		)
		if (result.variables['age@crea'] < 18):
			result.message = _('Cockcroft-Gault: formula does not apply at age [%s] (17 < age)') % result.variables['age@crea']
			return result

		result.variables['weight'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_weight, no_of_results = 1)
		if result.variables['weight'] is None:
			result.message = _('Cockcroft-Gault: weight not found')
			return result
		if result.variables['weight']['val_num'] is None:
			result.message = _('Cockcroft-Gault: weight not numeric')
			return result
		if result.variables['weight']['val_unit'] == 'kg':
			result.variables['weight_kg'] = self.d(result.variables['weight']['val_num'])
		elif result.variables['weight']['val_unit'] == 'g':
			result.variables['weight_kg'] = self.d(result.variables['weight']['val_num'] / self.d(1000))
		else:
			result.message = _('Cockcroft-Gault: weight not in kg or g')
			return result

		# calculate
		result.numeric_value = ((
			(140 - result.variables['age@crea']) * result.variables['weight_kg'] * result.variables['gender_multiplier']) \
					/								\
			(result.variables['unit_multiplier'] * result.variables['serum_crea_val'])
		)
		result.unit = 'ml/min'		#/1.73m²

		result.message = _('eGFR(CG): %.1f %s (%s)') % (
			result.numeric_value,
			result.unit,
			gmDateTime.pydt_strftime (
				result.variables['serum_crea']['clin_when'],
				format = '%Y %b %d'
			)
		)
		result.date_valid = result.variables['serum_crea']['clin_when']

		self.__cache['cockroft_gault'] = result
		_log.debug('%s' % result)

		return result
コード例 #12
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_gfr_ckd_epi(self):

		try:
			return self.__cache['CKD-EPI']
		except KeyError:
			pass

		result = cClinicalResult(_('unknown CKD-EPI'))
		result.formula_name = 'eGFR from CKD-EPI'
		result.formula_source = '8/2014: http://en.wikipedia.org/Renal_function'
		result.hints.append(_('best @ GFR > 60 ml/min'))

		if self.__patient is None:
			result.message = _('CKD-EPI: no patient')
			return result

		if self.__patient['dob'] is None:
			result.message = _('CKD-EPI: no DOB (no age)')
			return result

		# 1) gender
		from Gnumed.business.gmPerson import map_gender2mf
		result.variables['gender'] = self.__patient['gender']
		result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
		if result.variables['gender_mf'] == 'm':
			result.variables['gender_multiplier'] = self.d(1)
			result.variables['k:gender_divisor'] = self.d('0.9')
			result.variables['a:gender_power'] = self.d('-0.411')
		elif result.variables['gender_mf'] == 'f':
			result.variables['gender_multiplier'] = self.d('1.018')
			result.variables['k:gender_divisor'] = self.d('0.7')
			result.variables['a:gender_power'] = self.d('-0.329')
		else:
			result.message = _('CKD-EPI: neither male nor female')
			return result

		# 2) creatinine
		result.variables['serum_crea'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_creatinine_quantity, no_of_results = 1)
		if result.variables['serum_crea'] is None:
			result.message = _('CKD-EPI: serum creatinine value not found (LOINC: %s)') % gmLOINC.LOINC_creatinine_quantity
			return result
		if result.variables['serum_crea']['val_num'] is None:
			result.message = _('CKD-EPI: creatinine value not numeric')
			return result
		result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num'])
		if result.variables['serum_crea']['val_unit'] in ['mg/dl', 'mg/dL']:
			result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num'])
		elif result.variables['serum_crea']['val_unit'] in ['µmol/L', 'µmol/l']:
			result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num']) / self.d('88.4')
		else:
			result.message = _('CKD-EPI: unknown serum creatinine unit (%s)') % result.variables['serum_crea']['val_unit']
			return result

		# 3) age (at creatinine evaluation)
		result.variables['dob'] = self.__patient['dob']
		result.variables['age@crea'] = self.d (
			gmDateTime.calculate_apparent_age (
				start = result.variables['dob'],
				end = result.variables['serum_crea']['clin_when']
			)[0]
		)
#		if (result.variables['age@crea'] > 84) or (result.variables['age@crea'] < 18):
#			result.message = _('CKD-EPI: formula does not apply at age [%s] (17 < age < 85)') % result.variables['age@crea']
#			return result

		# 4) ethnicity
		result.variables['ethnicity_multiplier'] = self.d(1)			# non-black
		result.warnings.append(_('ethnicity: GNUmed does not know patient ethnicity, ignoring correction factor of 1.519 for "black"'))

		# calculate
		result.numeric_value = (
			self.d(141) * \
			pow(min((result.variables['serum_crea_val'] / result.variables['k:gender_divisor']), self.d(1)), result.variables['a:gender_power']) * \
			pow(max((result.variables['serum_crea_val'] / result.variables['k:gender_divisor']), self.d(1)), self.d('-1.209')) * \
			pow(self.d('0.993'), result.variables['age@crea']) * \
			result.variables['gender_multiplier'] * \
			result.variables['ethnicity_multiplier']
		)
		result.unit = 'ml/min/1.73m²'

		result.message = _('eGFR(CKD-EPI): %.1f %s (%s)') % (
			result.numeric_value,
			result.unit,
			gmDateTime.pydt_strftime (
				result.variables['serum_crea']['clin_when'],
				format = '%Y %b %d'
			)
		)
		result.date_valid = result.variables['serum_crea']['clin_when']

		self.__cache['CKD-EPI'] = result
		_log.debug('%s' % result)

		return result
コード例 #13
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_gfr_mdrd_short(self):

		try:
			return self.__cache['MDRD_short']
		except KeyError:
			pass

		result = cClinicalResult(_('unknown MDRD (4 vars/IDMS)'))
		result.formula_name = 'eGFR from 4-variables IDMS-MDRD'
		result.formula_source = '1/2013: http://en.wikipedia.org/Renal_function / http://www.ganfyd.org/index.php?title=Estimated_glomerular_filtration_rate (NHS)'
		result.hints.append(_('best @ 30 < GFR < 60 ml/min'))

		if self.__patient is None:
			result.message = _('MDRD (4 vars/IDMS): no patient')
			return result

		if self.__patient['dob'] is None:
			result.message = _('MDRD (4 vars/IDMS): no DOB (no age)')
			return result

		# 1) gender
		from Gnumed.business.gmPerson import map_gender2mf
		result.variables['gender'] = self.__patient['gender']
		result.variables['gender_mf'] = map_gender2mf[self.__patient['gender']]
		if result.variables['gender_mf'] == 'm':
			result.variables['gender_multiplier'] = self.d(1)
		elif result.variables['gender_mf'] == 'f':
			result.variables['gender_multiplier'] = self.d('0.742')
		else:
			result.message = _('MDRD (4 vars/IDMS): neither male nor female')
			return result

		# 2) creatinine
		result.variables['serum_crea'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_creatinine_quantity, no_of_results = 1)
		if result.variables['serum_crea'] is None:
			result.message = _('MDRD (4 vars/IDMS): serum creatinine value not found (LOINC: %s)') % gmLOINC.LOINC_creatinine_quantity
			return result
		if result.variables['serum_crea']['val_num'] is None:
			result.message = _('MDRD (4 vars/IDMS): creatinine value not numeric')
			return result
		result.variables['serum_crea_val'] = self.d(result.variables['serum_crea']['val_num'])
		if result.variables['serum_crea']['val_unit'] in ['mg/dl', 'mg/dL']:
			result.variables['unit_multiplier'] = self.d(175)						# older: 186
		elif result.variables['serum_crea']['val_unit'] in ['µmol/L', 'µmol/l']:
			result.variables['unit_multiplier'] = self.d(30849)					# older: 32788
		else:
			result.message = _('MDRD (4 vars/IDMS): unknown serum creatinine unit (%s)') % result.variables['serum_crea']['val_unit']
			return result

		# 3) age (at creatinine evaluation)
		result.variables['dob'] = self.__patient['dob']
		result.variables['age@crea'] = self.d (
			gmDateTime.calculate_apparent_age (
				start = result.variables['dob'],
				end = result.variables['serum_crea']['clin_when']
			)[0]
		)
		if (result.variables['age@crea'] > 84) or (result.variables['age@crea'] < 18):
			result.message = _('MDRD (4 vars/IDMS): formula does not apply at age [%s] (17 < age < 85)') % result.variables['age@crea']
			return result

		# 4) ethnicity
		result.variables['ethnicity_multiplier'] = self.d(1)			# non-black
		result.warnings.append(_('ethnicity: GNUmed does not know patient ethnicity, ignoring correction factor'))

		# calculate
		result.numeric_value =  result.variables['unit_multiplier'] * \
			pow(result.variables['serum_crea_val'], self.d('-1.154')) * \
			pow(result.variables['age@crea'], self.d('-0.203')) * \
			result.variables['ethnicity_multiplier'] * \
			result.variables['gender_multiplier']
		result.unit = 'ml/min/1.73m²'

		BSA = self.body_surface_area
		result.sub_results.append(BSA)
		if BSA.numeric_value is None:
			result.warnings.append(_('NOT corrected for non-average body surface (average = 1.73m²)'))
		else:
			result.variables['BSA'] = BSA.numeric_value
			result_numeric_value = result.numeric_value / BSA.numeric_value

		result.message = _('eGFR(MDRD): %.1f %s (%s) [4-vars, IDMS]') % (
			result.numeric_value,
			result.unit,
			gmDateTime.pydt_strftime (
				result.variables['serum_crea']['clin_when'],
				format = '%Y %b %d'
			)
		)
		result.date_valid = result.variables['serum_crea']['clin_when']

		self.__cache['MDRD_short'] = result
		_log.debug('%s' % result)

		return result
コード例 #14
0
ファイル: gmTimelineExporter.py プロジェクト: weeksjm/gnumed
def create_timeline_file(patient=None, filename=None, include_documents=False, include_vaccinations=False, include_encounters=False):

	emr = patient.emr
	global now
	now = gmDateTime.pydt_now_here()

	if filename is None:
		timeline_fname = gmTools.get_unique_filename(prefix = 'gm-', suffix = '.timeline')	# .timeline required ...
	else:
		timeline_fname = filename
	_log.debug('exporting EMR as timeline into [%s]', timeline_fname)
	timeline = io.open(timeline_fname, mode = 'wt', encoding = 'utf8', errors = 'xmlcharrefreplace')

	if patient['dob'] is None:
		lifespan_start = format_pydt(now.replace(year = now.year - 100))
	else:
		lifespan_start = format_pydt(patient['dob'])

	if patient['deceased'] is None:
		life_ends2day = 'True'
		lifespan_end = format_pydt(now)
	else:
		life_ends2day = 'False'
		lifespan_end = format_pydt(patient['deceased'])

	earliest_care_date = emr.earliest_care_date
	most_recent_care_date = emr.most_recent_care_date
	if most_recent_care_date is None:
		most_recent_care_date = lifespan_end
		care_ends2day = life_ends2day
	else:
		most_recent_care_date = format_pydt(most_recent_care_date)
		care_ends2day = 'False'

	timeline.write(xml_start % (
		# era: life span of patient
		_('Lifespan'),
		lifespan_start,
		lifespan_end,
		life_ends2day,
		ERA_NAME_CARE_PERIOD,
		format_pydt(earliest_care_date),
		most_recent_care_date,
		care_ends2day,
		# categories
		_('Health issues'),
		_('Episodes'),
		_('Encounters'),
		_('Hospital stays'),
		_('Procedures'),
		_('Documents'),
		_('Vaccinations'),
		_('Substances'),
		_('Life events')
	))
	# birth
	if patient['dob'] is None:
		start = now.replace(year = now.year - 100)
		timeline.write(__xml_encounter_template % (
			format_pydt(start),
			format_pydt(start),
			'?',
			_('Life events'),
			_('Date of birth unknown'),
			'True'
		))
	else:
		start = patient['dob']
		timeline.write(__xml_encounter_template % (
			format_pydt(patient['dob']),
			format_pydt(patient['dob']),
			'*',
			_('Life events'),
			_('Birth: %s') % patient.get_formatted_dob(format = '%Y %b %d %H:%M', honor_estimation = True),
			'True'
		))

	# start of care
	timeline.write(__xml_encounter_template % (
		format_pydt(earliest_care_date),
		format_pydt(earliest_care_date),
		gmTools.u_heavy_greek_cross,
		_('Life events'),
		_('Start of Care: %s\n(the earliest recorded event of care in this praxis)') % format_pydt(earliest_care_date, format = '%Y %b %d'),
		'True'
	))

	# containers must be defined before their
	# subevents, so put health issues first
	timeline.write('\n		<!-- ========================================\n Health issues\n======================================== -->')
	for issue in emr.health_issues:
		timeline.write(__format_health_issue_as_timeline_xml(issue, patient, emr))

	timeline.write('\n		<!-- ========================================\n Episodes\n======================================== -->')
	for epi in emr.get_episodes(order_by = 'pk_health_issue'):
		timeline.write(__format_episode_as_timeline_xml(epi, patient))

	if include_encounters:
		timeline.write(u'\n<!--\n========================================\n Encounters\n======================================== -->')
		for enc in emr.get_encounters(skip_empty = True):
			timeline.write(__format_encounter_as_timeline_xml(enc, patient))

	timeline.write('\n<!--\n========================================\n Hospital stays\n======================================== -->')
	for stay in emr.hospital_stays:
		timeline.write(__format_hospital_stay_as_timeline_xml(stay))

	timeline.write('\n<!--\n========================================\n Procedures\n======================================== -->')
	for proc in emr.performed_procedures:
		timeline.write(__format_procedure_as_timeline_xml(proc))

	if include_vaccinations:
		timeline.write(u'\n<!--\n========================================\n Vaccinations\n======================================== -->')
		for vacc in emr.vaccinations:
			timeline.write(__format_vaccination_as_timeline_xml(vacc))

	timeline.write('\n<!--\n========================================\n Substance intakes\n======================================== -->')
	for intake in emr.get_current_medications(include_inactive = True, include_unapproved = False):
		timeline.write(__format_intake_as_timeline_xml(intake))

	if include_documents:
		timeline.write(u'\n<!--\n========================================\n Documents\n======================================== -->')
		for doc in patient.document_folder.documents:
			timeline.write(__format_document_as_timeline_xml(doc))

	# allergies ?
	# - unclear where and how to place
	# test results ?
	# - too many events, at most "day sample drawn"

	# death
	if patient['deceased'] is None:
		end = now
	else:
		end = patient['deceased']
		death_ago = gmDateTime.format_apparent_age_medically (
			age = gmDateTime.calculate_apparent_age(start = end, end = now)
		)
		timeline.write(__xml_encounter_template % (
			format_pydt(end),
			format_pydt(end),
			gmTools.u_dagger,
			_('Life events'),
			_('Death: %s\n(%s ago at age %s)') % (
				format_pydt(end, format = '%Y %b %d %H:%M'),
				death_ago,
				patient.get_medical_age()
			),
			'True'
		))

	# display range
	if end.month == 2:
		if end.day == 29:
			# leap years aren't consecutive
			end = end.replace(day = 28)
	target_year = end.year + 1
	end = end.replace(year = target_year)
	timeline.write(xml_end % (
		format_pydt(start),
		format_pydt(end)
	))

	timeline.close()
	return timeline_fname
コード例 #15
0
    def _get_gfr_schwartz(self):

        try:
            return self.__cache['gfr_schwartz']
        except KeyError:
            pass

        result = cClinicalResult(_('unknown eGFR (Schwartz)'))
        result.formula_name = u'eGFR from updated Schwartz "bedside" formula (age < 19yrs)'
        result.formula_source = u'1/2013: http://en.wikipedia.org/Renal_function / http://www.ganfyd.org/index.php?title=Estimated_glomerular_filtration_rate (NHS) / doi 10.1681/ASN.2008030287 / doi: 10.2215/CJN.01640309'
        result.hints.append(_('only applies @ age <18'))

        if self.__patient is None:
            result.message = _('eGFR (Schwartz): no patient')
            return result

        if self.__patient['dob'] is None:
            result.message = _('eGFR (Schwartz): DOB needed for age')
            return result

        result.variables['dob'] = self.__patient['dob']

        # creatinine
        result.variables[
            'serum_crea'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_creatinine_quantity, no_of_results=1)
        if result.variables['serum_crea'] is None:
            result.message = _(
                'eGFR (Schwartz): serum creatinine value not found (LOINC: %s'
            ) % gmLOINC.LOINC_creatinine_quantity
            return result
        if result.variables['serum_crea']['val_num'] is None:
            result.message = _('eGFR (Schwartz): creatinine value not numeric')
            return result
        result.variables['serum_crea_val'] = self.d(
            result.variables['serum_crea']['val_num'])
        if result.variables['serum_crea']['val_unit'] in [u'mg/dl', u'mg/dL']:
            result.variables['unit_multiplier'] = self.d(1)
        elif result.variables['serum_crea']['val_unit'] in [
                u'µmol/L', u'µmol/l'
        ]:
            result.variables['unit_multiplier'] = self.d('0.00113')
        else:
            result.message = _(
                'eGFR (Schwartz): unknown serum creatinine unit (%s)'
            ) % result.variables['serum_crea']['val_unit']
            return result

        # age
        result.variables['age@crea'] = self.d(
            gmDateTime.calculate_apparent_age(
                start=result.variables['dob'],
                end=result.variables['serum_crea']['clin_when'])[0])
        if result.variables['age@crea'] > 17:
            result.message = _(
                'eGFR (Schwartz): formula does not apply at age [%s] (age must be <18)'
            ) % result.variables['age@crea']
            return result

        # age-dependant constant
        if result.variables['age@crea'] < 1:
            # first year pre-term: k = 0.33
            # first year full-term: k = (0.45)		0.41 (updated)
            result.variables['constant_for_age'] = self.d('0.41')
            result.warnings.append(
                _('eGFR (Schwartz): not known whether pre-term birth, applying full-term formula'
                  ))
        else:
            result.variables['constant_for_age'] = self.d('0.41')

        # height
        result.variables[
            'height'] = self.__patient.emr.get_result_at_timestamp(
                timestamp=result.variables['serum_crea']['clin_when'],
                loinc=gmLOINC.LOINC_height,
                tolerance_interval='7 days')
        if result.variables['height'] is None:
            result.message = _('eGFR (Schwartz): height not found')
            return result
        if result.variables['height']['val_num'] is None:
            result.message = _('eGFR (Schwartz): height not numeric')
            return result
        if result.variables['height']['val_unit'] == u'cm':
            result.variables['height_cm'] = self.d(
                result.variables['height']['val_num'])
        elif result.variables['height']['val_unit'] == u'mm':
            result.variables['height_cm'] = self.d(
                result.variables['height']['val_num'] / self.d(10))
        elif result.variables['height']['val_unit'] == u'm':
            result.variables['height_cm'] = self.d(
                result.variables['height']['val_num'] * 100)
        else:
            result.message = _('eGFR (Schwartz): height not in m, cm, or mm')
            return result

        # calculate
        result.numeric_value = (result.variables['constant_for_age'] *
                                result.variables['height_cm']) / (
                                    result.variables['unit_multiplier'] *
                                    result.variables['serum_crea_val'])
        result.unit = u'ml/min/1.73m²'

        result.message = _('eGFR (Schwartz): %.1f %s (%s)') % (
            result.numeric_value, result.unit,
            gmDateTime.pydt_strftime(
                result.variables['serum_crea']['clin_when'],
                format='%Y %b %d'))
        result.date_valid = result.variables['serum_crea']['clin_when']

        self.__cache['gfr_schwartz'] = result
        _log.debug(u'%s' % result)

        return result
コード例 #16
0
ファイル: gmClinicalCalculator.py プロジェクト: ncqgm/gnumed
	def _get_body_mass_index(self):

		try:
			return self.__cache['body_mass_index']
		except KeyError:
			pass

		result = cClinicalResult(_('unknown BMI'))
		result.formula_name = 'BMI/Quetelet Index'
		result.formula_source = '08/2014: https://en.wikipedia.org/wiki/Body_mass_index'

		if self.__patient is None:
			result.message = _('BMI: no patient')
			return result

		result.variables['height'] = self.__patient.emr.get_most_recent_results_in_loinc_group(loincs = gmLOINC.LOINC_height, no_of_results = 1)
		if result.variables['height'] is None:
			result.message = _('BMI: height not found')
			return result
		if result.variables['height']['val_num'] is None:
			result.message = _('BMI: height not numeric')
			return result
		if result.variables['height']['val_unit'] == 'cm':
			result.variables['height_m'] = self.d(result.variables['height']['val_num'] / self.d(100))
		elif result.variables['height']['val_unit'] == 'mm':
			result.variables['height_m'] = self.d(result.variables['height']['val_num'] / self.d(1000))
		elif result.variables['height']['val_unit'] == 'm':
			result.variables['height_m'] = self.d(result.variables['height']['val_num'])
		else:
			result.message = _('BMI: height not in m, cm, or mm')
			return result

		result.variables['weight'] = self.__patient.emr.get_result_at_timestamp (
			timestamp = result.variables['height']['clin_when'],
			loinc = gmLOINC.LOINC_weight,
			tolerance_interval = '10 days'
		)
		if result.variables['weight'] is None:
			result.message = _('BMI: weight not found')
			return result
		if result.variables['weight']['val_num'] is None:
			result.message = _('BMI: weight not numeric')
			return result
		if result.variables['weight']['val_unit'] == 'kg':
			result.variables['weight_kg'] = self.d(result.variables['weight']['val_num'])
		elif result.variables['weight']['val_unit'] == 'g':
			result.variables['weight_kg'] = self.d(result.variables['weight']['val_num'] / self.d(1000))
		else:
			result.message = _('BMI: weight not in kg or g')
			return result

		result.variables['dob'] = self.__patient['dob']
		start = result.variables['dob']
		end = result.variables['height']['clin_when']
		multiplier = 1
		if end < start:
			start = result.variables['height']['clin_when']
			end = result.variables['dob']
			multiplier = -1
		result.variables['age@height'] = multiplier * self.d(gmDateTime.calculate_apparent_age(start, end)[0])
		if (result.variables['age@height'] < 18):
			result.message = _('BMI (Quetelet): formula does not apply at age [%s] (0 < age < 18)') % result.variables['age@height']
			return result

		# bmi = mass kg / height m2
		result.numeric_value = result.variables['weight_kg'] / (result.variables['height_m'] * result.variables['height_m'])
		result.unit = 'kg/m²'

		result.message = _('BMI (Quetelet): %.2f %s') % (
			result.numeric_value,
			result.unit
		)
		result.date_valid = gmDateTime.pydt_now_here()

		self.__cache['body_mass_index'] = result
		_log.debug('%s' % result)

		return result
コード例 #17
0
    def _get_body_mass_index(self):

        try:
            return self.__cache['body_mass_index']
        except KeyError:
            pass

        result = cClinicalResult(_('unknown BMI'))
        result.formula_name = u'BMI/Quetelet Index'
        result.formula_source = u'08/2014: https://en.wikipedia.org/wiki/Body_mass_index'

        if self.__patient is None:
            result.message = _('BMI: no patient')
            return result

        result.variables[
            'height'] = self.__patient.emr.get_most_recent_results(
                loinc=gmLOINC.LOINC_height, no_of_results=1)
        if result.variables['height'] is None:
            result.message = _('BMI: height not found')
            return result
        if result.variables['height']['val_num'] is None:
            result.message = _('BMI: height not numeric')
            return result
        if result.variables['height']['val_unit'] == u'cm':
            result.variables['height_m'] = self.d(
                result.variables['height']['val_num'] / self.d(100))
        elif result.variables['height']['val_unit'] == u'mm':
            result.variables['height_m'] = self.d(
                result.variables['height']['val_num'] / self.d(1000))
        elif result.variables['height']['val_unit'] == u'm':
            result.variables['height_m'] = self.d(
                result.variables['height']['val_num'])
        else:
            result.message = _('BMI: height not in m, cm, or mm')
            return result

        result.variables[
            'weight'] = self.__patient.emr.get_result_at_timestamp(
                timestamp=result.variables['height']['clin_when'],
                loinc=gmLOINC.LOINC_weight,
                tolerance_interval='10 days')
        if result.variables['weight'] is None:
            result.message = _('BMI: weight not found')
            return result
        if result.variables['weight']['val_num'] is None:
            result.message = _('BMI: weight not numeric')
            return result
        if result.variables['weight']['val_unit'] == u'kg':
            result.variables['weight_kg'] = self.d(
                result.variables['weight']['val_num'])
        elif result.variables['weight']['val_unit'] == u'g':
            result.variables['weight_kg'] = self.d(
                result.variables['weight']['val_num'] / self.d(1000))
        else:
            result.message = _('BMI: weight not in kg or g')
            return result

        result.variables['dob'] = self.__patient['dob']
        start = result.variables['dob']
        end = result.variables['height']['clin_when']
        multiplier = 1
        if end < start:
            start = result.variables['height']['clin_when']
            end = result.variables['dob']
            multiplier = -1
        result.variables['age@height'] = multiplier * self.d(
            gmDateTime.calculate_apparent_age(start, end)[0])
        if (result.variables['age@height'] < 18):
            result.message = _(
                'BMI (Quetelet): formula does not apply at age [%s] (0 < age < 18)'
            ) % result.variables['age@height']
            return result

        # bmi = mass kg / height m2
        result.numeric_value = result.variables['weight_kg'] / (
            result.variables['height_m'] * result.variables['height_m'])
        result.unit = u'kg/m²'

        result.message = _('BMI (Quetelet): %.2f %s') % (result.numeric_value,
                                                         result.unit)
        result.date_valid = gmDateTime.pydt_now_here()

        self.__cache['body_mass_index'] = result
        _log.debug(u'%s' % result)

        return result
コード例 #18
0
ファイル: gmTopPanel.py プロジェクト: ncqgm/gnumed
    def __update_lab(self):

        if not self.curr_pat.connected:
            self._LBL_lab.SetLabel('')
            self._LBL_lab.SetToolTip(None)
            return

        tests2show = []
        tooltip_lines = []

        RRs = self.curr_pat.emr.get_most_recent_results_in_loinc_group(
            loincs=gmLOINC.LOINC_rr_quantity, max_no_of_results=1)
        if len(RRs) == 0:
            tests2show.append(_('BP ?'))
        else:
            tests2show.append(RRs[0]['unified_val'])
            tooltip_lines.append(
                _('BP: %s ago') % gmDateTime.format_apparent_age_medically(
                    age=gmDateTime.calculate_apparent_age(
                        start=RRs[0]['clin_when'])))

        HRs = self.curr_pat.emr.get_most_recent_results_in_loinc_group(
            loincs=gmLOINC.LOINC_heart_rate_quantity, max_no_of_results=1)
        if len(HRs) > 0:
            tests2show.append('@ %s' % HRs[0]['unified_val'])
            tooltip_lines.append(
                _('%s (@) in bpm: %s ago') %
                (HRs[0]['abbrev_tt'],
                 gmDateTime.format_apparent_age_medically(
                     age=gmDateTime.calculate_apparent_age(
                         start=HRs[0]['clin_when']))))

        bmi = self.curr_pat.emr.bmi
        if bmi.numeric_value is not None:
            tests2show.append(
                _('BMI %s') %
                bmi.numeric_value.quantize(decimal.Decimal('1.')))
            tooltip_lines.append(
                _('BMI: %s ago') % gmDateTime.format_apparent_age_medically(
                    age=gmDateTime.calculate_apparent_age(
                        start=bmi.date_valid)))
        else:
            weights = self.curr_pat.emr.get_most_recent_results_in_loinc_group(
                loincs=gmLOINC.LOINC_weight, max_no_of_results=1)
            if len(weights) == 0:
                tests2show.append(_('BMI ?'))
            else:
                tests2show.append(
                    '%s%s' %
                    (weights[0]['unified_val'], weights[0]['val_unit']))
                tooltip_lines.append(
                    _('weight: %s ago') %
                    gmDateTime.format_apparent_age_medically(
                        age=gmDateTime.calculate_apparent_age(
                            start=weights[0]['clin_when'])))

        gfr_or_crea = self.curr_pat.emr.best_gfr_or_crea
        if gfr_or_crea is None:
            tests2show.append(_('GFR ?'))
        else:
            try:
                tests2show.append(
                    _('GFR %s') %
                    gfr_or_crea.numeric_value.quantize(decimal.Decimal('1.')))
                tooltip_lines.append(
                    _('GFR: %s ago') %
                    gmDateTime.format_apparent_age_medically(
                        age=gmDateTime.calculate_apparent_age(
                            start=gfr_or_crea.date_valid)))
            except AttributeError:
                tests2show.append(
                    '%s %s' %
                    (gfr_or_crea['abbrev_tt'], gfr_or_crea['unified_val']))
                tooltip_lines.append(
                    _('%s: %s ago') %
                    (gfr_or_crea['abbrev_tt'],
                     gmDateTime.format_apparent_age_medically(
                         age=gmDateTime.calculate_apparent_age(
                             start=gfr_or_crea['clin_when']))))

        edc = self.curr_pat.emr.EDC
        if edc is not None:
            if self.curr_pat.emr.EDC_is_fishy:
                tests2show.append(
                    _('?EDC %s') % gmDateTime.pydt_strftime(
                        edc, '%Y-%b-%d', accuracy=gmDateTime.acc_days))
            else:
                tests2show.append(
                    _('EDC %s') % gmDateTime.pydt_strftime(
                        edc, '%Y-%b-%d', accuracy=gmDateTime.acc_days))

        INRs = self.curr_pat.emr.get_most_recent_results_in_loinc_group(
            loincs=gmLOINC.LOINC_inr_quantity, max_no_of_results=1)
        if len(INRs) > 0:
            tests2show.append('%s %s' %
                              (INRs[0]['abbrev_tt'], INRs[0]['unified_val']))
            tooltip_lines.append(
                _('%s: %s ago') % (INRs[0]['abbrev_tt'],
                                   gmDateTime.format_apparent_age_medically(
                                       age=gmDateTime.calculate_apparent_age(
                                           start=INRs[0]['clin_when']))))

        # include panel if configured, only show if exist
        if self.__lab_panel is not None:
            for result in self.__lab_panel.get_most_recent_results(
                    pk_patient=self.curr_pat.ID,
                    order_by='unified_abbrev',
                    group_by_meta_type=True):
                tests2show.append('%s %s' %
                                  (result['abbrev_tt'], result['unified_val']))
                tooltip_lines.append(
                    _('%s: %s ago') %
                    (result['abbrev_tt'],
                     gmDateTime.format_apparent_age_medically(
                         age=gmDateTime.calculate_apparent_age(
                             start=result['clin_when']))))
        self._LBL_lab.Label = '; '.join(tests2show)
        self._LBL_lab.SetToolTip('\n'.join(tooltip_lines))