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
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)