module Framingham::Heartdisease

Constants

AGE
AGE_RANGE
BETA_ZERO
BLOOD_PRESSURE
BLOOD_PRESSURE_RANGE
BMI_RANGE
BODY_MASS_INDEX
DIABETES
ERRORS
NORMAL
OPTIMAL
POWER_BASE
SMOKER

Public Instance Methods

eval(options = {}) click to toggle source
# File framingham/heartdisease.rb, line 4
def eval options = {}
  begin
    #initialize
    options = NORMAL.merge options
    @age = options[:age].to_f
    @blood_pressure = options[:blood_pressure].to_f
    @blood_pressure_treatment = options[:blood_pressure_treatment] ? :treated : :untreated
    @body_mass_index = options[:body_mass_index].to_f
    @gender = options[:gender].to_sym
    @diabetes = to_i options[:diabetes]
    @smoker = to_i options[:smoker]
    #validate
    raise ERRORS[:gender] unless GENDERS.include? @gender
  rescue => exception
    abort "\033[31merror: " + exception.message + "\033[0m"
  else
    #calculate
    start_beta = BETA_ZERO[@gender] + Math.log(@age) * AGE[@gender]
    risk = 1 - POWER_BASE[@gender] ** Math.exp(
      start_beta +
      Math.log(@blood_pressure) * BLOOD_PRESSURE[@gender][@blood_pressure_treatment] +
      Math.log(@body_mass_index) * BODY_MASS_INDEX[@gender] +
      @diabetes * DIABETES[@gender] +
      @smoker * SMOKER[@gender]
    )
    normal = 1 - POWER_BASE[@gender] ** Math.exp(
      start_beta +
      Math.log(NORMAL[:blood_pressure]) * BLOOD_PRESSURE[@gender][:untreated] +
      Math.log(NORMAL[:body_mass_index]) * BODY_MASS_INDEX[@gender]
    )
    optimal = 1 - POWER_BASE[@gender] ** Math.exp(
      start_beta +
      Math.log(OPTIMAL[:blood_pressure]) * BLOOD_PRESSURE[@gender][:untreated] +
      Math.log(OPTIMAL[:body_mass_index]) * BODY_MASS_INDEX[@gender]
    )
    age_range = 10..86
    age = 0
    heart_age = lambda{
      while (age_range.max - age_range.min) > 0.2 do
        age = (age_range.max + age_range.min) / 2.0
        test_risk = 1 - POWER_BASE[@gender] ** Math.exp(
          BETA_ZERO[@gender] + Math.log(age) * AGE[@gender] +
          Math.log(NORMAL[:blood_pressure]) * BLOOD_PRESSURE[@gender][:untreated] +
          Math.log(NORMAL[:body_mass_index]) * BODY_MASS_INDEX[@gender]
        )
        age_range = test_risk < risk ? age..age_range.max : age_range = age_range.min..age
      end
      age
    }.call
    {
      heart_age: heart_age,
      risk:      risk,
      normal:    normal,
      optimal:   optimal
    }
  end
end
help() click to toggle source
# File framingham/heartdisease.rb, line 70
def help
  "Evaluate 10 year heart disease risk"
end
pretty(_) click to toggle source
# File framingham/heartdisease.rb, line 62
def pretty _
  result = eval _
  puts "Heart Age: " + result[:heart_age].to_i.to_s
  puts "Risk:      " + "%4.1f%%" % (result[:risk] * 100)
  puts "Normal:    " + "%4.1f%%" % (result[:normal] * 100)
  puts "Optimal:   " + "%4.1f%%" % (result[:optimal] * 100)
end

Protected Instance Methods

internal_debug(_ = {}) click to toggle source
# File framingham/heartdisease.rb, line 76
def internal_debug _ = {}
  _ = eval _
  '%i' % _[:heart_age].round +
  '%5.1f' % ((1000 * _[:risk]).round / 10.0) +
  '%5.1f' % ((1000 * _[:normal]).round / 10.0) +
  '%5.1f' % ((1000 * _[:optimal]).round / 10.0)
end