def test_slicing_not_touching_original(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) record_sliced = record[0:1] assert len(record) == 6 record_sliced = record[0:2] assert len(record) == 6 record_sliced = record[1:3] assert len(record) == 6 record_sliced = record[1] assert len(record) == 6
def load(self, hea_file) -> ECGRecord: base_path = os.path.splitext(hea_file)[0] def load_annotation(ann_ext): return wfdb.rdann(base_path, ann_ext) hea_file = base_path + ".hea" if not os.path.isfile(hea_file): raise FileNotFoundError(f"{hea_file} is not found") record = wfdb.rdrecord(base_path) time = Time.from_fs_samples(record.fs, record.sig_len) new_record = ECGRecord(name=record.record_name, time=time) for signal, lead_name in zip(record.p_signal.T, record.sig_name): new_record.add_signal(Signal(signal, lead_name)) ann = load_annotation("atr") ecg_annotation = ECGAnnotation([ ECGAnnotationSample(samp, symbol) for samp, symbol in zip(ann.sample, ann.symbol) ]) new_record.annotations = ecg_annotation return new_record
def load(self, ecg_file) -> ECGRecord: if not os.path.isfile(ecg_file): raise FileNotFoundError(f"{ecg_file} is not found") record = Holter(ecg_file) record.load_data() def load_ann(ann_file, annheader): filesize = os.path.getsize(ann_file) headersize = 522 + annheader.var_block_size + 4 record.beat_anns = [] with open(ann_file, 'rb') as f: f.seek(headersize - 4, os.SEEK_SET) first_sample = np.fromfile(f, dtype=np.uint32, count=1)[0] current_sample = first_sample timeout = False # was there a gap in the annotations? for beat in range(int((filesize - headersize) / 4)): # note, the beat at first_sample isn't annotated. so the first beat # in beat_anns is actually the second beat of the recording. ann = chr(np.fromfile(f, dtype=np.uint8, count=1)[0]) internal = chr(np.fromfile(f, dtype=np.uint8, count=1)[0]) toc = np.fromfile(f, dtype=np.int16, count=1)[0] current_sample += toc if ann == '!': timeout = True # there was a few minutes gap in the anns; don't # know how to line them up to rest of recording record.beat_anns.append({'ann': ann, 'internal': internal, 'toc': toc}) if not timeout: record.beat_anns[-1]['samp_num'] = current_sample ann_file = os.path.splitext(ecg_file)[0] + '.ann' ann_header = Holter(ann_file, check_valid=False, annfile=True) load_ann(ann_file, ann_header) time = Time.from_fs_samples(record.sr, len(record.lead[0].data)) record_name = os.path.split(ecg_file)[1] record_name = ".".join(record_name.split(".")[:-1]) new_record = ECGRecord(name=record_name, time=time) for leadi in record.lead: new_record.add_signal(Signal(leadi.data, str(leadi))) ecg_annotation = ECGAnnotation([ECGAnnotationSample(i["samp_num"], i["ann"]) for i in record.beat_anns]) new_record.annotations = ecg_annotation new_record.info = SubjectInfo() new_record.info.race = record.race new_record.info.sex = record.sex new_record.info.birth_date = record.birth_date new_record.info.record_date = record.record_date new_record.info.file_date = record.file_date new_record.info.start_time = record.start_time new_record.info.pm = record.pm return new_record
with zipfile.ZipFile("MIT_Noise.zip", "r") as zip_ref: zip_ref.extractall() hea_path_1 = "mit-bih-arrhythmia-database-1.0.0/mit-bih-arrhythmia-database-1.0.0/" hea_path = "mit-bih-noise-stress-test-database-1.0.0/mit-bih-noise-stress-test-database-1.0.0/bw.hea" # To load a wfdb formatted ECG record hea_path_1 = "D:/Research_Impl/Noise_Removal_Autoencoder/Dataset/mit-bih-arrhythmia-database-1.0.0/mit-bih-arrhythmia-database-1.0.0/" hea_path = "D:/Research_Impl/Noise_Removal_Autoencoder/Dataset/mit-bih-noise-stress-test-database-1.0.0 (1)/mit-bih-noise-stress-test-database-1.0.0/bw.hea" ####################################################################################################### # EXTRACTING THE NOISE SIGNALS FROM HEA ####################################################################################################### record = ECGRecord.from_wfdb(hea_path) signal_noise = record.get_lead("noise1") ####################################################################################################### # EXTRACTING THE ORIGINAL SIGNALS FROM HEA ####################################################################################################### signal_original = [] for i in range(100, 125): if i == 110 or i == 120: continue record_1 = ECGRecord.from_wfdb(hea_path_1 + str(i) + ".hea") signal_orig = record_1.get_lead("MLII") if signal_orig == None: print(i) continue signal_original.append(signal_orig)
def test_length(fs, samples): record = ECGRecord("record_100", time=Time.from_fs_samples(fs, samples)) assert len(record) == samples
def test_unique_labels(hea_path): record = ECGRecord.from_wfdb(hea_path) assert record.annotations.unique_labels == ['+', 'A', 'N', 'V']
def test_annotation(hea_path): record = ECGRecord.from_wfdb(hea_path) assert len(record.annotations) == 2274
def test_signal_name(hea_path): record = ECGRecord.from_wfdb(hea_path) assert record.lead_names == ['MLII', 'V5']
def test_signal(hea_path): record = ECGRecord.from_wfdb(hea_path) assert record.n_sig == 2
def test_from_numpy_array_inconsistent_signal_name(time, signal): with pytest.raises(ValueError): ECGRecord.from_np_array("record_100", time, signal, ["II"])
def test_from_numpy_array(time, signal): record = ECGRecord.from_np_array("record_100", time, signal, ["I", "II", "III"]) assert len(record) == len(time)
def test_from_numpy_array_bad_signal_shape(time, signal): with pytest.raises(ValueError): ECGRecord.from_np_array("record_100", time, signal, ["II"])
def test_inconsistent_signal_type(): record = ECGRecord("record_100", time=Time.from_fs_samples(360, 10)) with pytest.raises(TypeError): record.add_signal(electrocardiogram())
def test_inconsistent_signal_len(): record = ECGRecord("record_100", time=Time.from_fs_samples(360, 10)) with pytest.raises(ValueError): record.add_signal(Signal(electrocardiogram(), "MLII"))
def test_bad_time(time): with pytest.raises(TypeError): ECGRecord("record_100", time=time)
def test_p_signal_shape(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) assert np.array_equal(record.p_signal.shape, (3, 6))
def test_length(hea_path): record = ECGRecord.from_wfdb(hea_path) assert len(record) == 650000
def test_repr(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) assert record.__repr__() == f"Record 100: ['I', 'II', 'III']"
def test_record_name(hea_path): record = ECGRecord.from_wfdb(hea_path) assert record.record_name == "100"
def test_get_lead(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) assert np.array_equal(record.get_lead("I")[:], [1, 2, 3, 4, 5, 6]) assert np.array_equal(record.get_lead("II")[:], [5, 6, 7, 8, 9, 10]) assert np.array_equal(record.get_lead("III")[:], [10, 20, 30, 40, 50, 60])
def test_signal_content(hea_path, lead_name, signal): record = ECGRecord.from_wfdb(hea_path) assert record.get_lead(lead_name)[:10] == signal
def test_duration(fs, samples): record = ECGRecord("record_100", time=Time.from_fs_samples(fs, samples)) assert record.duration == (samples - 1) / fs
def test_select_annotation(hea_path): record = ECGRecord.from_wfdb(hea_path) assert len(record.annotations.select_label("N")) == 2239
def test_get_lead_notfound(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) assert record.get_lead("MLII") is None
def test_file_notfound(hea_path): with pytest.raises(FileNotFoundError): ECGRecord.from_wfdb(hea_path)
def test_slicing(time, signal): record = ECGRecord.from_np_array("100", time, signal, ["I", "II", "III"]) record_sliced = record[0:1] assert record_sliced.time == time[0:1] for i, s in enumerate(signal): assert record_sliced._signals[i] == s[0:1]