File size: 7,438 Bytes
59f682e 1cc88fc 59f682e 1cc88fc 59f682e 449be20 1cc88fc 449be20 59f682e 1cc88fc 59f682e 1cc88fc 449be20 1cc88fc 449be20 1cc88fc 449be20 59f682e 449be20 59f682e 1cc88fc 59f682e cd20cc8 59f682e 1cc88fc 59f682e 1cc88fc 59f682e 1cc88fc 59f682e |
1 2 3 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
import streamlit as st
import pandas as pd
import plotly.graph_objs as go
# Step 1: Load the cleaned sheet "Clean TH avg rise BMD" and display it
def load_clean_bmd_data(file_path):
sheet_clean_th_avg_rise = 'Clean TH avg rise BMD'
df_clean_th_avg_rise = pd.read_excel(file_path, sheet_name=sheet_clean_th_avg_rise)
# Select relevant columns: Drug names and BMD percentage increases
df_cleaned = df_clean_th_avg_rise[['Unnamed: 0', '1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']]
# Rename the first column to 'Drug'
df_cleaned.columns = ['Drug', '1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']
# Remove any rows with missing drug names
df_cleaned = df_cleaned.dropna(subset=['Drug'])
return df_cleaned
# Step 2: Adjust constants based on patient's BMD and T-score
def adjust_constants(bmd_patient, tscore_patient, c_avg, c_sd):
# Adjust C_avg and C_sd based on patient's BMD and T-score
error = tscore_patient - (bmd_patient - c_avg) / c_sd
c_avg_new = c_avg + error * c_sd
c_sd_new = (bmd_patient - c_avg) / tscore_patient
return c_avg_new, c_sd_new
# Step 3: Calculate BMD increase after medication (corrected version)
def calculate_bmd_increase(baseline_bmd, percentage_increase):
return baseline_bmd * (1 + percentage_increase)
# Step 4: Create a table showing BMD prediction and T-score conversion for each year
def create_bmd_and_tscore_prediction_table(df_bmd_data, drug_selected, bmd_patient, c_avg_new, c_sd_new):
years = ['1st', '2nd', '3rd', '4th', '5th', '6th', '8th', '10th']
predictions = []
for drug in drug_selected:
for year in years:
if not pd.isna(df_bmd_data.loc[df_bmd_data['Drug'] == drug, year].values[0]):
percent_increase = df_bmd_data.loc[df_bmd_data['Drug'] == drug, year].values[0]
bmd_new = calculate_bmd_increase(bmd_patient, percent_increase) # Use baseline BMD
tscore_new = calculate_tscore_from_bmd(bmd_new, c_avg_new, c_sd_new) # Calculate predicted T-score
predictions.append((drug, year, bmd_new, tscore_new))
return pd.DataFrame(predictions, columns=['Drug', 'Year', 'Predicted BMD', 'Predicted T-score'])
# Step 5: Plot BMD and T-score as separate graphs side by side
def plot_bmd_and_tscore_separate(prediction_table, baseline_bmd, baseline_tscore):
years = ['0'] + list(prediction_table['Year'].unique())
# Plot for BMD
traces_bmd = []
for drug in prediction_table['Drug'].unique():
df_drug = prediction_table[prediction_table['Drug'] == drug]
bmd_values = [baseline_bmd] + list(df_drug['Predicted BMD'])
trace_bmd = go.Scatter(x=years, y=bmd_values, mode='lines+markers', name=drug + ' (BMD)')
traces_bmd.append(trace_bmd)
# Plot for T-score
traces_tscore = []
for drug in prediction_table['Drug'].unique():
df_drug = prediction_table[prediction_table['Drug'] == drug]
tscore_values = [baseline_tscore] + list(df_drug['Predicted T-score'])
trace_tscore = go.Scatter(x=years, y=tscore_values, mode='lines+markers', name=drug + ' (T-score)', yaxis='y2')
traces_tscore.append(trace_tscore)
# Create BMD layout
layout_bmd = go.Layout(
title="Predicted BMD over Time",
xaxis=dict(title='Years'),
yaxis=dict(title='BMD (g/cm²)', showgrid=False),
legend=dict(x=0.1, y=1.1, orientation='h')
)
# Create T-score layout
layout_tscore = go.Layout(
title="Predicted T-score over Time",
xaxis=dict(title='Years'),
yaxis2=dict(title='T-score', overlaying='y', side='right', showgrid=False),
legend=dict(x=0.1, y=1.1, orientation='h')
)
# Create BMD and T-score figures
fig_bmd = go.Figure(data=traces_bmd, layout=layout_bmd)
fig_tscore = go.Figure(data=traces_tscore, layout=layout_tscore)
# Use Streamlit columns to place two plots side by side
col1, col2 = st.columns(2)
with col1:
st.plotly_chart(fig_bmd)
with col2:
st.plotly_chart(fig_tscore)
# Step 6: Calculate T-score from adjusted BMD
def calculate_tscore_from_bmd(bmd_patient, c_avg, c_sd):
return (bmd_patient - c_avg) / c_sd
# Main function to load data, run the application, and plot results with T-score labels
def main_with_plot_tscore_labels(file_path, bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar, drug_selected):
# Step 1: Load and clean BMD data from the Excel sheet
df_bmd_data = load_clean_bmd_data(file_path)
# Step 2: Adjust constants based on the patient's data
c_avg_new, c_sd_new = adjust_constants(bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar)
# Step 4: Create the prediction table with BMD and T-score
prediction_table = create_bmd_and_tscore_prediction_table(df_bmd_data, drug_selected, bmd_patient, c_avg_new, c_sd_new)
# Display baseline BMD and T-score before the year-by-year comparison
st.write(f"Baseline: BMD = {bmd_patient:.3f}, T-score = {tscore_patient:.2f}")
st.write("BMD and T-score Prediction Table")
st.dataframe(prediction_table)
# Step 5: Plot the BMD and T-score graphs side by side
plot_bmd_and_tscore_separate(prediction_table, bmd_patient, tscore_patient)
# Step 6: Check if goal is achieved and show the predicted BMD and T-score for each year
for i, row in prediction_table.iterrows():
st.write(f"Year {row['Year']}: BMD = {row['Predicted BMD']:.3f}, T-score = {row['Predicted T-score']:.2f}")
# Check if the goal of BMD >= -2.4 is achieved
if row['Predicted T-score'] >= -2.4:
st.success(f"Goal achieved at year {row['Year']}")
break
# Streamlit UI
def main():
st.title("BMD and T-score Prediction Tool")
# Input patient data
bmd_patient = st.number_input("Initial BMD", min_value=0.0, max_value=2.0, value=0.635, step=0.001)
tscore_patient = st.number_input("Initial T-score", min_value=-5.0, max_value=2.0, value=-2.5, step=0.01)
# Drug options
drug_options = ['Teriparatide', 'Teriparatide + Denosumab', 'Denosumab', 'Denosumab + Teriparatide',
'Romosozumab', 'Romosozumab + Denosumab', 'Romosozumab + Alendronate',
'Romosozumab + Ibandronate', 'Romosozumab + Zoledronate', 'Alendronate',
'Risedronate', 'Ibandronate oral', 'Ibandronate IV (3mg)', 'Zoledronate']
# Add option to select all medications
selected_drugs = st.multiselect("Select drugs to compare", drug_options, default=None)
if "All Medications" in selected_drugs:
selected_drugs = drug_options # If "All Medications" is selected, include all drugs
# Set C_avg and C_sd for Lunar device (example values)
C_avg_lunar = 0.95 # Example: Average BMD for Total Hip from Excel (Lunar)
C_sd_lunar = 0.12 # Example: SD for Total Hip (Lunar)
# Example file path
file_path = "BMD constant calculator.xlsx"
# ตรวจสอบว่ามีการเลือกยาแล้วหรือไม่
if len(selected_drugs) == 0:
st.warning("Please select at least one drug to compare.")
else:
# Run prediction and plot results
if st.button("Predict"):
main_with_plot_tscore_labels(file_path, bmd_patient, tscore_patient, C_avg_lunar, C_sd_lunar, selected_drugs)
if __name__ == "__main__":
main()
|