def test_anonymize(self): header = highlevel.make_header(technician='tech', recording_additional='radd', patientname='name', patient_additional='padd', patientcode='42', equipment='eeg', admincode='420', gender='Male', birthdate='05.09.1980') annotations = [[0.01, -1, 'begin'], [0.5, -1, 'middle'], [10, -1, 'end']] header['annotations'] = annotations signal_headers = highlevel.make_signal_headers( ['ch' + str(i) for i in range(3)]) signals = np.random.rand(3, 256 * 300) * 200 #5 minutes of eeg highlevel.write_edf(self.personalized, signals, signal_headers, header) highlevel.anonymize_edf(self.personalized, new_file=self.anonymized, to_remove=[ 'patientname', 'birthdate', 'admincode', 'patientcode', 'technician' ], new_values=['x', '', 'xx', 'xxx', 'xxxx'], verify=True, verbose=True) new_header = highlevel.read_edf_header(self.anonymized) self.assertEqual(new_header['birthdate'], '') self.assertEqual(new_header['patientname'], 'x') self.assertEqual(new_header['admincode'], 'xx') self.assertEqual(new_header['patientcode'], 'xxx') self.assertEqual(new_header['technician'], 'xxxx') highlevel.anonymize_edf(self.personalized, to_remove=[ 'patientname', 'birthdate', 'admincode', 'patientcode', 'technician' ], new_values=['x', '', 'xx', 'xxx', 'xxxx'], verify=True) new_header = highlevel.read_edf_header(self.personalized[:-4] + '_anonymized.edf') self.assertEqual(new_header['birthdate'], '') self.assertEqual(new_header['patientname'], 'x') self.assertEqual(new_header['admincode'], 'xx') self.assertEqual(new_header['patientcode'], 'xxx') self.assertEqual(new_header['technician'], 'xxxx') with self.assertRaises(AssertionError): highlevel.anonymize_edf(self.personalized, new_file=self.anonymized, to_remove=[ 'patientname', 'birthdate', 'admincode', 'patientcode', 'technician' ], new_values=['x', '', 'xx', 'xxx'], verify=True)
def test_drop_channel(self): signal_headers = highlevel.make_signal_headers( ['ch' + str(i) for i in range(5)]) signals = np.random.rand(5, 256 * 300) * 200 #5 minutes of eeg highlevel.write_edf(self.drop_from, signals, signal_headers) dropped = highlevel.drop_channels(self.drop_from, to_keep=['ch1', 'ch2'], verbose=True) signals2, signal_headers, header = highlevel.read_edf(dropped) np.testing.assert_allclose(signals[1:3, :], signals2, atol=0.01) highlevel.drop_channels(self.drop_from, self.drop_from[:-4] + '2.edf', to_drop=['ch0', 'ch1', 'ch2']) signals2, signal_headers, header = highlevel.read_edf( self.drop_from[:-4] + '2.edf') np.testing.assert_allclose(signals[3:, :], signals2, atol=0.01) with self.assertRaises(AssertionError): highlevel.drop_channels(self.drop_from, to_keep=['ch1'], to_drop=['ch3'])
def extract_ecg(edf_file, copy_folder): filename = os.path.basename(edf_file) new_edf_file = os.path.join(copy_folder, filename) if os.path.exists(new_edf_file): return try: header = highlevel.read_edf_header(edf_file) except: print(f'error in file {edf_file}') return channels = header['channels'] try: channels.remove('cs_ECG') except: print(f'warning, {edf_file} has no cs_ECG') ch_names = [x for x in channels if 'ECG' in x.upper()] if len(ch_names) > 1: print( f'Warning, these are present: {ch_names}, selecting {ch_names[0]}') ch_name = ch_names[0] signals, shead, header = highlevel.read_edf(edf_file, ch_names=[ch_name], digital=True, verbose=False) shead[0]['label'] = 'ECG' assert len(signals) > 0, 'signal empty' try: highlevel.write_edf(new_edf_file, signals, shead, header, digital=True) except: shead[0]['digital_min'] = signals.min() shead[0]['digital_max'] = signals.max() highlevel.write_edf(new_edf_file, signals, shead, header, digital=True)
def test_read_write_edf(self): startdate = datetime.now() t = startdate startdate = datetime(t.year, t.month, t.day, t.hour, t.minute, t.second) header = highlevel.make_header(technician='tech', recording_additional='radd', patientname='name', patient_additional='padd', patientcode='42', equipment='eeg', admincode='420', gender='Male', startdate=startdate, birthdate='05.09.1980') annotations = [[0.01, -1, 'begin'], [0.5, -1, 'middle'], [10, -1, 'end']] header['annotations'] = annotations signal_headers1 = highlevel.make_signal_headers( ['ch' + str(i) for i in range(5)]) signals = np.random.rand(5, 256 * 300) * 200 #5 minutes of eeg success = highlevel.write_edf(self.edfplus_data_file, signals, signal_headers1, header) self.assertTrue(os.path.isfile(self.edfplus_data_file)) self.assertGreater(os.path.getsize(self.edfplus_data_file), 0) self.assertTrue(success) signals2, signal_headers2, header2 = highlevel.read_edf( self.edfplus_data_file) self.assertEqual(len(signals2), 5) self.assertEqual(len(signals2), len(signal_headers2)) for shead1, shead2 in zip(signal_headers1, signal_headers2): self.assertDictEqual(shead1, shead2) self.assertDictEqual(header, header2) np.testing.assert_allclose(signals, signals2, atol=0.01) signals = (signals * 100).astype(np.int8) success = highlevel.write_edf(self.edfplus_data_file, signals, signal_headers1, header, digital=True) self.assertTrue(os.path.isfile(self.edfplus_data_file)) self.assertGreater(os.path.getsize(self.edfplus_data_file), 0) self.assertTrue(success) signals2, signal_headers2, header2 = highlevel.read_edf( self.edfplus_data_file, digital=True) self.assertEqual(len(signals2), 5) self.assertEqual(len(signals2), len(signal_headers2)) for shead1, shead2 in zip(signal_headers1, signal_headers2): self.assertDictEqual(shead1, shead2) self.assertDictEqual(header, header2) np.testing.assert_array_equal(signals, signals2)
def test_read_write_with_annotations(self): signals, signal_headers, header = highlevel.read_edf(self.test_generator) expected = [[0.0, -1, 'Recording starts'], [600.0, -1, 'Recording ends']] self.assertEqual(header['annotations'], expected) highlevel.write_edf(self.edfplus_data_file, signals, signal_headers, header) signals2, signal_header2s, header2 = highlevel.read_edf(self.edfplus_data_file) self.assertEqual(header['annotations'], header2['annotations'])
def test_read_write_edf(self): startdate = datetime.now() t = startdate startdate = datetime(t.year,t.month,t.day,t.hour, t.minute,t.second) header = highlevel.make_header(technician='tech', recording_additional='r_add', patientname='name', patient_additional='p_add', patientcode='42', equipment='eeg', admincode='120', gender='Male', startdate=startdate,birthdate='05.09.1980') annotations = [[0.01, -1, 'begin'],[0.5, -1, 'middle'],[10, -1, 'end']] signal_headers1 = highlevel.make_signal_headers(['ch'+str(i) for i in range(5)]) for file_type in [-1,0,1,2,3]: if file_type in [0, 2]: header['annotations'] = [] else: header['annotations'] = annotations file = '{}_{}_phys.edf'.format(self.tmp_testfile, file_type) signals = np.random.rand(5, 256*300)*200 #5 minutes of eeg success = highlevel.write_edf(file, signals, signal_headers1, header, file_type=file_type) self.assertTrue(os.path.isfile(file)) self.assertGreater(os.path.getsize(file), 0) self.assertTrue(success) signals2, signal_headers2, header2 = highlevel.read_edf(file) self.assertEqual(len(signals2), 5) self.assertEqual(len(signals2), len(signal_headers2)) for shead1, shead2 in zip(signal_headers1, signal_headers2): self.assertDictEqual(shead1, shead2) np.testing.assert_allclose(signals, signals2, atol=0.01) if file_type in [-1, 1, 3]: self.assertDictEqual(header, header2) file = '{}_{}_dig.edf'.format(self.tmp_testfile, file_type) signals = (signals*100).astype(np.int8) success = highlevel.write_edf(file, signals, signal_headers1, header, digital=True) self.assertTrue(os.path.isfile(file)) self.assertGreater(os.path.getsize(file), 0) self.assertTrue(success) signals2, signal_headers2, header2 = highlevel.read_edf(file, digital=True) self.assertEqual(len(signals2), 5) self.assertEqual(len(signals2), len(signal_headers2)) np.testing.assert_array_equal(signals, signals2) for shead1, shead2 in zip(signal_headers1, signal_headers2): self.assertDictEqual(shead1, shead2) # EDF/BDF header writing does not correctly work yet if file_type in [-1, 1, 3]: self.assertDictEqual(header, header2)
def test_read_write_diff_sfreq(self): signals = [] sfreqs = [1, 64, 128, 200] sheaders = [] for sfreq in sfreqs: signals.append(np.random.randint(-2048, 2048, sfreq*60).astype(np.int32)) shead = highlevel.make_signal_header('ch{}'.format(sfreq), sample_rate=sfreq) sheaders.append(shead) highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=True) signals2, sheaders2, _ = highlevel.read_edf(self.edfplus_data_file, digital=True) for s1, s2 in zip(signals, signals2): np.testing.assert_allclose(s1, s2)
def test_blocksize_auto(self): """ test that the blocksize parameter works as intended""" file = '{}.edf'.format(self.tmp_testfile) siglen = 256 * 155 signals = np.random.rand(10, siglen) sheads = highlevel.make_signal_headers([str(x) for x in range(10)], sample_rate=256, physical_max=1, physical_min=-1) valid_block_sizes = [-1, 1, 5, 31] for block_size in valid_block_sizes: highlevel.write_edf(file, signals, sheads, block_size=block_size) signals2, _, _ = highlevel.read_edf(file) np.testing.assert_allclose(signals, signals2, atol=0.01) with self.assertRaises(AssertionError): highlevel.write_edf(file, signals, sheads, block_size=61) with self.assertRaises(AssertionError): highlevel.write_edf(file, signals, sheads, block_size=-2) # now test non-divisor block_size siglen = signals.shape[-1] highlevel.write_edf(file, signals, sheads, block_size=60) signals2, _, _ = highlevel.read_edf(file) self.assertEqual(signals2.shape, (10, 256 * 60 * 3)) np.testing.assert_allclose(signals2[:, :siglen], signals, atol=0.01) np.testing.assert_allclose(signals2[:, siglen:], np.zeros([10, 25 * 256]), atol=0.0001)
def test_assertion_dmindmax(self): # test digital and dmin wrong signals =[np.random.randint(-2048, 2048, 256*60).astype(np.int32)] sheaders = [highlevel.make_signal_header('ch1', sample_rate=256)] sheaders[0]['digital_min'] = -128 sheaders[0]['digital_max'] = 128 with self.assertRaises(AssertionError): highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=True) # test pmin wrong signals = [np.random.randint(-2048, 2048, 256*60)] sheaders = [highlevel.make_signal_header('ch1', sample_rate=256)] sheaders[0]['physical_min'] = -200 sheaders[0]['physical_max'] = 200 with self.assertRaises(AssertionError): highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=False)
def test_annotation_bytestring(self): header = highlevel.make_header(technician='tech', recording_additional='radd', patientname='name', patient_additional='padd', patientcode='42', equipment='eeg', admincode='420', gender='Male', birthdate='05.09.1980') annotations = [[0.01, b'-1', 'begin'], [0.5, b'-1', 'middle'], [10, -1, 'end']] header['annotations'] = annotations signal_headers = highlevel.make_signal_headers( ['ch' + str(i) for i in range(3)]) signals = np.random.rand(3, 256 * 300) * 200 #5 minutes of eeg highlevel.write_edf(self.edfplus_data_file, signals, signal_headers, header) _, _, header2 = highlevel.read_edf(self.edfplus_data_file) highlevel.write_edf(self.edfplus_data_file, signals, signal_headers, header) _, _, header3 = highlevel.read_edf(self.edfplus_data_file) self.assertEqual(header2['annotations'], header3['annotations'])
def ECG_writer(signal_sqi, file_name, file_type, info = None): """ Parameters ---------- signal_sqi : SignalSQI object containing signals, sampling rate and sqi file_name : name of file to write, with extension. For edf file_type, possible extensions are edf, edf+, bdf, bdf+. For mit file_type, : possible extensions are... : file_type : edf or mit or csv info : list In case of writing edf file: A list containing signal_headers and header (in order). signal_headers is a list of dict with one signal header for each signal channel. header (dict) contain ecg file information. In case of writing wfdb record (mit file): A dict containing header as defined in .hea file. (Default value = None) Returns ------- """ signals = signal_sqi.signals sampling_rate = signal_sqi.sampling_rate start_datetime = signal_sqi.start_datetime assert isinstance(sampling_rate, int) or isinstance(sampling_rate, float), \ 'sampling rate must be either int or float' if file_type == 'edf': signals = signals.transpose() if info is not None: signal_headers = info[1] header = info[0] annotations = header['annotations'] # issue https://github.com/holgern/pyedflib/issues/119 for i in range(len(annotations)): if isinstance(header['annotations'][i][1], bytes): header['annotations'][i][1] = \ float(str(header['annotations'][i][1], 'utf-8')) highlevel.write_edf(file_name, signals, signal_headers, header, file_type = -1, digital = False, block_size = -1) else: highlevel.write_edf_quick(file_name, signals, sampling_rate) return os.path.isfile(file_name) if file_type == 'mit': if info is None: raise Exception("Header dict needed") else: wrsamp(record_name = file_name.split('/')[-1], fs = sampling_rate, units = info['units'], sig_name = info['sig_name'], p_signal = signals, base_date = info['base_date'], base_time = info['base_time'], comments = info['comments'], write_dir = '/'.join(file_name.split('/')[:-1])) return glob.glob(file_name + '.*') if file_type == 'csv': timestamps = generate_timestamp(start_datetime, sampling_rate, signals.shape[0]) signals = pd.DataFrame(np.hstack((np.array(timestamps).reshape(-1, 1), signals))) signals.to_csv(path_or_buf = file_name, index = False, header = True) return os.path.isfile(file_name)
sigs = {} for sfreq in tqdm([128, 200, 256, 250, 350, 512]): signal, sheaders, header = highlevel.read_edf('Z:/ecg/110_88246.edf') sigs[sfreq] = np.atleast_2d(resample(signal, 512, sfreq)) # rescale signal to match max for head in sheaders: head['sample_rate'] = sfreq head['physical_min'] = sigs[sfreq].min() head['physical_max'] = sigs[sfreq].max() highlevel.write_edf(f'z:/ecg/512to{sfreq}hz.edf', sigs[sfreq], sheaders, header) # create upsampled file sigs = {} for sfreq in tqdm([128, 200, 256, 512]): signal, sheaders, header = highlevel.read_edf('Z:/ecg/375_90431.edf') sigs[sfreq] = np.atleast_2d(resample(signal, 512, sfreq)) # rescale signal to match max for head in sheaders: head['sample_rate'] = sfreq head['physical_min'] = sigs[sfreq].min() head['physical_max'] = sigs[sfreq].max()