|
a |
|
b/tester_GUDB.py |
|
|
1 |
import numpy as np |
|
|
2 |
import pandas as pd |
|
|
3 |
import _tester_utils |
|
|
4 |
import pathlib |
|
|
5 |
from ecgdetectors import Detectors |
|
|
6 |
|
|
|
7 |
current_dir = pathlib.Path(__file__).resolve() |
|
|
8 |
data_dir = str(pathlib.Path(current_dir).parents[1]/'dataset_716'/'experiment_data') |
|
|
9 |
code_dir = str(pathlib.Path(current_dir).parents[1]/'dataset_716'/'example_code') |
|
|
10 |
|
|
|
11 |
import sys |
|
|
12 |
sys.path.insert(0, code_dir) |
|
|
13 |
from ecg_gla_database import Ecg |
|
|
14 |
|
|
|
15 |
|
|
|
16 |
class GUDB_test: |
|
|
17 |
""" |
|
|
18 |
This class benchmarks detectors against the GU database. |
|
|
19 |
You need to download both the GU database from: http://researchdata.gla.ac.uk/716/ |
|
|
20 |
and needs to be placed below this directory: "../dataset_716". |
|
|
21 |
""" |
|
|
22 |
|
|
|
23 |
def single_classifier_test(self, detector, tolerance=0, config="chest_strap"): |
|
|
24 |
|
|
|
25 |
max_delay_in_samples = 250 / 3 |
|
|
26 |
|
|
|
27 |
total_subjects = Ecg.total_subjects |
|
|
28 |
|
|
|
29 |
results = np.zeros((total_subjects, (4*len(Ecg.experiments))+1), dtype=int) |
|
|
30 |
|
|
|
31 |
for subject_number in range(0, total_subjects): |
|
|
32 |
progress = int(subject_number/float(total_subjects)*100.0) |
|
|
33 |
print("GUDB "+config+" progress: %i%%" % progress) |
|
|
34 |
|
|
|
35 |
results[subject_number, 0] = subject_number |
|
|
36 |
exp_counter = 1 |
|
|
37 |
for experiment in Ecg.experiments: |
|
|
38 |
|
|
|
39 |
ecg_class = Ecg(data_dir, subject_number, experiment) |
|
|
40 |
|
|
|
41 |
anno_exists = False |
|
|
42 |
if config=="chest_strap" and ecg_class.anno_cs_exists: |
|
|
43 |
unfiltered_ecg = ecg_class.cs_V2_V1 |
|
|
44 |
anno = ecg_class.anno_cs |
|
|
45 |
anno_exists = True |
|
|
46 |
elif config=="loose_cables" and ecg_class.anno_cables_exists: |
|
|
47 |
unfiltered_ecg = ecg_class.einthoven_II |
|
|
48 |
anno = ecg_class.anno_cables |
|
|
49 |
anno_exists = True |
|
|
50 |
elif config!="chest_strap" and config!="loose_cables": |
|
|
51 |
raise RuntimeError("Config argument must be chest_strap or loose_cables!") |
|
|
52 |
return results |
|
|
53 |
|
|
|
54 |
if anno_exists: |
|
|
55 |
|
|
|
56 |
r_peaks = detector(unfiltered_ecg) |
|
|
57 |
|
|
|
58 |
delay = _tester_utils.calcMedianDelay(r_peaks, unfiltered_ecg, max_delay_in_samples) |
|
|
59 |
print("delay = ",delay) |
|
|
60 |
|
|
|
61 |
# there must be a delay in all cases so anything below is a bad sign |
|
|
62 |
if delay > 1: |
|
|
63 |
|
|
|
64 |
TP, FP, FN = _tester_utils.evaluate_detector(r_peaks, anno, delay, tol=tolerance) |
|
|
65 |
TN = len(unfiltered_ecg)-(TP+FP+FN) |
|
|
66 |
|
|
|
67 |
results[subject_number, exp_counter] = TP |
|
|
68 |
results[subject_number, exp_counter+1] = FP |
|
|
69 |
results[subject_number, exp_counter+2] = FN |
|
|
70 |
results[subject_number, exp_counter+3] = TN |
|
|
71 |
|
|
|
72 |
exp_counter = exp_counter+4 |
|
|
73 |
|
|
|
74 |
return results |
|
|
75 |
|
|
|
76 |
|
|
|
77 |
def classifer_test_all(self, tolerance=0, config="chest_strap"): |
|
|
78 |
|
|
|
79 |
det_names = ['two_average', 'matched_filter', 'swt', 'engzee', 'christov', 'hamilton', 'pan_tompkins'] |
|
|
80 |
output_names = ['TP', 'FP', 'FN', 'TN'] |
|
|
81 |
|
|
|
82 |
total_results = np.zeros((Ecg.total_subjects, 4*len(Ecg.experiments)*len(det_names)), dtype=int) |
|
|
83 |
|
|
|
84 |
counter = 0 |
|
|
85 |
for det_name in det_names: |
|
|
86 |
|
|
|
87 |
print('\n'+config+" "+det_name+":") |
|
|
88 |
|
|
|
89 |
result = self.single_classifier_test(_tester_utils.det_from_name(det_name, 250), tolerance=tolerance, config=config) |
|
|
90 |
result = result[:, 1:] |
|
|
91 |
|
|
|
92 |
total_results[:, counter:counter+(4*len(Ecg.experiments))] = result |
|
|
93 |
|
|
|
94 |
counter = counter+(4*len(Ecg.experiments)) |
|
|
95 |
|
|
|
96 |
index_labels = np.arange(Ecg.total_subjects) |
|
|
97 |
col_labels = [] |
|
|
98 |
|
|
|
99 |
for det_name in det_names: |
|
|
100 |
for experiment_name in Ecg.experiments: |
|
|
101 |
for output_name in output_names: |
|
|
102 |
label = det_name+" "+experiment_name+" "+output_name |
|
|
103 |
col_labels.append(label) |
|
|
104 |
|
|
|
105 |
total_results_pd = pd.DataFrame(total_results, index_labels, col_labels, dtype=int) |
|
|
106 |
total_results_pd.to_csv('results_GUDB_'+config+'.csv', sep=',') |
|
|
107 |
|
|
|
108 |
return total_results_pd |