shivapriyasom commited on
Commit
309e1e1
Β·
verified Β·
1 Parent(s): b12b769

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +472 -0
app.py ADDED
@@ -0,0 +1,472 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import traceback
4
+
5
+ from inference import (
6
+ FEATURE_NAMES,
7
+ REPORTING_OUTCOMES,
8
+ OUTCOME_DESCRIPTIONS,
9
+ OUTCOMES,
10
+ SHAP_OUTCOMES,
11
+ predict_with_comparison,
12
+ create_all_shap_plots,
13
+ create_all_pie_charts,
14
+ )
15
+
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # Choice lists
19
+ # ---------------------------------------------------------------------------
20
+
21
+ AGEGPFF_CHOICES = ["<=10", "11-17", "18-29", "30-49", ">=50"]
22
+ SEX_CHOICES = ["Male", "Female"]
23
+ KPS_CHOICES = ["<90", "β‰₯ 90"]
24
+ DONORF_CHOICES = [
25
+ "HLA identical sibling",
26
+ "HLA mismatch relative",
27
+ "Matched unrelated donor",
28
+ "Mismatched unrelated donor or cord blood",
29
+ ]
30
+ GRAFTYPE_CHOICES = ["Bone marrow", "Peripheral blood", "Cord blood"]
31
+ CONDGRPF_CHOICES = ["MAC", "RIC", "NMA"]
32
+ CONDGRP_FINAL_CHOICES = [
33
+ "TBI/Cy", "TBI/Cy/Flu", "TBI/Cy/Flu/TT", "TBI/Mel", "TBI/Flu",
34
+ "TBI alone (300/400/600cGy)", "Bu/Cy", "Bu/Mel", "Flu/Bu/TT",
35
+ "Flu/Bu", "Flu/Mel/TT", "Flu/Mel", "Cy/Flu", "Treosulfan",
36
+ "Cy alone", "Flud", "TLI",
37
+ ]
38
+ ATGF_CHOICES = ["ATG", "Alemtuzumab", "None"]
39
+ GVHD_FINAL_CHOICES = [
40
+ "Ex-vivo T-cell depletion", "CD34 selection", "Post-CY + siro +- MMF",
41
+ "Post-CY + MMF + CNI", "CNI + MMF", "CNI + MTX", "CNI alone",
42
+ "CNI + siro", "Siro alone", "MMF + MTX", "MMF + siro", "MMF alone",
43
+ "MTX alone", "MTX + siro",
44
+ ]
45
+ HLA_FINAL_CHOICES = ["8/8", "7/8", "≀ 6/8"]
46
+ RCMVPR_CHOICES = ["Negative", "Positive"]
47
+ EXCHTFPR_CHOICES = ["No", "Yes"]
48
+ VOC2YPR_CHOICES = ["No", "Yes"]
49
+ VOCFRQPR_CHOICES = ["< 3/yr", "β‰₯ 3/yr"]
50
+ SCATXRSN_CHOICES = [
51
+ "CNS event", "Acute chest Syndrome", "Recurrent vaso-occlusive pain",
52
+ "Recurrent priapism", "Excessive transfusion requirements/iron overload",
53
+ "Cardio-pulmonary", "Chronic transfusion", "Asymptomatic",
54
+ "Renal insufficiency", "Splenic sequestration", "Avascular necrosis",
55
+ "Hodgkin lymphoma",
56
+ ]
57
+
58
+
59
+ # ---------------------------------------------------------------------------
60
+ # Grouped published-regimen dropdown
61
+ # ---------------------------------------------------------------------------
62
+
63
+ GROUPED_REGIMEN_CHOICES = [
64
+ ("── HLA IDENTICAL ──", "__header_hla_identical__"),
65
+ ("Hsieh et al 2014", "Hsieh et al 2014"),
66
+ ("Krishnamurti et al 2019", "Krishnamurti et al 2019"),
67
+ ("King et al 2015", "King et al 2015"),
68
+ ("Walters et al 1996", "Walters et al 1996"),
69
+ ("── HLA MISMATCHED ──", "__header_hla_mismatched__"),
70
+ ("Bolanos-Meade et al 2022 (HLA Mismatch)", "Bolanos-Meade et al 2022 (HLA Mismatch)"),
71
+ ("Patel et al 2020 (HLA Mismatch)", "Patel et al 2020 (HLA Mismatch)"),
72
+ ("── MATCHED UNRELATED ──", "__header_matched_unrelated__"),
73
+ ("L Krishnamurti et al 2019", "L Krishnamurti et al 2019"),
74
+ ("Shenoy et al 2016", "Shenoy et al 2016"),
75
+ ("── MISMATCHED UNRELATED / CORD BLOOD ──", "__header_mismatched_cord__"),
76
+ ("Bolanos-Meade et al 2022 (Mismatched/Cord)", "Bolanos-Meade et al 2022 (Mismatched/Cord)"),
77
+ ("Patel et al 2020 (Mismatched/Cord)", "Patel et al 2020 (Mismatched/Cord)"),
78
+ ]
79
+
80
+ HEADER_VALUES = {v for _, v in GROUPED_REGIMEN_CHOICES if v.startswith("__header_")}
81
+
82
+ PUBLISHED_PRESETS = {
83
+ # HLA Identical Sibling
84
+ "Hsieh et al 2014": {
85
+ "CONDGRPF": "NMA", "CONDGRP_FINAL": "TBI alone (300/400/600cGy)",
86
+ "ATGF": "Alemtuzumab", "GVHD_FINAL": "Siro alone",
87
+ "HLA_FINAL": "8/8", "DONORF": "HLA identical sibling",
88
+ },
89
+ "Krishnamurti et al 2019": {
90
+ "CONDGRPF": "MAC", "CONDGRP_FINAL": "Flu/Bu",
91
+ "ATGF": "ATG", "GVHD_FINAL": "CNI + MTX",
92
+ "HLA_FINAL": "8/8", "DONORF": "HLA identical sibling",
93
+ },
94
+ "King et al 2015": {
95
+ "CONDGRPF": "RIC", "CONDGRP_FINAL": "Flu/Mel",
96
+ "ATGF": "Alemtuzumab", "GVHD_FINAL": "CNI + MTX",
97
+ "HLA_FINAL": "8/8", "DONORF": "HLA identical sibling",
98
+ },
99
+ "Walters et al 1996": {
100
+ "CONDGRPF": "MAC", "CONDGRP_FINAL": "Bu/Cy",
101
+ "ATGF": "ATG", "GVHD_FINAL": "CNI + MTX",
102
+ "HLA_FINAL": "8/8", "DONORF": "HLA identical sibling",
103
+ },
104
+ # HLA Mismatch Relative
105
+ "Bolanos-Meade et al 2022 (HLA Mismatch)": {
106
+ "CONDGRPF": "NMA", "CONDGRP_FINAL": "TBI/Cy/Flu",
107
+ "ATGF": "ATG", "GVHD_FINAL": "Post-CY + siro +- MMF",
108
+ "HLA_FINAL": "7/8", "DONORF": "HLA mismatch relative",
109
+ },
110
+ "Patel et al 2020 (HLA Mismatch)": {
111
+ "CONDGRPF": "NMA", "CONDGRP_FINAL": "TBI/Cy/Flu/TT",
112
+ "ATGF": "ATG", "GVHD_FINAL": "Post-CY + siro +- MMF",
113
+ "HLA_FINAL": "7/8", "DONORF": "HLA mismatch relative",
114
+ },
115
+ # Matched Unrelated Donor
116
+ "L Krishnamurti et al 2019": {
117
+ "CONDGRPF": "MAC", "CONDGRP_FINAL": "Flu/Bu",
118
+ "ATGF": "ATG", "GVHD_FINAL": "CNI + MTX",
119
+ "HLA_FINAL": "8/8", "DONORF": "Matched unrelated donor",
120
+ },
121
+ "Shenoy et al 2016": {
122
+ "CONDGRPF": "RIC", "CONDGRP_FINAL": "Flu/Mel",
123
+ "ATGF": "Alemtuzumab", "GVHD_FINAL": "CNI + MTX",
124
+ "HLA_FINAL": "8/8", "DONORF": "Matched unrelated donor",
125
+ },
126
+ # Mismatched Unrelated Donor or Cord Blood
127
+ "Bolanos-Meade et al 2022 (Mismatched/Cord)": {
128
+ "CONDGRPF": "NMA", "CONDGRP_FINAL": "TBI/Cy/Flu",
129
+ "ATGF": "ATG", "GVHD_FINAL": "Post-CY + siro +- MMF",
130
+ "HLA_FINAL": "7/8", "DONORF": "Mismatched unrelated donor or cord blood",
131
+ },
132
+ "Patel et al 2020 (Mismatched/Cord)": {
133
+ "CONDGRPF": "NMA", "CONDGRP_FINAL": "TBI/Cy/Flu/TT",
134
+ "ATGF": "ATG", "GVHD_FINAL": "Post-CY + siro +- MMF",
135
+ "HLA_FINAL": "7/8", "DONORF": "Mismatched unrelated donor or cord blood",
136
+ },
137
+ }
138
+
139
+
140
+ # ---------------------------------------------------------------------------
141
+ # Feature groupings
142
+ # ---------------------------------------------------------------------------
143
+
144
+ PATIENT_FEATURES = ["AGE", "AGEGPFF", "SEX", "KPS", "RCMVPR"]
145
+ DONOR_FEATURES = ["DONORF", "GRAFTYPE", "HLA_FINAL",
146
+ "CONDGRPF", "CONDGRP_FINAL", "ATGF", "GVHD_FINAL"]
147
+ DISEASE_FEATURES = ["NACS2YR", "EXCHTFPR", "VOC2YPR", "VOCFRQPR", "SCATXRSN"]
148
+ ALL_FEATURES = PATIENT_FEATURES + DONOR_FEATURES + DISEASE_FEATURES
149
+
150
+
151
+ # ---------------------------------------------------------------------------
152
+ # Utility callbacks
153
+ # ---------------------------------------------------------------------------
154
+
155
+ def get_age_group(age):
156
+ if age is None or age == "":
157
+ return ""
158
+ try:
159
+ age = float(age)
160
+ if age <= 10:
161
+ return "<=10"
162
+ elif age <= 17:
163
+ return "11-17"
164
+ elif age <= 29:
165
+ return "18-29"
166
+ elif age <= 49:
167
+ return "30-49"
168
+ else:
169
+ return ">=50"
170
+ except (ValueError, TypeError):
171
+ return ""
172
+
173
+
174
+ def vocfrqpr_from_voc2ypr(voc_status):
175
+ if voc_status == "No":
176
+ return gr.update(value="< 3/yr", interactive=False)
177
+ else:
178
+ return gr.update(value=None, interactive=True)
179
+
180
+
181
+ def apply_grouped_preset(selected_value):
182
+ # Header row clicked β€” reset dropdown, leave all fields unchanged
183
+ if not selected_value or selected_value in HEADER_VALUES:
184
+ return [gr.update(value=None)] + [gr.update()] * 6
185
+
186
+ preset = PUBLISHED_PRESETS.get(selected_value)
187
+ if not preset:
188
+ return [gr.update()] * 7
189
+
190
+ return [
191
+ gr.update(), # leave dropdown showing selection
192
+ gr.update(value=preset["DONORF"]),
193
+ gr.update(value=preset["CONDGRPF"]),
194
+ gr.update(value=preset["CONDGRP_FINAL"]),
195
+ gr.update(value=preset["ATGF"]),
196
+ gr.update(value=preset["GVHD_FINAL"]),
197
+ gr.update(value=preset["HLA_FINAL"]),
198
+ ]
199
+
200
+
201
+ # ---------------------------------------------------------------------------
202
+ # Component factory
203
+ # ---------------------------------------------------------------------------
204
+
205
+ def make_component(name: str):
206
+ if name == "AGE":
207
+ return gr.Number(label="Age at transplant (years)", minimum=0, maximum=120)
208
+ elif name == "AGEGPFF":
209
+ return gr.Textbox(label="Age group (Auto-filled)", interactive=False)
210
+ elif name == "NACS2YR":
211
+ return gr.Number(
212
+ label="Number of Acute Chest Syndromes within 2 years pre-HCT",
213
+ minimum=0,
214
+ )
215
+ elif name == "SEX":
216
+ return gr.Dropdown(SEX_CHOICES, label="Sex")
217
+ elif name == "KPS":
218
+ return gr.Dropdown(KPS_CHOICES, label="Karnofsky/Lansky Performance Score at HCT")
219
+ elif name == "DONORF":
220
+ return gr.Dropdown(DONORF_CHOICES, label="Donor type")
221
+ elif name == "GRAFTYPE":
222
+ return gr.Dropdown(GRAFTYPE_CHOICES, label="Graft type")
223
+ elif name == "CONDGRPF":
224
+ return gr.Dropdown(CONDGRPF_CHOICES, label="Conditioning intensity")
225
+ elif name == "CONDGRP_FINAL":
226
+ return gr.Dropdown(CONDGRP_FINAL_CHOICES, label="Conditioning Regimen")
227
+ elif name == "ATGF":
228
+ return gr.Dropdown(ATGF_CHOICES, label="Serotherapy")
229
+ elif name == "GVHD_FINAL":
230
+ return gr.Dropdown(GVHD_FINAL_CHOICES, label="GVHD Prophylaxis")
231
+ elif name == "HLA_FINAL":
232
+ return gr.Dropdown(HLA_FINAL_CHOICES, label="Donor-Recipient HLA Matching")
233
+ elif name == "RCMVPR":
234
+ return gr.Dropdown(RCMVPR_CHOICES, label="Recipient CMV serostatus")
235
+ elif name == "EXCHTFPR":
236
+ return gr.Dropdown(EXCHTFPR_CHOICES, label="Exchange transfusion required?")
237
+ elif name == "VOC2YPR":
238
+ return gr.Dropdown(
239
+ VOC2YPR_CHOICES,
240
+ label="VOC requiring hospitalization within 2 years pre-HCT?",
241
+ )
242
+ elif name == "VOCFRQPR":
243
+ return gr.Dropdown(VOCFRQPR_CHOICES, label="Frequency of VOC hospitalizations")
244
+ elif name == "SCATXRSN":
245
+ return gr.Dropdown(SCATXRSN_CHOICES, label="Reason for Transplant")
246
+ else:
247
+ return gr.Textbox(label=name)
248
+
249
+
250
+ # ---------------------------------------------------------------------------
251
+ # Prediction callback
252
+ # ---------------------------------------------------------------------------
253
+
254
+ def predict_gradio(*values):
255
+ try:
256
+ user_vals = {f: v for f, v in zip(ALL_FEATURES, values)}
257
+
258
+ missing = []
259
+ for f, v in user_vals.items():
260
+ if v is None or v == "" or (isinstance(v, float) and pd.isna(v)):
261
+ missing.append(f)
262
+ if missing:
263
+ raise ValueError(
264
+ f"Please fill in all fields before predicting.\nMissing: {', '.join(missing)}"
265
+ )
266
+
267
+ calibrated, uncalibrated = predict_with_comparison(user_vals)
268
+ calibrated_probs, calibrated_intervals = calibrated
269
+
270
+ rows = []
271
+ for outcome in REPORTING_OUTCOMES:
272
+ desc = OUTCOME_DESCRIPTIONS[outcome]
273
+ calib_prob = calibrated_probs[outcome]
274
+ ci_low_c, ci_high_c = calibrated_intervals[outcome]
275
+ rows.append({
276
+ "Outcome": desc,
277
+ "Probability": f"{calib_prob * 100:.1f}%",
278
+ "95% CI": f"[{ci_low_c * 100:.1f}% - {ci_high_c * 100:.1f}%]",
279
+ })
280
+ df = pd.DataFrame(rows)
281
+
282
+ shap_plots = create_all_shap_plots(user_vals, max_display=10)
283
+ pie_charts = create_all_pie_charts(calibrated_probs)
284
+
285
+ return (
286
+ df,
287
+ pie_charts["DEAD"],
288
+ pie_charts["GF"],
289
+ pie_charts["AGVHD"],
290
+ pie_charts["CGVHD"],
291
+ pie_charts["VOCPSHI"],
292
+ pie_charts["STROKEHI"],
293
+ shap_plots["DEAD"],
294
+ shap_plots["GF"],
295
+ shap_plots["AGVHD"],
296
+ shap_plots["CGVHD"],
297
+ shap_plots["VOCPSHI"],
298
+ shap_plots["EFS"],
299
+ shap_plots["STROKEHI"],
300
+ shap_plots["OS"],
301
+ )
302
+
303
+ except Exception as e:
304
+ tb = traceback.format_exc()
305
+ print("=" * 60)
306
+ print("ERROR IN predict_gradio:")
307
+ print(tb)
308
+ print("=" * 60)
309
+ raise gr.Error(f"{type(e).__name__}: {str(e)}\n\nSee terminal for full traceback.")
310
+
311
+
312
+ # ---------------------------------------------------------------------------
313
+ # CSS
314
+ # ---------------------------------------------------------------------------
315
+
316
+ custom_css = """
317
+ .predict-button {
318
+ background: linear-gradient(to right, #ff6b35, #ff8c42) !important;
319
+ border: none !important;
320
+ color: white !important;
321
+ font-weight: bold !important;
322
+ font-size: 16px !important;
323
+ padding: 12px !important;
324
+ }
325
+ .predict-button:hover {
326
+ background: linear-gradient(to right, #ff5722, #ff7b29) !important;
327
+ }
328
+ """
329
+
330
+ # ---------------------------------------------------------------------------
331
+ # Gradio UI
332
+ # ---------------------------------------------------------------------------
333
+
334
+ with gr.Blocks(title="HCT Outcome Prediction Model") as demo:
335
+ gr.Markdown(
336
+ """
337
+ # HCT Outcome Prediction Model
338
+
339
+ Enter patient, transplant, and disease characteristics to predict outcomes.
340
+ """
341
+ )
342
+
343
+ inputs_dict = {}
344
+
345
+ with gr.Row():
346
+ # ── Patient Characteristics ──────────────────────────────────────
347
+ with gr.Column(scale=1):
348
+ gr.Markdown("### Patient Characteristics")
349
+ for f in PATIENT_FEATURES:
350
+ inputs_dict[f] = make_component(f)
351
+
352
+ # ── Transplant Characteristics ───────────────────────────────────
353
+ with gr.Column(scale=1):
354
+ gr.Markdown("### Transplant Characteristics")
355
+
356
+ grouped_regimen_dropdown = gr.Dropdown(
357
+ choices=GROUPED_REGIMEN_CHOICES,
358
+ value=None,
359
+ label="Published conditioning regimen",
360
+ info="Auto-fills Donor Type, Conditioning Intensity, Conditioning Regimen, "
361
+ "Serotherapy and GVHD Prophylaxis",
362
+ )
363
+
364
+ donorf_comp = inputs_dict["DONORF"] = make_component("DONORF")
365
+ inputs_dict["GRAFTYPE"] = make_component("GRAFTYPE")
366
+ condgrpf = inputs_dict["CONDGRPF"] = make_component("CONDGRPF")
367
+ condgrp_final = inputs_dict["CONDGRP_FINAL"] = make_component("CONDGRP_FINAL")
368
+ atgf = inputs_dict["ATGF"] = make_component("ATGF")
369
+ gvhd_final = inputs_dict["GVHD_FINAL"] = make_component("GVHD_FINAL")
370
+ hla_final = inputs_dict["HLA_FINAL"] = make_component("HLA_FINAL")
371
+
372
+ # ── Disease Characteristics ──────────────────────────────────────
373
+ with gr.Column(scale=1):
374
+ gr.Markdown("### Disease Characteristics")
375
+ for f in DISEASE_FEATURES:
376
+ inputs_dict[f] = make_component(f)
377
+
378
+ # ── Reactive callbacks ───────────────────────────────────────────────
379
+ inputs_dict["AGE"].change(
380
+ fn=get_age_group,
381
+ inputs=inputs_dict["AGE"],
382
+ outputs=inputs_dict["AGEGPFF"],
383
+ )
384
+
385
+ inputs_dict["VOC2YPR"].change(
386
+ fn=vocfrqpr_from_voc2ypr,
387
+ inputs=inputs_dict["VOC2YPR"],
388
+ outputs=inputs_dict["VOCFRQPR"],
389
+ )
390
+
391
+ # outputs[0] is the dropdown itself so clicking a header resets it to None
392
+ grouped_regimen_dropdown.change(
393
+ fn=apply_grouped_preset,
394
+ inputs=grouped_regimen_dropdown,
395
+ outputs=[
396
+ grouped_regimen_dropdown,
397
+ donorf_comp, condgrpf, condgrp_final, atgf, gvhd_final, hla_final,
398
+ ],
399
+ )
400
+
401
+ inputs_list = [inputs_dict[f] for f in ALL_FEATURES]
402
+
403
+ btn = gr.Button("Predict", elem_classes="predict-button", size="lg")
404
+
405
+ gr.Markdown("---")
406
+ gr.Markdown("## Prediction Results")
407
+ gr.Markdown("### Predicted Outcomes")
408
+
409
+ with gr.Column():
410
+ output_table = gr.Dataframe(
411
+ headers=["Outcome", "Probability", "95% CI"],
412
+ label="",
413
+ row_count=(len(REPORTING_OUTCOMES), "dynamic"),
414
+ col_count=(3, "fixed"),
415
+ )
416
+
417
+ gr.Markdown("---")
418
+ gr.Markdown("## Pie Charts")
419
+
420
+ with gr.Row():
421
+ with gr.Column():
422
+ pie_dead = gr.Plot(label="Death")
423
+ with gr.Column():
424
+ pie_gf = gr.Plot(label="Graft Failure")
425
+ with gr.Column():
426
+ pie_agvhd = gr.Plot(label="Acute Graft-versus-Host Disease")
427
+
428
+ with gr.Row():
429
+ with gr.Column():
430
+ pie_cgvhd = gr.Plot(label="Chronic Graft-versus-Host Disease")
431
+ with gr.Column():
432
+ pie_vocpshi = gr.Plot(label="Vaso-Occlusive Crisis Post-HCT")
433
+ with gr.Column():
434
+ pie_stroke = gr.Plot(label="Stroke Post-HCT")
435
+
436
+ gr.Markdown("---")
437
+ gr.Markdown("## SHAP - Feature Importance")
438
+
439
+ with gr.Row():
440
+ with gr.Column():
441
+ shap_dead = gr.Plot(label="Death")
442
+ with gr.Column():
443
+ shap_gf = gr.Plot(label="Graft Failure")
444
+ with gr.Column():
445
+ shap_agvhd = gr.Plot(label="Acute Graft-versus-Host Disease")
446
+ with gr.Column():
447
+ shap_cgvhd = gr.Plot(label="Chronic Graft-versus-Host Disease")
448
+
449
+ with gr.Row():
450
+ with gr.Column():
451
+ shap_vocpshi = gr.Plot(label="Vaso-Occlusive Crisis Post-HCT")
452
+ with gr.Column():
453
+ shap_efs = gr.Plot(label="Event-Free Survival")
454
+ with gr.Column():
455
+ shap_stroke = gr.Plot(label="Stroke Post-HCT")
456
+ with gr.Column():
457
+ shap_os = gr.Plot(label="Overall Survival")
458
+
459
+ btn.click(
460
+ fn=predict_gradio,
461
+ inputs=inputs_list,
462
+ outputs=[
463
+ output_table,
464
+ pie_dead, pie_gf, pie_agvhd, pie_cgvhd, pie_vocpshi, pie_stroke,
465
+ shap_dead, shap_gf, shap_agvhd, shap_cgvhd,
466
+ shap_vocpshi, shap_efs, shap_stroke, shap_os,
467
+ ],
468
+ )
469
+
470
+
471
+ if __name__ == "__main__":
472
+ demo.launch(ssr_mode=False, css=custom_css)