app/lib/risk_engine/hazard_ratios.dart
John Mizerek 40275bcd0c Add lifestyle factors screen with diet, social, stress tracking
- Split behavioral inputs into two screens (Habits + Lifestyle)
- Added 5 new modifiable factors: diet quality, processed food,
  drug use, social connection, and stress level
- Updated hazard ratios for all new factors based on meta-analyses
- Model version bumped to 1.1
- Simplified welcome screen with clearer value proposition
- Updated tests for expanded behavioral model

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-21 09:22:48 -08:00

248 lines
5.5 KiB
Dart

import '../models/models.dart';
/// Hazard ratios based on conservative estimates from meta-analyses.
/// All HRs are relative to optimal baseline (HR = 1.0).
double getSmokingHR(SmokingStatus status, int cigarettesPerDay) {
switch (status) {
case SmokingStatus.never:
return 1.0;
case SmokingStatus.former:
return 1.3;
case SmokingStatus.current:
if (cigarettesPerDay < 10) return 1.8;
if (cigarettesPerDay <= 20) return 2.2;
return 2.8;
}
}
double getAlcoholHR(AlcoholLevel level) {
switch (level) {
case AlcoholLevel.none:
case AlcoholLevel.light:
return 1.0;
case AlcoholLevel.moderate:
return 1.1;
case AlcoholLevel.heavy:
return 1.3;
case AlcoholLevel.veryHeavy:
return 1.6;
}
}
double getSleepHR(double hours, bool consistent) {
double hr;
if (hours >= 7 && hours <= 8) {
hr = 1.0;
} else if (hours >= 6 && hours < 7) {
hr = 1.05;
} else if (hours < 6) {
hr = 1.15;
} else {
// > 8 hours
hr = 1.10;
}
if (!consistent) {
hr *= 1.05;
}
return hr;
}
double getActivityHR(ActivityLevel level) {
switch (level) {
case ActivityLevel.high:
return 1.0;
case ActivityLevel.moderate:
return 1.05;
case ActivityLevel.light:
return 1.15;
case ActivityLevel.sedentary:
return 1.4;
}
}
double getBmiHR(double bmi) {
if (bmi >= 18.5 && bmi < 25) return 1.0;
if (bmi >= 25 && bmi < 30) return 1.1;
if (bmi >= 30 && bmi < 35) return 1.2;
if (bmi >= 35 && bmi < 40) return 1.4;
if (bmi >= 40) return 1.8;
return 1.15; // Underweight
}
double getDrivingHR(DrivingExposure level) {
switch (level) {
case DrivingExposure.low:
return 1.0;
case DrivingExposure.moderate:
return 1.02;
case DrivingExposure.high:
return 1.04;
case DrivingExposure.veryHigh:
return 1.08;
}
}
double getWorkHoursHR(WorkHoursLevel level) {
switch (level) {
case WorkHoursLevel.normal:
return 1.0;
case WorkHoursLevel.elevated:
return 1.05;
case WorkHoursLevel.high:
return 1.15;
case WorkHoursLevel.extreme:
return 1.3;
}
}
// --- New lifestyle factors ---
/// Diet quality - based on Mediterranean diet studies
double getDietHR(DietQuality level) {
switch (level) {
case DietQuality.excellent:
return 1.0;
case DietQuality.good:
return 1.05;
case DietQuality.fair:
return 1.15;
case DietQuality.poor:
return 1.3;
}
}
/// Processed food consumption - ultra-processed food studies
double getProcessedFoodHR(ProcessedFoodLevel level) {
switch (level) {
case ProcessedFoodLevel.rarely:
return 1.0;
case ProcessedFoodLevel.occasional:
return 1.05;
case ProcessedFoodLevel.frequent:
return 1.12;
case ProcessedFoodLevel.daily:
return 1.2;
}
}
/// Drug use - excluding alcohol/tobacco (cannabis, recreational drugs)
double getDrugUseHR(DrugUse level) {
switch (level) {
case DrugUse.none:
return 1.0;
case DrugUse.occasional:
return 1.05;
case DrugUse.regular:
return 1.15;
case DrugUse.daily:
return 1.35;
}
}
/// Social connection - loneliness/isolation meta-analyses
double getSocialHR(SocialConnection level) {
switch (level) {
case SocialConnection.strong:
return 1.0;
case SocialConnection.moderate:
return 1.05;
case SocialConnection.limited:
return 1.2;
case SocialConnection.isolated:
return 1.45;
}
}
/// Chronic stress - based on allostatic load research
double getStressHR(StressLevel level) {
switch (level) {
case StressLevel.low:
return 1.0;
case StressLevel.moderate:
return 1.05;
case StressLevel.high:
return 1.15;
case StressLevel.chronic:
return 1.35;
}
}
/// Existing conditions modify baseline mortality but are NOT modifiable.
double getDiagnosisHR(Set<Diagnosis> diagnoses) {
double hr = 1.0;
for (final diagnosis in diagnoses) {
switch (diagnosis) {
case Diagnosis.cardiovascular:
hr *= 1.5;
break;
case Diagnosis.diabetes:
hr *= 1.4;
break;
case Diagnosis.cancer:
hr *= 2.0;
break;
case Diagnosis.copd:
hr *= 1.6;
break;
case Diagnosis.hypertension:
hr *= 1.2;
break;
}
}
return hr;
}
/// Confidence levels for each behavior based on evidence quality.
Confidence getConfidenceForBehavior(String behaviorKey) {
switch (behaviorKey) {
case 'smoking':
case 'alcohol':
case 'activity':
case 'social':
return Confidence.high;
case 'sleep':
case 'workHours':
case 'diet':
case 'stress':
return Confidence.moderate;
case 'driving':
case 'processedFood':
case 'drugUse':
return Confidence.emerging;
default:
return Confidence.moderate;
}
}
/// Display names for behaviors.
String getDisplayName(String behaviorKey) {
switch (behaviorKey) {
case 'smoking':
return 'Smoking';
case 'alcohol':
return 'Alcohol Consumption';
case 'sleep':
return 'Sleep';
case 'activity':
return 'Physical Activity';
case 'driving':
return 'Driving Exposure';
case 'workHours':
return 'Work Hours';
case 'diet':
return 'Diet Quality';
case 'processedFood':
return 'Processed Food';
case 'drugUse':
return 'Drug Use';
case 'social':
return 'Social Connection';
case 'stress':
return 'Chronic Stress';
default:
return behaviorKey;
}
}