1- import requests
21import os
2+
3+
4+
5+ import requests
6+ import rpy2 .robjects as ro
7+ from rpy2 .robjects .packages import importr
8+ from rpy2 .robjects .vectors import FloatVector , StrVector
39from flask import Flask , request , render_template , redirect , url_for
410from dotenv import load_dotenv
511from datetime import datetime
612
713app = Flask (__name__ )
814
9- FHIR_SERVER_BASE_URL = "http://pwebmedcit.services.brown.edu:9091/fhir"
15+ # Import the PooledCohort package in R
16+ pooled_cohort = importr ("PooledCohort" )
1017
18+ # Load environment variables
1119load_dotenv ()
1220
21+ FHIR_SERVER_BASE_URL = os .getenv ("FHIR_SERVER_BASE_URL" )
1322username = os .getenv ("FHIR_USERNAME" )
1423password = os .getenv ("FHIR_PASSWORD" )
1524
25+ # Set environment variables for R from .env
26+ os .environ ['R_HOME' ] = os .getenv ('R_HOME' )
27+ os .environ ['R_USER' ] = os .getenv ('R_USER' )
28+
1629observation_codes = {
1730 "Systolic Blood Pressure" : "8480-6" ,
1831 "Diastolic Blood Pressure" : "8462-4" ,
2134 "LDL Cholesterol" : "18262-6"
2235}
2336
37+ race_mapping = {
38+ "American Indian or Alaska Native" : "white" ,
39+ "Asian" : "white" ,
40+ "Black or African American" : "black" ,
41+ "Native Hawaiian or Other Pacific Islander" : "white" ,
42+ "White" : "white"
43+ }
44+
2445def get_observation_value (entry ):
2546 if 'valueQuantity' in entry ['resource' ]:
2647 return entry ['resource' ]['valueQuantity' ]['value' ]
@@ -48,15 +69,12 @@ def get_patient_demographics(patient_id, credentials):
4869 age = calculate_age (birth_date )
4970 sex = patient ['gender' ]
5071 race = 'Not Found'
51-
52- # Extract race from extensions
5372 for extension in patient .get ('extension' , []):
5473 if extension ['url' ] == 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race' :
5574 for ext in extension .get ('extension' , []):
5675 if ext ['url' ] == 'ombCategory' :
57- race = ext ['valueCoding' ]['display' ]
76+ race = race_mapping . get ( ext ['valueCoding' ]['display' ], 'white' )
5877 break
59-
6078 return {'age' : age , 'sex' : sex , 'race' : race }
6179 else :
6280 return {'age' : 'Not Found' , 'sex' : 'Not Found' , 'race' : 'Not Found' }
@@ -76,26 +94,6 @@ def get_patient_observations(patient_id, credentials):
7694 observations [obs_name ] = 'Not Found'
7795 return observations , demographics
7896
79- def calculate_ascvd_risk (age , sex , race , total_cholesterol , hdl_cholesterol , systolic_bp , on_hypertension_treatment , diabetes , smoker ):
80- # Simplified ASCVD risk calculation
81- # Note: This is a placeholder. Use a proper ASCVD risk calculator for accurate results.
82- risk_score = 0
83- if sex == 'male' :
84- risk_score += 1
85- if race == 'African American' :
86- risk_score += 1
87- risk_score += age / 10
88- risk_score += total_cholesterol / 50
89- risk_score -= hdl_cholesterol / 50
90- risk_score += systolic_bp / 20
91- if on_hypertension_treatment == 'yes' :
92- risk_score += 1
93- if diabetes == 'yes' :
94- risk_score += 1
95- if smoker == 'yes' :
96- risk_score += 1
97- return round (risk_score , 2 )
98-
9997@app .route ('/' , methods = ['GET' , 'POST' ])
10098def index ():
10199 observations = None
@@ -124,21 +122,46 @@ def calculate_risk():
124122 smoker = request .form ['smoker' ]
125123 hypertension = request .form ['hypertension' ]
126124
127- ascvd_risk = calculate_ascvd_risk (age , sex , race , total_cholesterol , hdl_cholesterol , systolic_bp , hypertension , diabetes , smoker )
125+ # Convert sex and race to R compatible formats
126+ sex_r = StrVector ([sex ])
127+ race_r = StrVector ([race_mapping .get (race , 'white' )])
128+
129+ # Convert other inputs to R compatible formats
130+ age_r = FloatVector ([age ])
131+ total_cholesterol_r = FloatVector ([total_cholesterol ])
132+ hdl_cholesterol_r = FloatVector ([hdl_cholesterol ])
133+ systolic_bp_r = FloatVector ([systolic_bp ])
134+ diabetes_r = StrVector (['yes' if diabetes == 'yes' else 'no' ])
135+ smoker_r = StrVector (['yes' if smoker == 'yes' else 'no' ])
136+ hypertension_r = StrVector (['yes' if hypertension == 'yes' else 'no' ])
137+
138+ # Call the ASCVD risk calculation function from PooledCohort
139+ ascvd_risk_r = pooled_cohort .predict_10yr_ascvd_risk (
140+ sex = sex_r ,
141+ race = race_r ,
142+ age_years = age_r ,
143+ chol_total_mgdl = total_cholesterol_r ,
144+ chol_hdl_mgdl = hdl_cholesterol_r ,
145+ bp_sys_mmhg = systolic_bp_r ,
146+ bp_meds = hypertension_r ,
147+ smoke_current = smoker_r ,
148+ diabetes = diabetes_r
149+ )
150+
151+ # Convert the result back to Python
152+ ascvd_risk = list (ascvd_risk_r )[0 ]* 100
128153
129- # Maintain the form values for observations and demographics
130154 demographics = {'age' : age , 'sex' : sex , 'race' : race }
131155 observations = {
132156 'Total Cholesterol' : total_cholesterol ,
133157 'HDL Cholesterol' : hdl_cholesterol ,
134158 'Systolic Blood Pressure' : systolic_bp ,
135- 'Diastolic Blood Pressure' : request .form ['diastolic_blood_pressure' ] if 'diastolic_blood_pressure' in request .form else 'Not Found' ,
136- 'LDL Cholesterol' : request .form ['ldl_cholesterol' ] if 'ldl_cholesterol' in request .form else 'Not Found'
159+ 'Diastolic Blood Pressure' : request .form ['diastolic_blood_pressure' ] if 'diastolic_blood_pressure' in request .form else 'Not Found'
137160 }
138161
139162 return render_template ('index.html' , ascvd_risk = ascvd_risk , demographics = demographics , observations = observations , patient_id = patient_id )
140163
141164if __name__ == '__main__' :
142- port_str = os .environ [ 'FHIR_PORT' ]
165+ port_str = os .getenv ( 'FHIR_PORT' , '5000' )
143166 port_int = int (port_str )
144167 app .run (debug = True , port = port_int )
0 commit comments