예제 #1
0
    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)
예제 #2
0
    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")
예제 #3
0
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 []
예제 #4
0
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
예제 #5
0
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 []
예제 #7
0
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)
예제 #8
0
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
예제 #9
0
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('')
예제 #10
0
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
예제 #11
0
# -*- 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)

# %% 
예제 #12
0
 def __init__(self, filename, patient_id=None):
     self._filename = filename
     self._patient_id = patient_id
     self._file = EdfReader(filename)
예제 #13
0
파일: Loader.py 프로젝트: HKH515/edf-loader
    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
예제 #14
0
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__)
예제 #15
0
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)
예제 #16
0
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:
예제 #17
0
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())