mgbam commited on
Commit
15947fa
·
verified ·
1 Parent(s): 4aa0d01

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -98
app.py DELETED
@@ -1,98 +0,0 @@
1
- import io
2
- import json
3
- from typing import Any, Dict, List
4
-
5
- import gradio as gr
6
- import matplotlib.pyplot as plt
7
-
8
- from app.ml.gating import gate_signal
9
- from app.ml.inference import infer_ecg, load_model
10
- from app.rules.engine import evaluate_ecg_rules
11
-
12
-
13
- # Preload model (uses ./checkpoints/ecg_classifier.pt if present)
14
- load_model()
15
-
16
-
17
- def parse_signal(text: str | List[float]) -> List[float]:
18
- if isinstance(text, list):
19
- return [float(x) for x in text]
20
- try:
21
- return [float(x) for x in json.loads(text)]
22
- except Exception:
23
- raise gr.Error("Provide ECG samples as a JSON list, e.g., [0.1, 0.2, 0.3]")
24
-
25
-
26
- def run_infer(signal_text: str) -> Dict[str, Any]:
27
- sig = parse_signal(signal_text)
28
- gated, gating_meta = gate_signal(sig, return_windows=True)
29
- model_output: Dict[str, Any] = infer_ecg(
30
- gated,
31
- original_len=len(sig),
32
- gating_meta=gating_meta,
33
- )
34
- patient_context = {"patient_id": "demo"}
35
- rules_result = evaluate_ecg_rules(patient_context, model_output)
36
- explanations = [*(model_output.get("gating", {}).get("explanations", []) if isinstance(model_output.get("gating"), dict) else []),
37
- *rules_result.get("explanations", [])]
38
- return {
39
- "label": model_output.get("label"),
40
- "score": round(float(model_output.get("score", 0.0)), 3),
41
- "hr": model_output.get("hr"),
42
- "alert_level": rules_result.get("alert_level", "none"),
43
- "gated_ratio": round(model_output.get("gated_ratio", 1.0), 3),
44
- "gating": gating_meta,
45
- "explanations": explanations,
46
- }
47
-
48
-
49
- def plot_gating(signal_text: str):
50
- sig = parse_signal(signal_text)
51
- gated, meta = gate_signal(sig, return_windows=True)
52
- fig, axes = plt.subplots(2, 1, figsize=(6, 4))
53
- axes[0].plot(sig, color="#0066ff", linewidth=1)
54
- axes[0].set_title("Raw signal")
55
- axes[1].plot(gated, color="#ff6600", linewidth=1)
56
- axes[1].set_title(f"Gated signal (ratio={meta['ratio']:.2f})")
57
- fig.tight_layout()
58
- buf = io.BytesIO()
59
- fig.savefig(buf, format="png", dpi=120)
60
- plt.close(fig)
61
- buf.seek(0)
62
- return buf
63
-
64
-
65
- demo_normal = [0.05 for _ in range(256)]
66
- demo_afib = [0.3 for _ in range(256)]
67
-
68
- with gr.Blocks(title="Sundew ECG Demo") as demo:
69
- gr.Markdown("### Neurosymbolic ECG • Sundew Gating + Rules")
70
- with gr.Tabs():
71
- with gr.Tab("Upload/Infer"):
72
- inp = gr.Textbox(
73
- label="ECG samples (JSON list)",
74
- value=json.dumps(demo_afib[:128]),
75
- )
76
- out = gr.JSON(label="Inference")
77
- btn = gr.Button("Run")
78
- btn.click(run_infer, inputs=inp, outputs=out)
79
- with gr.Tab("Gating Preview"):
80
- inp2 = gr.Textbox(
81
- label="ECG samples (JSON list)",
82
- value=json.dumps(demo_afib[:128]),
83
- )
84
- img = gr.Image(type="filepath", label="Raw vs Gated")
85
- btn2 = gr.Button("Show gating")
86
- btn2.click(plot_gating, inputs=inp2, outputs=img)
87
- with gr.Tab("Demos"):
88
- out_demo = gr.JSON()
89
- btn_n = gr.Button("Normal")
90
- btn_a = gr.Button("Arrhythmia-ish")
91
- hidden_n = gr.Textbox(value=json.dumps(demo_normal), visible=False)
92
- hidden_a = gr.Textbox(value=json.dumps(demo_afib), visible=False)
93
- btn_n.click(run_infer, inputs=hidden_n, outputs=out_demo)
94
- btn_a.click(run_infer, inputs=hidden_a, outputs=out_demo)
95
-
96
-
97
- if __name__ == "__main__":
98
- demo.launch()