Update app.py
Browse files
app.py
CHANGED
@@ -2,164 +2,98 @@ import streamlit as st
|
|
2 |
import pandas as pd
|
3 |
import plotly.graph_objs as go
|
4 |
|
5 |
-
#
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
return baseline_bmd * (1 + percentage_increase)
|
39 |
-
|
40 |
-
# Step 4: Create a table showing BMD prediction and T-score conversion for each year for each drug
|
41 |
-
def create_bmd_and_tscore_prediction_tables(df_bmd_data, selected_drugs, bmd_patient, tscore_patient, c_avg_new, c_sd_new):
|
42 |
-
years = ['1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']
|
43 |
-
drug_tables = {}
|
44 |
-
|
45 |
-
# Loop through each selected drug and generate the prediction table
|
46 |
-
for drug in selected_drugs:
|
47 |
-
predictions = [('0', bmd_patient, tscore_patient)] # Add initial value (Year 0)
|
48 |
for year in years:
|
49 |
-
if not pd.isna(
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
for
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
-
#
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
# Create BMD plot
|
76 |
-
trace_bmd = go.Scatter(x=years, y=bmd_values, mode='lines+markers', name=f'{drug} (BMD)', line=dict(color='blue'))
|
77 |
-
fig_bmd = go.Figure(data=[trace_bmd], layout=go.Layout(title=f'{drug} - Predicted BMD over Time', xaxis=dict(title='Years'), yaxis=dict(title='BMD (g/cm²)')))
|
78 |
|
79 |
-
# Create
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
with col2:
|
88 |
-
st.plotly_chart(fig_tscore)
|
89 |
-
|
90 |
-
# Step 6: Check if goal is achieved and show the predicted BMD and T-score for each year
|
91 |
-
goal_achieved = False
|
92 |
-
for i, row in table.iterrows():
|
93 |
-
if row['Predicted T-score'] >= -2.49:
|
94 |
-
st.success(f"Goal achieved for {drug} at year {row['Year']} with T-score = {row['Predicted T-score']:.2f}")
|
95 |
-
goal_achieved = True
|
96 |
-
break
|
97 |
-
if not goal_achieved:
|
98 |
-
st.warning(f"Goal not achieved for {drug}")
|
99 |
-
|
100 |
-
# Step 6: Calculate T-score from adjusted BMD
|
101 |
-
def calculate_tscore_from_bmd(bmd_patient, c_avg, c_sd):
|
102 |
-
return (bmd_patient - c_avg) / c_sd
|
103 |
-
|
104 |
-
# Main function to load data, run the application, and plot results with T-score labels
|
105 |
-
def main_with_separate_tables(file_path, bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar, selected_drugs, site):
|
106 |
-
# Step 1: Load and clean BMD data from the selected site (Total Hip, Femoral Neck, Lumbar Spine)
|
107 |
-
df_bmd_data = load_clean_bmd_data(file_path, site)
|
108 |
-
|
109 |
-
# Step 2: Adjust constants based on the patient's data
|
110 |
-
c_avg_new, c_sd_new = adjust_constants(bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar)
|
111 |
-
|
112 |
-
# Step 4: Create separate prediction tables for each selected drug
|
113 |
-
prediction_tables = create_bmd_and_tscore_prediction_tables(df_bmd_data, selected_drugs, bmd_patient, tscore_patient, c_avg_new, c_sd_new)
|
114 |
-
|
115 |
-
# Display baseline BMD and T-score
|
116 |
-
st.write(f"Baseline: BMD = {bmd_patient:.3f}, T-score = {tscore_patient:.2f}")
|
117 |
-
|
118 |
-
# Step 5: Display prediction tables and plots for each drug
|
119 |
-
display_prediction_tables_and_plots(prediction_tables, bmd_patient, tscore_patient)
|
120 |
|
121 |
# Streamlit UI
|
122 |
def main():
|
123 |
st.title("BMD and T-score Prediction Tool")
|
124 |
-
|
125 |
# Input patient data
|
126 |
-
bmd_patient = st.number_input("Initial BMD", min_value=0.0, max_value=2.0, value=0.
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
# Add option to select multiple drugs
|
140 |
-
selected_drugs = st.multiselect("Select drugs to compare", drug_options)
|
141 |
-
|
142 |
-
# Set constants for each site
|
143 |
-
if site == 'Total Hip':
|
144 |
-
C_avg_lunar = 0.95 # Example: Average BMD for Total Hip from Excel (Lunar)
|
145 |
-
C_sd_lunar = 0.12
|
146 |
-
elif site == 'Femoral Neck':
|
147 |
-
C_avg_lunar = 0.905 # Example: Average BMD for Femoral Neck from Excel (Lunar)
|
148 |
-
C_sd_lunar = 0.116 # Example: SD for Femoral Neck (Lunar)
|
149 |
-
elif site == 'Lumbar Spine (L1-L4)':
|
150 |
-
C_avg_lunar = 1.097 # Example: Average BMD for Lumbar Spine (L1-L4) from Excel (Lunar)
|
151 |
-
C_sd_lunar = 0.128 # Example: SD for Lumbar Spine (L1-L4) (Lunar)
|
152 |
-
|
153 |
-
# Example file path
|
154 |
-
file_path = "BMD constant calculator.xlsx"
|
155 |
-
|
156 |
-
# ตรวจสอบว่ามีการเลือกยาแล้วหรือไม่
|
157 |
-
if len(selected_drugs) == 0:
|
158 |
-
st.warning("Please select at least one drug to compare.")
|
159 |
-
else:
|
160 |
-
# Run prediction and plot results
|
161 |
-
if st.button("Predict"):
|
162 |
-
main_with_separate_tables(file_path, bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar, selected_drugs, site)
|
163 |
|
164 |
if __name__ == "__main__":
|
165 |
main()
|
|
|
2 |
import pandas as pd
|
3 |
import plotly.graph_objs as go
|
4 |
|
5 |
+
# Constants from linear regression
|
6 |
+
REGRESSION_CONSTANTS = {
|
7 |
+
'FN': {'mu': 0.916852, 'sigma': 0.120754},
|
8 |
+
'TH': {'mu': 0.955439, 'sigma': 0.125406},
|
9 |
+
'LS': {'mu': 1.131649, 'sigma': 0.139618},
|
10 |
+
}
|
11 |
+
|
12 |
+
# Load medication data
|
13 |
+
@st.cache_data
|
14 |
+
def load_medication_data():
|
15 |
+
# Use the combined medication data we cleaned earlier
|
16 |
+
file_path = "/mnt/data/BMD medication prediction.xlsx"
|
17 |
+
return pd.read_excel(file_path)
|
18 |
+
|
19 |
+
# Calculate predicted BMD after medication
|
20 |
+
def calculate_bmd(bmd, percentage_increase):
|
21 |
+
return bmd * (1 + percentage_increase)
|
22 |
+
|
23 |
+
# Convert BMD to T-score
|
24 |
+
def calculate_tscore(bmd, mu, sigma):
|
25 |
+
return (bmd - mu) / sigma
|
26 |
+
|
27 |
+
# Generate prediction table for all drugs
|
28 |
+
def generate_predictions(medication_data, site, bmd, mu, sigma):
|
29 |
+
site_data = medication_data[medication_data['Site'] == site]
|
30 |
+
years = ['1st Year', '2nd Year', '3rd Year', '4th Year', '5th Year', '6th Year', '8th Year', '10th Year']
|
31 |
+
|
32 |
+
prediction_results = []
|
33 |
+
for _, row in site_data.iterrows():
|
34 |
+
drug = row['Medication']
|
35 |
+
bmd_predictions = [bmd]
|
36 |
+
tscore_predictions = [calculate_tscore(bmd, mu, sigma)]
|
37 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
for year in years:
|
39 |
+
if not pd.isna(row[year]):
|
40 |
+
bmd_new = calculate_bmd(bmd_predictions[-1], row[year])
|
41 |
+
tscore_new = calculate_tscore(bmd_new, mu, sigma)
|
42 |
+
bmd_predictions.append(bmd_new)
|
43 |
+
tscore_predictions.append(tscore_new)
|
44 |
|
45 |
+
prediction_results.append({
|
46 |
+
'Drug': drug,
|
47 |
+
'BMD Predictions': bmd_predictions,
|
48 |
+
'T-score Predictions': tscore_predictions,
|
49 |
+
})
|
50 |
+
return prediction_results
|
51 |
+
|
52 |
+
# Display results as table and plots
|
53 |
+
def display_results(predictions, site):
|
54 |
+
st.subheader(f"Predictions for {site}")
|
55 |
+
|
56 |
+
for result in predictions:
|
57 |
+
drug = result['Drug']
|
58 |
+
bmd_predictions = result['BMD Predictions']
|
59 |
+
tscore_predictions = result['T-score Predictions']
|
60 |
+
years = ['0', '1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']
|
61 |
|
62 |
+
# Create table
|
63 |
+
data = {
|
64 |
+
'Year': years[:len(bmd_predictions)],
|
65 |
+
'Predicted BMD': bmd_predictions,
|
66 |
+
'Predicted T-score': tscore_predictions,
|
67 |
+
}
|
68 |
+
st.write(f"### {drug}")
|
69 |
+
st.dataframe(pd.DataFrame(data))
|
|
|
|
|
|
|
70 |
|
71 |
+
# Create plots
|
72 |
+
fig_bmd = go.Figure(data=[go.Scatter(x=data['Year'], y=data['Predicted BMD'], mode='lines+markers', name='BMD')])
|
73 |
+
fig_bmd.update_layout(title=f"{drug} - Predicted BMD over Time", xaxis_title="Year", yaxis_title="BMD (g/cm²)")
|
74 |
+
st.plotly_chart(fig_bmd)
|
75 |
+
|
76 |
+
fig_tscore = go.Figure(data=[go.Scatter(x=data['Year'], y=data['Predicted T-score'], mode='lines+markers', name='T-score')])
|
77 |
+
fig_tscore.update_layout(title=f"{drug} - Predicted T-score over Time", xaxis_title="Year", yaxis_title="T-score")
|
78 |
+
st.plotly_chart(fig_tscore)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
# Streamlit UI
|
81 |
def main():
|
82 |
st.title("BMD and T-score Prediction Tool")
|
83 |
+
|
84 |
# Input patient data
|
85 |
+
bmd_patient = st.number_input("Initial BMD", min_value=0.0, max_value=2.0, value=0.8, step=0.01)
|
86 |
+
site_options = ['FN', 'TH', 'LS']
|
87 |
+
site = st.selectbox("Select Region (Site)", site_options)
|
88 |
+
|
89 |
+
# Load constants and medication data
|
90 |
+
constants = REGRESSION_CONSTANTS[site]
|
91 |
+
medication_data = load_medication_data()
|
92 |
+
|
93 |
+
# Generate and display predictions
|
94 |
+
if st.button("Predict"):
|
95 |
+
predictions = generate_predictions(medication_data, site, bmd_patient, constants['mu'], constants['sigma'])
|
96 |
+
display_results(predictions, site)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
98 |
if __name__ == "__main__":
|
99 |
main()
|