bjornsing commited on
Commit
02ad25e
1 Parent(s): 4a5ddda
app.py CHANGED
@@ -1,15 +1,28 @@
1
  import os
2
  import wfdb
 
3
  import numpy as np
4
  import gradio as gr
5
  from models.inception import *
 
6
 
7
 
8
- def load_data():
9
- cwd = os.getcwd()
10
- sample_data = f"{cwd}/sample_data/ath_001"
11
- ecg = wfdb.rdsamp(sample_data)
12
- return np.asarray(ecg)
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def load_model(sample_frequency,recording_time, num_leads):
15
  cwd = os.getcwd()
@@ -19,14 +32,51 @@ def load_model(sample_frequency,recording_time, num_leads):
19
  return model
20
 
21
 
22
- def run(ecg):
23
  SAMPLE_FREQUENCY = 100
24
  TIME = 10
25
  NUM_LEADS = 1
26
- data = load_data()
 
 
 
 
 
 
27
  model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)
28
- predicion = model.predict(data)
29
- return predicion
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
- iface = gr.Interface(fn=run, inputs="text", outputs="text")
32
- iface.launch()
 
1
  import os
2
  import wfdb
3
+ import shutil
4
  import numpy as np
5
  import gradio as gr
6
  from models.inception import *
7
+ from scipy.signal import resample
8
 
9
 
10
+ def load_data(sample_data):
11
+ ecg, meta_data = wfdb.rdsamp(sample_data)
12
+ lead_I = ecg[:,0]
13
+ sample_frequency = meta_data["fs"]
14
+ return lead_I, sample_frequency
15
+
16
+ def preprocess_ecg(ecg,fs):
17
+ if fs != 100:
18
+ ecg = resample(ecg, int(len(ecg)*(100/fs)))
19
+ else:
20
+ pass
21
+ if len(ecg) > 1000:
22
+ ecg = ecg[:1000]
23
+ else:
24
+ pass
25
+ return ecg
26
 
27
  def load_model(sample_frequency,recording_time, num_leads):
28
  cwd = os.getcwd()
 
32
  return model
33
 
34
 
35
+ def run(header_file, data_file):
36
  SAMPLE_FREQUENCY = 100
37
  TIME = 10
38
  NUM_LEADS = 1
39
+ demo_dir = f"{CWD}/sample_data"
40
+ _, hdr_basename = os.path.split(header_file.name)
41
+ _, data_basename = os.path.split(data_file.name)
42
+ shutil.copyfile(data_file.name, f"{demo_dir}/{data_basename}")
43
+ shutil.copyfile(header_file.name, f"{demo_dir}/{hdr_basename}")
44
+ data, fs = load_data(f"{demo_dir}/{hdr_basename.split('.')[0]}")
45
+ ecg = preprocess_ecg(data,fs)
46
  model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)
47
+ predicion = model.predict(np.expand_dims(ecg,0)).ravel()[0]
48
+ return str(round(predicion,1))
49
+
50
+ # Give credit to https://huggingface.co/spaces/Tej3/ECG_Classification/blob/main/app.py for interface
51
+
52
+ CWD = os.getcwd()
53
+
54
+ with gr.Blocks() as demo:
55
+ #with gr.Row():
56
+ # pred_type = gr.Radio(['Age', 'Gender'], label= "Select Model")
57
+ with gr.Row():
58
+ with gr.Column(scale=1):
59
+ header_file = gr.File(label = "header_file", file_types=[".hea"],)
60
+ data_file = gr.File(label = "data_file", file_types=[".dat"])
61
+ with gr.Column(scale=1):
62
+ output_age = gr.Textbox(label = "Predicted age")
63
+ #output_gender = gr.Textbox(label = "Predicted gender")
64
+ #with gr.Row():
65
+ # ecg_graph = gr.Plot(label = "ECG Signal Visualisation")
66
+ with gr.Row():
67
+ predict_btn = gr.Button("Predict")
68
+ predict_btn.click(fn= run, inputs = [#pred_type,
69
+ header_file, data_file], outputs=[output_age])
70
+ with gr.Row():
71
+ gr.Examples(examples=[[f"{CWD}/sample_data/ath_001.hea", f"{CWD}/sample_data/ath_001.dat"],\
72
+ # [f"{CWD}/demo_data/test/00008_lr.hea", f"{CWD}/demo_data/test/00008_lr.dat", "sinusrhythmus linkstyp qrs(t) abnormal inferiorer infarkt alter unbest."], \
73
+ # [f"{CWD}/demo_data/test/00045_lr.hea", f"{CWD}/demo_data/test/00045_lr.dat", "sinusrhythmus unvollstÄndiger rechtsschenkelblock sonst normales ekg"],\
74
+ # [f"{CWD}/demo_data/test/00257_lr.hea", f"{CWD}/demo_data/test/00257_lr.dat", "premature atrial contraction(s). sinus rhythm. left atrial enlargement. qs complexes in v2. st segments are slightly elevated in v2,3. st segments are depressed in i, avl. t waves are low or flat in i, v5,6 and inverted in avl. consistent with ischaemic h"],\
75
+ ],
76
+ inputs = [header_file, data_file])
77
+ #
78
+ if __name__ == "__main__":
79
+ demo.launch()
80
 
