Rathapoom's picture
Update app.py
1cc88fc verified
raw
history blame
7.44 kB
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()