def __init__(self, path, *args, sampleRate=None, **kargs): """ The rest of parameters can be seen at :meth:`Helper.__init__` Parameters ---------- path: str The path to the edf file """ reader = EdfReader(path) ns = reader.signals_in_file data = [reader.readSignal(i) for i in range(ns)] names = reader.getSignalLabels() frequencies = reader.getSampleFrequencies() if not sampleRate: sampleRate = frequencies[0] if not all(frequencies==sampleRate): raise ValueError("All channels must have the same frequency.") data=np.array(data) super().__init__(data, *args, sampleRate = sampleRate, names = names, **kargs)
def safe_edf_file_operation(self, operation:str="close", full_file_path:Optional[str]=None) -> Union[EdfReader, NoReturn]: """ finished, checked, Parameters ---------- operation: str, default "close", operation name, can be "open" and "close" full_file_path: str, optional, path of the file which contains the psg data, if not given, default path will be used Returns ------- """ if operation == "open": if self.file_opened is not None: self.file_opened._close() self.file_opened = EdfReader(full_file_path) elif operation =="close": if self.file_opened is not None: self.file_opened._close() self.file_opened = None else: raise ValueError("Illegal operation")
def getSignalHeaders(edfFilename): try: print("Reading headers from ", edfFilename) edfR = EdfReader(str(edfFilename)) return edfR.getSignalHeaders() except: print('Could not read headers from {}'.format(edfFilename)) return []
def get_study_starttime(edf_filename, verbose=False): if verbose: print("Reading start time from ", edf_filename) try: edf_r = EdfReader(str(edf_filename), annotations_mode=False, check_file_size=False) return edf_r.getStartdatetime() except: print("Failed reading headers from ", str(edf_filename)) return None
def get_signal_headers(edf_filename, verbose=False): if verbose: print("Reading headers from ", edf_filename) try: edf_r = EdfReader(str(edf_filename), annotations_mode=False, check_file_size=False) return edf_r.getSignalHeaders() except: print("Failed reading headers from ", str(edf_filename)) return []
def getSignalHeaders(edfFilename): try: # print("Reading headers from ", edfFilename) try: edfR = EdfReader(str(edfFilename)) return edfR.getSignalHeaders() except: edfR = mne.io.read_raw_edf(str(edfFilename), verbose=False) return edfR.ch_names except: print("Could not read headers from {}".format(edfFilename)) return []
def get_feature(edf_file): reader = EdfReader(edf_file) n = reader.signals_in_file buffer = np.zeros((n, reader.getNSamples()[0])) for i in np.arange(n): buffer[i, :] = reader.readSignal(i) signal = list(buffer[0]) signal_len = 64 return FeatureExt(signal, signal_len)
def read_edf_file(filename): f = EdfReader(filename) chan = 0 data = f.readSignal(chan) / 1000. sample_freq = f.getSampleFrequency(chan) f._close() return data, sample_freq
def verify_edf_files(edf_path_to_verify: Path): if not isinstance(edf_path_to_verify, Path): edf_path_to_verify = Path(edf_path_to_verify) if not edf_path_to_verify.is_dir(): print( f'Path to edf files is not a directory: {str(edf_path_to_verify)}') elif not edf_path_to_verify.exists(): print(f'Path to edf files does not exist: {str(edf_path_to_verify)}') else: edf_files_not_in_table = [] edf_files_in_table = [] # Get all the files in the path edf_files = edf_path_to_verify.glob('*.[eE][dD][fF]') edf_file_count = len([name for name in edf_files if name.is_file()]) edf_files = edf_path_to_verify.glob('*.[eE][dD][fF]') num_files = edf_file_count fail_files = [] fail_reasons = [] print( f'Verifying .edf files in {str(edf_path_to_verify)}\n\t{num_files} EDF files found.' ) for i, edf_file in enumerate(edf_files): edf_filename = edf_file.name edf_stem = edf_file.stem.lower() if edf_stem in edf_files_in_table: edf_files_in_table.remove(edf_stem) else: edf_files_not_in_table.append(edf_filename) print(f'{i + 1:3d} of {num_files} - {edf_filename} ... ', end='') try: EdfReader(str(edf_file)) print('SUCCESS') except Exception as Exc: # traceback.print_exc(file=sys.stdout) # traceback.print_exception(type(Exc), Exc, None) # traceback.format_exception_only(type(Exc), Exc) # fail_reasons.append(str(Exc)) fail_files.append(edf_filename) print('FAIL') print('') print(f'{len(fail_files)} files failed:') if len(fail_files) > 0: for idx, fail_file in enumerate(fail_files): print(fail_file + '\t' + fail_reasons[idx]) print('')
def _load_edf_file(file_path, signal_labels=None): """Simple wrapper around pyedflib to load LFP/EEG/EMG traces from EDF files and return a numpy array. Currently, only loading of signals with the same sampling frequency and number of samples is supported. Arguments: ---------- file_path -- str /path/to/file.edf signal_labels -- list of str or None (default None) Labels of the signals to load. If None, all signals are loaded. Returns: -------- signals -- (total samples, total signals) ndarray The signals concatenated into a single numpy array. """ with EdfReader(file_path) as reader: if signal_labels is None: signal_labels = reader.getSignalLabels() signals = _load_edf_channels(signal_labels, reader) return signals
# -*- coding: utf-8 -*- """ Created on Sun Jan 5 16:17:58 2020 @author: Dell """ # %% importing dependancies from pyedflib import EdfReader import numpy as np # %% importing the dataset filepath = 'D:\Mini II\DATASETS\eNTERFACING\Data\EEG\Part1_IAPS_SES1_EEG_fNIRS_03082006.bdf' f = EdfReader(filepath) n = f.signals_in_file signal_labels = f.getSignalLabels() sigbufs = np.zeros((n, f.getNSamples()[0])) for i in np.arange(n): sigbufs = f.readSignal(i) # %%
def __init__(self, filename, patient_id=None): self._filename = filename self._patient_id = patient_id self._file = EdfReader(filename)
def _load_file(self, input_file, return_missing=False): """ Parameters ---------- input_file : str path of the file which to load return_missing : bool if true, returns triple (x, y, missing) where missing is true if input_file does contain one or more of the requested channels. Returns ------- tuple ( x : {'channelname': {'sampling_frequency': 100, 'data': np.array}, ... } y : {'channelname': {'sampling_frequency': 100, 'data': np.array}, ... } ) """ reader = EdfReader(input_file) channel_names = reader.getSignalLabels() channel_names_dict = { channel_names[i]: i for i in range(len(channel_names)) } x_channels_to_process = set(channel_names).intersection( set(self.x_channels)) y_channels_to_process = set(channel_names).intersection( set(self.y_channels)) x_not_present = set(self.x_channels).difference( set(self.x_channels).intersection(set(channel_names))) y_not_present = set(self.y_channels).difference( set(self.y_channels).intersection(set(channel_names))) not_present = x_not_present.union(y_not_present) #return this with x and y to detect missing channels. missing = len(not_present) != 0 #report missing channels if missing: not_present = [i for i in not_present] print( f'File \'{input_file}\' does not have channels: {not_present}') # Create data dictionaries x_channel_data_dict = {} for i in x_channels_to_process: x_channel_data_dict[i] = { "sampling_frequency": reader.getSampleFrequency(channel_names_dict[i]), "data": reader.readSignal(channel_names_dict[i]) } y_channel_data_dict = {} for i in y_channels_to_process: y_channel_data_dict[i] = { "sampling_frequency": reader.getSampleFrequency(channel_names_dict[i]), "data": reader.readSignal(channel_names_dict[i]) } if return_missing: return x_channel_data_dict, y_channel_data_dict, missing else: return x_channel_data_dict, y_channel_data_dict
class UCDDB(PhysioNetDataBase): """ NOT finished, St. Vincent"s University Hospital / University College Dublin Sleep Apnea Database ABOUT ucddb ----------- 1. contains 25 full overnight polysomnograms (PSGs) with simultaneous three-channel Holter ECGs *.rec --- PSG data in EDF format *_lifecard.edf --- ECG data in EDF format 2. PSG signals recorded were: EEG (C3-A2), EEG (C4-A1), left EOG, right EOG, submental EMG, ECG (modified lead V2), oro-nasal airflow (thermistor), ribcage movements, abdomen movements (uncalibrated strain gauges), oxygen saturation (finger pulse oximeter), snoring (tracheal microphone), body position 3. holter ECG leads: V5, CC5, V5R 4. sleep stage annotations: 0 - Wake 1 - REM 2 - Stage 1 3 - Stage 2 4 - Stage 3 5 - Stage 4 6 - Artifact 7 - Indeterminate 5. respiratory events: O - obstructive, apneas, C - central apneas, M - mixed apneas, HYP - hypopneas, PB - periodic breathing episodes CS - Cheynes-Stokes Bradycardia / Tachycardia NOTE ---- 1. this dataset is NOT in the standard wfdb format, but rather in EDF format 2. in record ucddb002, only two distinct ECG signals were recorded; the second ECG signal was also used as the third signal. ISSUES ------ Usage ----- 1. sleep stage 2. sleep apnea References ---------- [1] https://physionet.org/content/ucddb/1.0.0/ """ def __init__(self, db_dir:Optional[str]=None, working_dir:Optional[str]=None, verbose:int=2, **kwargs:Any) -> NoReturn: """ Parameters ---------- db_dir: str, optional, storage path of the database if not specified, data will be fetched from Physionet working_dir: str, optional, working directory, to store intermediate files and log file verbose: int, default 2, log verbosity kwargs: auxilliary key word arguments """ super().__init__(db_name="ucddb", db_dir=db_dir, working_dir=working_dir, verbose=verbose, **kwargs) self.data_ext = "rec" self.extra_data_ext = "_lifecard.edf" self.ann_ext = None self.stage_ann_ext = "_stage.txt" self.event_ann_ext = "_stage.txt" self._ls_rec() self.fs = None self.file_opened = None def safe_edf_file_operation(self, operation:str="close", full_file_path:Optional[str]=None) -> Union[EdfReader, NoReturn]: """ finished, checked, Parameters ---------- operation: str, default "close", operation name, can be "open" and "close" full_file_path: str, optional, path of the file which contains the psg data, if not given, default path will be used Returns ------- """ if operation == "open": if self.file_opened is not None: self.file_opened._close() self.file_opened = EdfReader(full_file_path) elif operation =="close": if self.file_opened is not None: self.file_opened._close() self.file_opened = None else: raise ValueError("Illegal operation") def get_subject_id(self, rec) -> int: """ """ raise NotImplementedError def database_info(self) -> NoReturn: """ """ print(self.__doc__)
class NSRRDataBase(_DataBase): """ https://sleepdata.org/ """ def __init__(self, db_name: str, db_dir: str, working_dir: Optional[str] = None, verbose: int = 2, **kwargs: Any) -> NoReturn: """ Parameters ---------- db_name: str, name of the database db_dir: str, storage path of the database working_dir: str, optional, working directory, to store intermediate files and log file verbose: int, default 2, log verbosity kwargs: auxilliary key word arguments typical `db_dir`: ------------------ "E:\\notebook_dir\\ecg\\data\\NSRR\\xxx\\" "/export/algo/wenh06/ecg_data/NSRR/xxx/" """ super().__init__(db_name=db_name, db_dir=db_dir, working_dir=working_dir, verbose=verbose, **kwargs) # self._set_logger(prefix="NSRR") self.fs = None self._all_records = None self.device_id = None # maybe data are imported into impala db, to facilitate analyzing self.file_opened = None all_dbs = [ [ "shhs", "Multi-cohort study focused on sleep-disordered breathing and cardiovascular outcomes" ], ["mesa", ""], ["oya", ""], [ "chat", "Multi-center randomized trial comparing early adenotonsillectomy to watchful waiting plus supportive care" ], [ "heartbeat", "Multi-center Phase II randomized controlled trial that evaluates the effects of supplemental nocturnal oxygen or Positive Airway Pressure (PAP) therapy" ], # more to be added ] self.df_all_db_info = pd.DataFrame({ "db_name": [item[0] for item in all_dbs], "db_description": [item[1] for item in all_dbs] }) self.kwargs = kwargs def safe_edf_file_operation( self, operation: str = "close", full_file_path: Optional[str] = None) -> NoReturn: """ finished, checked, Parameters ---------- operation: str, default "close", operation name, can be "open" and "close" full_file_path: str, optional, path of the file which contains the psg data, if not given, default path will be used """ if operation == "open": if self.file_opened is not None: self.file_opened._close() self.file_opened = EdfReader(full_file_path) elif operation == "close": if self.file_opened is not None: self.file_opened._close() self.file_opened = None else: raise ValueError("Illegal operation") def get_subject_id(self, rec: str) -> int: """ Attach a `subject_id` to the record, in order to facilitate further uses Parameters ---------- rec: str, record name Returns ------- int, a `subject_id` attached to the record `rec` """ raise NotImplementedError def get_patient_id(self, rec: str) -> int: """ synonym for func `self.get_subject_id` """ return self.get_subject_id(rec=rec) def show_rec_stats(self, rec: str) -> NoReturn: """ print the statistics about the record `rec` Parameters ---------- rec: str, record name """ raise NotImplementedError def database_info(self, detailed: bool = False) -> NoReturn: """ print the information about the database detailed: bool, default False, if False, an short introduction of the database will be printed, if True, then docstring of the class will be printed additionally """ raw_info = {"What": "", "Who": "", "When": "", "Funding": ""} print(raw_info) if detailed: print(self.__doc__) def helper(self, items: Union[List[str], str, type(None)] = None, **kwargs) -> NoReturn: """ """ pp = pprint.PrettyPrinter(indent=4) attrs = vars(self) methods = [ func for func in dir(self) if callable(getattr(self, func)) and not (func.startswith("__") and func.endswith("__")) ] if items is None: _items = [ "attributes", "methods", ] elif isinstance(items, str): _items = [items] else: _items = items pp = pprint.PrettyPrinter(indent=4) if "attributes" in _items: print("--- helpler - attributes ---") pp.pprint(attrs) if "methods" in _items: print("--- helpler - methods ---") pp.pprint(methods)
from pyedflib import highlevel from pyedflib import EdfReader # read an edf file signals, signal_headers, header = highlevel.read_edf('CHP040.edf') print('********************************************************************************************************************************', file=open("output.txt", "a")) f = EdfReader('CHP040.edf') #print("\nlibrary version: %s" % pyedflib.version.version) print("\ngeneral header:\n") print("file duration: %i seconds" % f.file_duration) print("startdate: %i-%i-%i" % (f.getStartdatetime().day,f.getStartdatetime().month,f.getStartdatetime().year)) print("starttime: %i:%02i:%02i" % (f.getStartdatetime().hour,f.getStartdatetime().minute,f.getStartdatetime().second)) print("patientcode: %s" % f.getPatientCode()) print("gender: %s" % f.getGender()) print("birthdate: %s" % f.getBirthdate()) print("patient_name: %s" % f.getPatientName()) print("patient_additional: %s" % f.getPatientAdditional()) print("admincode: %s" % f.getAdmincode()) print("technician: %s" % f.getTechnician()) print("equipment: %s" % f.getEquipment()) print("recording_additional: %s" % f.getRecordingAdditional()) print("datarecord duration: %f seconds" % f.getFileDuration()) print("number of datarecords in the file: %i" % f.datarecords_in_file) print("number of annotations in the file: %i" % f.annotations_in_file) print('****************************************************************', file=open("output.txt", "a")) for i in header:
class ChbEdfFile(object): """ Edf reader using pyedflib """ def __init__(self, filename, patient_id=None): self._filename = filename self._patient_id = patient_id self._file = EdfReader(filename) def get_filename(self): return self._filename def get_n_channels(self): """ Number of channels """ return len(self._file.getSampleFrequencies()) def get_n_data_points(self): """ Number of data points """ if len(self._file.getNSamples()) < 1: raise ValueError("Number of channels is less than 1") return self._file.getNSamples()[0] def get_channel_names(self): """ Names of channels """ return self._file.getSignalLabels() def get_channel_scalings(self): """ Channel scalings as an array :return: """ out = np.zeros(self.get_n_channels()) for i in range(self.get_n_channels()): out[i] = self._file.getPhysicalMaximum( i) - self._file.getPhysicalMinimum(i) return out def get_file_duration(self): """ Returns the file duration in seconds """ return self._file.getFileDuration() def get_sampling_rate(self): """ Get the frequency """ if len(self._file.getSampleFrequencies()) < 1: raise ValueError("Number of channels is less than 1") return self._file.getSampleFrequency(0) def get_channel_data(self, channel_id): """ Get raw data for a single channel """ if channel_id >= self.get_n_channels() or channel_id < 0: raise ValueError("Illegal channel id selected %d" % channel_id) return self._file.readSignal(channel_id) def get_data(self): """ Get raw data for all channels """ output_data = np.zeros( (self.get_n_data_points(), self.get_n_channels())) for i in range(self.get_n_channels()): output_data[:, i] = self._file.readSignal(i) return output_data def get_start_datetime(self): """ Get the starting date and time """ return self._file.getStartdatetime() def get_end_datetime(self): return self._file.getStartdatetime() + datetime.timedelta( seconds=self._file.getFileDuration())