81
+ #iface = gr.Interface(fn=run, inputs="text", outputs="text")
82
+ #iface.launch()
flagged/log.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ ecg,output,flag,username,timestamp
2
+ 1,,,,2024-01-13 13:13:14.648011
3
+ 1,,,,2024-01-13 13:13:16.151475
models/__pycache__/inception.cpython-38.pyc ADDED
Binary file (2.59 kB). View file
 
models/__pycache__/inception.cpython-39.pyc ADDED
Binary file (2.58 kB). View file
 
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio==3.25.0
2
+ numpy==1.24.2
3
+ tqdm==4.64.1
4
+ wfdb==4.1.0
5
+ scipy==1.7.3
6
+ tensorflow=2.8.0
sample_data/ath_001_1fwuysgx07e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat ADDED
Binary file (120 kB). View file
 
sample_data/ath_001_2ztxkdc11326385fdd37d229683c95ce9ac5e9768817f96f.hea ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ath_001 12 500 5000
2
+ ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
3
+ ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
4
+ ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
5
+ ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
6
+ ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
7
+ ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
8
+ ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
9
+ ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
10
+ ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
11
+ ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
12
+ ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
13
+ ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
14
+ #SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
15
+ #C: Sinus arrhythmia, Normal ECG
16
+
sample_data/ath_001_ewabg1uc1326385fdd37d229683c95ce9ac5e9768817f96f.hea ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ath_001 12 500 5000
2
+ ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
3
+ ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
4
+ ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
5
+ ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
6
+ ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
7
+ ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
8
+ ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
9
+ ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
10
+ ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
11
+ ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
12
+ ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
13
+ ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
14
+ #SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
15
+ #C: Sinus arrhythmia, Normal ECG
16
+
sample_data/ath_001_f17hino207e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat ADDED
Binary file (120 kB). View file
 
sample_data/ath_001_rh_j77511326385fdd37d229683c95ce9ac5e9768817f96f.hea ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ath_001 12 500 5000
2
+ ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
3
+ ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
4
+ ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
5
+ ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
6
+ ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
7
+ ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
8
+ ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
9
+ ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
10
+ ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
11
+ ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
12
+ ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
13
+ ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
14
+ #SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
15
+ #C: Sinus arrhythmia, Normal ECG
16
+
sample_data/ath_001_zxgouf9007e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat ADDED
Binary file (120 kB). View file
 
