Rathapoom commited on
Commit
4dd63ab
·
verified ·
1 Parent(s): a3e38d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -149
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
- # Step 1: Load the cleaned sheet based on the selected site
6
- def load_clean_bmd_data(file_path, site):
7
- sheet_name = ''
8
- if site == 'Total Hip':
9
- sheet_name = 'Clean TH avg rise BMD'
10
- elif site == 'Femoral Neck':
11
- sheet_name = 'clean FN avg rise BMD'
12
- elif site == 'Lumbar Spine (L1-L4)':
13
- sheet_name = 'clean LS avg rise BMD'
14
-
15
- df_clean_bmd_data = pd.read_excel(file_path, sheet_name=sheet_name)
16
-
17
- # Select relevant columns: Drug names and BMD percentage increases
18
- df_cleaned = df_clean_bmd_data[['Unnamed: 0', '1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']]
19
-
20
- # Rename the first column to 'Drug'
21
- df_cleaned.columns = ['Drug', '1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']
22
-
23
- # Remove any rows with missing drug names
24
- df_cleaned = df_cleaned.dropna(subset=['Drug'])
25
-
26
- return df_cleaned
27
-
28
- # Step 2: Adjust constants based on patient's BMD and T-score
29
- def adjust_constants(bmd_patient, tscore_patient, c_avg, c_sd):
30
- # Adjust C_avg and C_sd based on patient's BMD and T-score
31
- error = tscore_patient - (bmd_patient - c_avg) / c_sd
32
- c_avg_new = c_avg + error * c_sd
33
- c_sd_new = (bmd_patient - c_avg) / tscore_patient
34
- return c_avg_new, c_sd_new
35
-
36
- # Step 3: Calculate BMD increase after medication (corrected version)
37
- def calculate_bmd_increase(baseline_bmd, percentage_increase):
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(df_bmd_data.loc[df_bmd_data['Drug'] == drug, year].values[0]):
50
- percent_increase = df_bmd_data.loc[df_bmd_data['Drug'] == drug, year].values[0]
51
- bmd_new = calculate_bmd_increase(bmd_patient, percent_increase) # Use baseline BMD
52
- tscore_new = calculate_tscore_from_bmd(bmd_new, c_avg_new, c_sd_new) # Calculate predicted T-score
53
- predictions.append((year, bmd_new, tscore_new))
54
 
55
- # Create DataFrame for each drug
56
- drug_table = pd.DataFrame(predictions, columns=['Year', 'Predicted BMD', 'Predicted T-score'])
57
- drug_tables[drug] = drug_table
58
-
59
- return drug_tables
60
-
61
- # Step 5: Plot BMD and T-score as separate graphs side by side for each drug
62
- def display_prediction_tables_and_plots(prediction_tables, baseline_bmd, baseline_tscore):
63
- # Loop through each drug's prediction table
64
- for drug, table in prediction_tables.items():
65
- st.write(f"### {drug} Results")
 
 
 
 
 
66
 
67
- # Display the prediction table for the current drug
68
- st.dataframe(table)
69
-
70
- # Create and display separate plots for each drug
71
- years = list(table['Year'])
72
- bmd_values = list(table['Predicted BMD'])
73
- tscore_values = list(table['Predicted T-score'])
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 T-score plot
80
- trace_tscore = go.Scatter(x=years, y=tscore_values, mode='lines+markers', name=f'{drug} (T-score)', line=dict(color='green'))
81
- fig_tscore = go.Figure(data=[trace_tscore], layout=go.Layout(title=f'{drug} - Predicted T-score over Time', xaxis=dict(title='Years'), yaxis=dict(title='T-score')))
82
-
83
- # Display the plots
84
- col1, col2 = st.columns(2)
85
- with col1:
86
- st.plotly_chart(fig_bmd)
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.635, step=0.001, format="%.3f")
127
- tscore_patient = st.number_input("Initial T-score", min_value=-5.0, max_value=2.0, value=-2.5, step=0.01, format="%.2f")
128
-
129
- # Site options (Total Hip, Femoral Neck, Lumbar Spine)
130
- site_options = ['Total Hip', 'Femoral Neck', 'Lumbar Spine (L1-L4)']
131
- site = st.selectbox("Select site", site_options)
132
-
133
- # Drug options
134
- drug_options = ['Teriparatide', 'Teriparatide + Denosumab', 'Denosumab', 'Denosumab + Teriparatide',
135
- 'Romosozumab', 'Romosozumab + Denosumab', 'Romosozumab + Alendronate',
136
- 'Romosozumab + Ibandronate', 'Romosozumab + Zoledronate', 'Alendronate',
137
- 'Risedronate', 'Ibandronate oral', 'Ibandronate IV (3mg)', 'Zoledronate']
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()