mqadir commited on
Commit
9a17ca8
·
verified ·
1 Parent(s): 0b1229a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -2
app.py CHANGED
@@ -76,19 +76,62 @@ def extract_features(seg_path, high_risk_threshold_mm=5.0):
76
 
77
  def calculate_risk_and_format(mask_path, no_chemo, pd_surgery):
78
  """Runs extraction, ML prediction, and formats UI output."""
 
79
  mac, vev, aev, ttv = extract_features(mask_path)
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  if risk_model is not None:
82
- features = np.array([[mac, vev, aev, ttv, int(no_chemo), int(pd_surgery)]])
 
 
 
 
 
 
 
 
 
 
83
  prob_r1 = risk_model.predict_proba(features)[0][1]
84
  else:
85
  prob_r1 = 0.72 # Fallback dummy
86
 
 
87
  risk_percentage = prob_r1 * 100
88
  risk_color = "red" if risk_percentage > 50 else "green"
89
  risk_display = f"<h2 style='color: {risk_color}; margin-top: 0;'>Predicted probability of R1 resection: {risk_percentage:.1f}%</h2>"
90
 
91
- return (gr.update(value="", visible=False), f"{mac:.1f}", f"{vev:.1f}", f"{aev:.1f}", f"{ttv:.1f}", risk_display)
 
 
 
 
 
 
 
 
 
92
 
93
 
94
  # PIPELINE HANDLERS
 
76
 
77
  def calculate_risk_and_format(mask_path, no_chemo, pd_surgery):
78
  """Runs extraction, ML prediction, and formats UI output."""
79
+ # 1. Extract raw metrics
80
  mac, vev, aev, ttv = extract_features(mask_path)
81
 
82
+ # Convert textboxes safely
83
+ try:
84
+ chemo_val = int(no_chemo)
85
+ pd_val = int(pd_surgery)
86
+ except ValueError:
87
+ error_msg = "**Error:** Clinical metadata fields must be numbers (1 or 0)."
88
+ return (gr.update(value=error_msg, visible=True), "", "", "", "", "")
89
+
90
+ # 2. Hardcode the Means and Stds from your training data
91
+ # Extracted from your means/stds arrays based on their index positions
92
+ TTV_MEAN, TTV_STD = 8980.23827, 8281.19811
93
+ MAC_MEAN, MAC_STD = 8.53567157, 8.92353600
94
+ AEV_MEAN, AEV_STD = 155.784393, 367.152035
95
+ VEV_MEAN, VEV_STD = 576.025386, 559.944824
96
+
97
+ # 3. Apply Z-score Normalization
98
+ scaled_ttv = (ttv - TTV_MEAN) / TTV_STD
99
+ scaled_mac = (mac - MAC_MEAN) / MAC_STD
100
+ scaled_aev = (aev - AEV_MEAN) / AEV_STD
101
+ scaled_vev = (vev - VEV_MEAN) / VEV_STD
102
+
103
+ # 4. Predict Risk
104
  if risk_model is not None:
105
+ # STRICT ORDER MATCHING your column_order:
106
+ # ['Chemo_0', 'Surgery_1', 'Total_Tumor_Volume_mm3_arterial', 'Min_Distance_mm_arterial', 'High_Risk_Volume_mm3_5mm_arterial', 'High_Risk_Volume_mm3_5mm_venous']
107
+ features = np.array([[
108
+ chemo_val, # Chemo_0
109
+ pd_val, # Surgery_1
110
+ scaled_ttv, # Total_Tumor_Volume_mm3_arterial
111
+ scaled_mac, # Min_Distance_mm_arterial
112
+ scaled_aev, # High_Risk_Volume_mm3_5mm_arterial
113
+ scaled_vev # High_Risk_Volume_mm3_5mm_venous
114
+ ]])
115
+
116
  prob_r1 = risk_model.predict_proba(features)[0][1]
117
  else:
118
  prob_r1 = 0.72 # Fallback dummy
119
 
120
+ # 5. Format Outputs
121
  risk_percentage = prob_r1 * 100
122
  risk_color = "red" if risk_percentage > 50 else "green"
123
  risk_display = f"<h2 style='color: {risk_color}; margin-top: 0;'>Predicted probability of R1 resection: {risk_percentage:.1f}%</h2>"
124
 
125
+ # Notice we still display the RAW un-normalized values to the user in the UI,
126
+ # but the model calculates risk using the SCALED values.
127
+ return (
128
+ gr.update(value="", visible=False),
129
+ f"{mac:.1f}",
130
+ f"{vev:.1f}",
131
+ f"{aev:.1f}",
132
+ f"{ttv:.1f}",
133
+ risk_display
134
+ )
135
 
136
 
137
  # PIPELINE HANDLERS