test.ipynb ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 41,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "import wfdb\n",
11
+ "import numpy as np\n",
12
+ "import gradio as gr\n",
13
+ "from models.inception import *\n",
14
+ "from scipy.signal import resample\n",
15
+ "\n",
16
+ "\n",
17
+ "def load_data():\n",
18
+ " cwd = os.getcwd()\n",
19
+ " sample_data = f\"{cwd}/sample_data/ath_001\"\n",
20
+ " ecg, meta_data = wfdb.rdsamp(sample_data)\n",
21
+ " lead_I = ecg[:,0]\n",
22
+ " sample_frequency = meta_data[\"fs\"]\n",
23
+ " return lead_I, sample_frequency\n",
24
+ "\n",
25
+ "def preprocess_ecg(ecg,fs):\n",
26
+ " if fs != 500:\n",
27
+ " ecg = resample(ecg, int(len(ecg)*(500/fs)))\n",
28
+ " else:\n",
29
+ " pass\n",
30
+ " if len(ecg) > 5000:\n",
31
+ " ecg = ecg[:5000]\n",
32
+ " else:\n",
33
+ " pass\n",
34
+ " return ecg\n",
35
+ "\n",
36
+ "def load_model(sample_frequency,recording_time, num_leads):\n",
37
+ " cwd = os.getcwd()\n",
38
+ " weights = f\"{cwd}/models/weights/model_weights_leadI.h5\"\n",
39
+ " model = build_model((sample_frequency * recording_time, num_leads), 1)\n",
40
+ " model.load_weights(weights)\n",
41
+ " return model\n",
42
+ "\n",
43
+ "\n",
44
+ "def run(ecg):\n",
45
+ " SAMPLE_FREQUENCY = 100\n",
46
+ " TIME = 10\n",
47
+ " NUM_LEADS = 1\n",
48
+ " data, fs = load_data()\n",
49
+ " model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)\n",
50
+ " predicion = model.predict(data)\n",
51
+ " return str(predicion)"
52
+ ]
53
+ },
54
+ {
55
+ "cell_type": "code",
56
+ "execution_count": 42,
57
+ "metadata": {},
58
+ "outputs": [],
59
+ "source": [
60
+ "data, fs = load_data()"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "code",
65
+ "execution_count": 43,
66
+ "metadata": {},
67
+ "outputs": [
68
+ {
69
+ "data": {
70
+ "text/plain": [
71
+ "(5000,)"
72
+ ]
73
+ },
74
+ "execution_count": 43,
75
+ "metadata": {},
76
+ "output_type": "execute_result"
77
+ }
78
+ ],
79
+ "source": [
80
+ "data.shape"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": 49,
86
+ "metadata": {},
87
+ "outputs": [],
88
+ "source": [
89
+ "out = preprocess_ecg(data,250)"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "code",
94
+ "execution_count": 50,
95
+ "metadata": {},
96
+ "outputs": [
97
+ {
98
+ "data": {
99
+ "text/plain": [
100
+ "(5000,)"
101
+ ]
102
+ },
103
+ "execution_count": 50,
104
+ "metadata": {},
105
+ "output_type": "execute_result"
106
+ }
107
+ ],
108
+ "source": [
109
+ "out[:5000].shape"
110
+ ]
111
+ },
112
+ {
113
+ "cell_type": "code",
114
+ "execution_count": 39,
115
+ "metadata": {},
116
+ "outputs": [
117
+ {
118
+ "data": {
119
+ "text/plain": [
120
+ "0.5"
121
+ ]
122
+ },
123
+ "execution_count": 39,
124
+ "metadata": {},
125
+ "output_type": "execute_result"
126
+ }
127
+ ],
128
+ "source": [
129
+ "500/1000"
130
+ ]
131
+ },
132
+ {
133
+ "cell_type": "code",
134
+ "execution_count": 30,
135
+ "metadata": {},
136
+ "outputs": [],
137
+ "source": [
138
+ "upsamp = preprocess_ecg(data,1000)"
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "execution_count": 31,
144
+ "metadata": {},
145
+ "outputs": [
146
+ {
147
+ "data": {
148
+ "text/plain": [
149
+ "array([0.])"
150
+ ]
151
+ },
152
+ "execution_count": 31,
153
+ "metadata": {},
154
+ "output_type": "execute_result"
155
+ }
156
+ ],
157
+ "source": [
158
+ "upsamp"
159
+ ]
160
+ },
161
+ {
162
+ "cell_type": "code",
163
+ "execution_count": null,
164
+ "metadata": {},
165
+ "outputs": [],
166
+ "source": []
167
+ }
168
+ ],
169
+ "metadata": {
170
+ "kernelspec": {
171
+ "display_name": "new_tf",
172
+ "language": "python",
173
+ "name": "python3"
174
+ },
175
+ "language_info": {
176
+ "codemirror_mode": {
177
+ "name": "ipython",
178
+ "version": 3
179
+ },
180
+ "file_extension": ".py",
181
+ "mimetype": "text/x-python",
182
+ "name": "python",
183
+ "nbconvert_exporter": "python",
184
+ "pygments_lexer": "ipython3",
185
+ "version": "3.9.12"
186
+ }
187
+ },
188
+ "nbformat": 4,
189
+ "nbformat_minor": 2
190
+ }