File size: 6,460 Bytes
59f682e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449be20
 
 
59f682e
449be20
59f682e
449be20
59f682e
 
449be20
 
 
 
 
 
59f682e
449be20
59f682e
 
449be20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59f682e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449be20
 
59f682e
 
 
 
 
8f237ca
 
59f682e
 
 
 
 
 
 
 
cd20cc8
 
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
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 year in years:
        if not pd.isna(df_bmd_data.loc[df_bmd_data['Drug'] == drug_selected, year].values[0]):
            percent_increase = df_bmd_data.loc[df_bmd_data['Drug'] == drug_selected, 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((year, bmd_new, tscore_new))

    return pd.DataFrame(predictions, columns=['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'])
    bmd_values = [baseline_bmd] + list(prediction_table['Predicted BMD'])
    tscore_values = [baseline_tscore] + list(prediction_table['Predicted T-score'])

    # Create BMD plot
    trace_bmd = go.Scatter(x=years, y=bmd_values, mode='lines+markers', name='BMD', line=dict(color='blue'))

    # Create T-score plot
    trace_tscore = go.Scatter(x=years, y=tscore_values, mode='lines+markers', name='T-score', line=dict(color='green'))

    # Layout for BMD graph
    layout_bmd = go.Layout(
        title="Predicted BMD over Time",
        xaxis=dict(title='Years'),
        yaxis=dict(title='BMD (g/cm²)', showgrid=False)
    )

    # Layout for T-score graph
    layout_tscore = go.Layout(
        title="Predicted T-score over Time",
        xaxis=dict(title='Years'),
        yaxis=dict(title='T-score', showgrid=False)
    )

    # Create figures
    fig_bmd = go.Figure(data=[trace_bmd], layout=layout_bmd)
    fig_tscore = go.Figure(data=[trace_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.49 is achieved
        if row['Predicted T-score'] >= -2.49:
            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)

    # Select drug
    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']
    drug_selected = st.selectbox("Select a drug", drug_options)

    # 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"

    # 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, drug_selected)

if __name__ == "__main__":
    main()