Ejemplo n.º 1
0
def load_data(filename):
    '''Get recordings from a single XDF file and order streams by device.'''
    # Load XDF file
    streams = load_xdf(filename)

    streameeg, streamacc, streamppg, streamgyr, device_name = [], [], [], [], []

    # Get the individual names of every Muse device
    for stream in streams[0]:
        name = stream['info']['name'][0][:9]
        if name not in device_name:
            device_name.append(name)

    # Order the streams in a new list based on the name of the device
    streams_ordered = []
    for item in device_name:
        if len(streams_ordered) < (len(device_name) * 4) + len(device_name):
            for stream in streams[0]:
                if item == stream['info']['name'][0][:9]:
                    streams_ordered.append(stream)

    # Insert each stream inside a file into the corresponding list
    for stream in streams_ordered:
        if 'EEG' in stream['info']['type'][0]:
            streameeg.append(stream)
        if 'Accelerometer' in stream['info']['type'][0]:
            streamacc.append(stream)
        if 'Gyroscope' in stream['info']['type'][0]:
            streamgyr.append(stream)
        if 'PPG' in stream['info']['type'][0]:
            streamppg.append(stream)

    return streameeg, streamacc, streamppg, streamgyr
Ejemplo n.º 2
0
def load_eeg_data(folder_path):
    """
    Load the raw EEG data from the xdf file.
    :param folder_path: path to the folder where the xdf file was located
    :return: ndarray, EEG data
    """

    # Get the xdf file
    path = os.path.join(folder_path, 'EEG.xdf')
    data, header = pyxdf.load_xdf(path, [{'type': 'EEG'}])

    # Get the EEG data & update sample rate param
    eeg_data = data[0]['time_series']
    eeg_timestamp = data[0]['time_stamps']
    params['data']['sample_freq'] = float(data[0]['info']['effective_srate'])  # update the sample rate

    # Remove channels
    eeg_data = np.delete(eeg_data, obj=params['preprocess']['remove_channels'], axis=1)

    # Debug print
    print('EEG data loaded\nData shape: {}'.format(eeg_data.shape))

    # Dump the info as JSON
    json.dump(data[0]['info'], open(os.path.join(folder_path, '.info'), 'w'))

    return eeg_data, eeg_timestamp
Ejemplo n.º 3
0
    def __init__(self, path, verbose=None, freq=2048):
        logging.basicConfig(
            level=logging.INFO)  # Use logging.INFO to reduce output.
        fname = os.path.abspath(
            os.path.join(os.path.dirname(__file__), '..', '..', path))
        self.streams, self.fileheader = pyxdf.load_xdf(fname)
        self.freq = freq
        self.cut_EEG = None

        if verbose is True:
            print("Found {} streams:".format(len(self.streams)))

            for ix, stream in enumerate(self.streams):
                print(
                    "Stream {}: {} - type {} - uid {} - shape {} at {} Hz (effective {} Hz)"
                    .format(ix + 1, stream['info']['name'][0],
                            stream['info']['type'][0],
                            stream['info']['uid'][0],
                            (int(stream['info']['channel_count'][0]),
                             len(stream['time_stamps'])),
                            stream['info']['nominal_srate'][0],
                            stream['info']['effective_srate']))
                if any(stream['time_stamps']):
                    print("\tDuration: {} s".format(stream['time_stamps'][-1] -
                                                    stream['time_stamps'][0]))
            print("Done.")

        else:
            print(type(self.streams), len(self.streams), type(self.streams[0]),
                  len(self.streams[0]))
            print(self.streams[1]["time_series"].shape)

        self.data_EEG = np.array(
            self.streams[1]["time_series"]).transpose()[1:33]
Ejemplo n.º 4
0
def get_trials_times(subject_path):
    """
    This function get subject path and return a list of the trials timestamps.
    contains the trial start & end timestamps.
    :param subject_path: str, path to the current subject folder
    :return: list with tuples correspond to the start & end of each trial
    """

    # Load the markers from the xdf file
    path = os.path.join(subject_path, 'EEG.xdf')
    data, header = pyxdf.load_xdf(path, [{'type': 'Markers'}])

    # Get the markers data and timestamps
    markers = [e[0] for e in data[0]['time_series']]
    markers_timestamps = data[0]['time_stamps']

    start = params['lsl']['start_trial']
    trial_times = []

    for i in range(len(markers)):

        if markers[i] == start:
            trial_times.append(
                (markers_timestamps[i], markers_timestamps[i + 1]))

    return trial_times
def expand_files(file, dst_path):

    if not dst_path.exists():
        dst_path.mkdir(parents=True)

    data, header = pyxdf.load_xdf(file)

    stream_names = [stream['info']['name'][0] for stream in data]
    # print(stream_names)

    markers, markers_time = get_experimental_marker(data)

    for stream in data:
        stream_name = stream['info']['name'][0]
        stream_info = stream['info']
        time_series = np.array(stream['time_series'])  #Recorded values
        time_stamps = np.array(stream['time_stamps']).reshape(-1,
                                                              1)  #Timestamps

        #Trim signals with experimental markers
        idx = np.where((time_stamps > markers_time[0])
                       & (time_stamps < markers_time[1]))
        time_series = time_series[idx].reshape(-1, 1)
        time_stamps = time_stamps[idx].reshape(-1, 1)

        data = np.hstack((time_stamps, time_series))
        df = pd.DataFrame(data)
        df.to_csv(dst_path / "{:}_data.csv".format(stream_name), index=False)

        with open(dst_path / "{:}_info.json".format(stream_name), 'w') as f1:
            json_data = json.dumps(stream_info, indent=3)
            f1.write(json_data)
Ejemplo n.º 6
0
def XDFFile(filename: Union[Path, str], verbose=False) -> Dict[str, XDFStream]:
    """load an :code:`xdf`-file and return a dictionary of its streams

    args
    ----
    filename: 
        the name of the xdffile

    returns
    -------
    streams: Dict[str, XDFStream]
        a collection of all :class:`~.XDFStream` s in the file. These can be indexed by their respective name

    """
    streams, _ = pyxdf.load_xdf(filename=str(filename))
    collection: Dict[str, XDFStream] = dict()
    doublettes: Dict[str, int] = dict()
    for stream in streams:
        if not verbose:
            print("XDFFile: Parsing", stream["info"]["name"][0])
        x = XDFStream(stream)
        x.origin = str(filename)
        doublettes[x.name] = doublettes.get(x.name, 0) + 1
        if doublettes[x.name] == 1:
            collection[x.name] = x
        else:
            collection[x.name + str(doublettes[x.name])] = x

    return collection
Ejemplo n.º 7
0
def main(filename):
    streams, info = load_xdf(filename)
    hdr = "XDF Fileversion " + info["info"]["version"][0]
    print(f"\r\nLoading {filename:3}\n")
    print(f"{hdr:>80}\n")
    line = "{0:<25s}{1:^20s}{2:4s}{3:^5s}{4:>26s}"
    print(line.format("Name", "Type", "Ch", "Fs", "Source"))
    print("-" * 80)
    for s in streams:
        name = s["info"]["name"][0]
        typ = s["info"]["type"][0]
        cc = s["info"]["channel_count"][0]
        fs = s["info"]["nominal_srate"][0]
        name = shorten(name, 25)
        typ = shorten(typ, 20)
        try:
            sid = s["info"]["source_id"][0]
            sid = shorten(sid, 25)
        except IndexError:
            sid = '""'

        print(line.format(name, typ, cc, fs, sid))

    print("\n")

    line = "{0:<30s}{1:>50s}"
    for s in streams:
        typ = s["info"]["type"][0]
        name = s["info"]["name"][0]
        if "marker" in typ.lower():
            events = Counter([s[0] for s in s["time_series"]])
            print(line.format(name, "Events"))
            print("-" * 80)
            for key, val in events.items():
                if key == "":
                    wrapped_key = '""'
                else:
                    wrapped_key = textwrap.shorten(key,
                                                   width=70,
                                                   placeholder="...")
                alignment = 80 - len(wrapped_key)
                print("{0}{1:>{align}}".format(wrapped_key,
                                               val,
                                               align=alignment))

            print()
        else:
            print(line.format(name, "Exemplary data"))
            print("-" * 80)
            sz = s["time_series"].shape
            if sz[1]:
                x = s["time_stamps"]
                y = s["time_series"][:, 0]
                plot(y, x)
            else:
                print("No data found, array has shape({0}, {1})".format(*sz))
            print()

    print(f"Overview finished for {filename:3}\n")
Ejemplo n.º 8
0
    def __init__(self, xdf_path: str, channels: List[str]):

        self.channels: List[str] = channels
        self.labels: List[int] = []
        self.sample_freq: float = 125
        self._xdf, _ = pyxdf.load_xdf(xdf_path)
        self.data: NDArray = self._xdf[1][
            'time_series'][:,
                           3:]  # remove first 3 columns (time, noisy, noisy)
        self.duration: List[Tuple] = self.extract_durations()
Ejemplo n.º 9
0
def read_raw_xdf(fname, stream_id):
    """Read XDF file.

    Parameters
    ----------
    fname : str
        Name of the XDF file.
    stream_id : int
        ID (number) of the stream to load.

    Returns
    -------
    raw : mne.io.Raw
        XDF file data.
    """
    from pyxdf import load_xdf

    streams, header = load_xdf(fname)
    for stream in streams:
        if stream["info"]["stream_id"] == stream_id:
            break  # stream found

    n_chans = int(stream["info"]["channel_count"][0])
    fs = float(stream["info"]["nominal_srate"][0])
    labels, types, units = [], [], []
    try:
        for ch in stream["info"]["desc"][0]["channels"][0]["channel"]:
            labels.append(str(ch["label"][0]))
            if ch["type"]:
                types.append(ch["type"][0])
            if ch["unit"]:
                units.append(ch["unit"][0])
    except (TypeError, IndexError):  # no channel labels found
        pass
    if not labels:
        labels = [str(n) for n in range(n_chans)]
    if not units:
        units = ["NA" for _ in range(n_chans)]
    info = mne.create_info(ch_names=labels, sfreq=fs, ch_types="eeg")
    # convert from microvolts to volts if necessary
    scale = np.array([1e-6 if u == "microvolts" else 1 for u in units])
    raw = mne.io.RawArray((stream["time_series"] * scale).T, info)

    first_samp = stream["time_stamps"][0]
    markers = match_streaminfos(resolve_streams(fname), [{"type": "Markers"}])
    for stream_id in markers:
        for stream in streams:
            if stream["info"]["stream_id"] == stream_id:
                break
        onsets = stream["time_stamps"] - first_samp
        descriptions = [item for sub in stream["time_series"] for item in sub]
        raw.annotations.append(onsets, [0] * len(onsets), descriptions)

    return raw
Ejemplo n.º 10
0
def read_raw_xdf(fname, stream_id=None):
    """Read XDF file.
    Parameters
    ----------
    fname : str
        Name of the XDF file.
    stream_id : int | str | None
        ID (number) or name of the stream to load (optional). If None, the
        first stream of type "EEG" will be read.
    Returns
    -------
    raw : mne.io.Raw
        XDF file data.
    """
    streams, header = load_xdf(fname)

    if stream_id is not None:
        if isinstance(stream_id, str):
            stream = _find_stream_by_name(streams, stream_id)
        elif isinstance(stream_id, int):
            stream = _find_stream_by_id(streams, stream_id)
    else:
        stream = _find_stream_by_type(streams, stream_type="EEG")

    if stream is not None:
        name = stream["info"]["name"][0]
        n_chans = int(stream["info"]["channel_count"][0])
        fs = float(stream["info"]["nominal_srate"][0])
        logger.info(f"Found EEG stream '{name}' ({n_chans} channels, "
                    f"sampling rate {fs}Hz).")
        labels, types, units = _get_ch_info(stream)
        if not labels:
            labels = [str(n) for n in range(n_chans)]
        if not units:
            units = ["NA" for _ in range(n_chans)]
        info = mne.create_info(ch_names=labels, sfreq=fs, ch_types="eeg")
        # convert from microvolts to volts if necessary
        scale = np.array([1e-6 if u == "microvolts" else 1 for u in units])
        raw = mne.io.RawArray((stream["time_series"] * scale).T, info)
        first_samp = stream["time_stamps"][0]
    else:
        logger.info("No EEG stream found.")
        return

    markers = _find_stream_by_type(streams, stream_type="Markers")
    if markers is not None:
        onsets = markers["time_stamps"] - first_samp
        logger.info(f"Adding {len(onsets)} annotations.")
        descriptions = markers["time_series"]
        annotations = mne.Annotations(onsets, [0] * len(onsets), descriptions)
        raw.set_annotations(annotations)

    return raw
Ejemplo n.º 11
0
def main():
    for f in dataPath.glob('*.xdf'):

        # Load xdf files
        if len(re.findall(".xdf", f.name)) > 0:
            file = f

            # Rename files --> remove identifiers
            uid = re.findall('.+(?=_S[0-9][0-9]+_T[0-9][0-9]_)', file.name)[0]
            session = int(
                re.findall('(?<=_S)[0-9]+(?=_T[0-9][0-9]_)', file.name)[0])
            trial = int(
                re.findall('(?<=_S[0-9]{2}_T)[0-9]{2}(?=_)', file.name)[0])
            task = re.findall('(?<=_S[0-9]{2}_T[0-9]{2}_).+(?=_raw\.xdf)',
                              file.name)[0]

            basePath = './eye_tracker_txt/' + "{:}_S{:02d}_T{:02d}_{:}_".format(
                uid, session, trial, task)

            print(uid, session, trial, task)
            print("srcPath", f)
            print("dstPath", basePath)

            data, header = pyxdf.load_xdf(file)
            stream_names = [stream['info']['name'][0] for stream in data]
            print(stream_names)

            eye_stream_dict = {}
            gaze_stream = None
            markers, markersTime = None, None

            # Get data and experiment markers
            for stream in data:
                if stream['info']['name'][0] == 'left_eye_data' or stream[
                        'info']['name'][0] == 'right_eye_data':
                    eye = 'left' if 'left' in stream['info']['name'][
                        0] else 'right'
                    eye_stream_dict[eye] = stream
                if stream['info']['name'][0] == 'gaze_position':
                    gaze_stream = stream
                if stream['info']['name'][0] == 'ExperimentMarkers':
                    if stream['time_series'][0][0] == '':
                        continue
                    markers = stream['time_series']
                    markersTime = stream['time_stamps']

            extract_eye_data(eye_stream_dict, markers, markersTime, basePath)
            extract_gaze_position(gaze_stream, markers, markersTime, basePath)
Ejemplo n.º 12
0
def test_load_file(file):
    streams, header = load_xdf(file)

    if file.endswith("minimal.xdf"):
        assert header["info"]["version"][0] == "1.0"

        assert len(streams) == 2
        assert streams[0]["info"]["name"][0] == "SendDataC"
        assert streams[0]["info"]["type"][0] == "EEG"
        assert streams[0]["info"]["channel_count"][0] == "3"
        assert streams[0]["info"]["nominal_srate"][0] == "10"
        assert streams[0]["info"]["channel_format"][0] == "int16"
        assert streams[0]["info"]["stream_id"] == 0

        s = np.array([[192, 255, 238], [12, 22, 32], [13, 23, 33],
                      [14, 24, 34], [15, 25, 35], [12, 22, 32], [13, 23, 33],
                      [14, 24, 34], [15, 25, 35]],
                     dtype=np.int16)
        t = np.array([5., 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8])
        np.testing.assert_array_equal(streams[0]["time_series"], s)
        np.testing.assert_array_almost_equal(streams[0]["time_stamps"], t)

        assert streams[1]["info"]["name"][0] == "SendDataString"
        assert streams[1]["info"]["type"][0] == "StringMarker"
        assert streams[1]["info"]["channel_count"][0] == "1"
        assert streams[1]["info"]["nominal_srate"][0] == "10"
        assert streams[1]["info"]["channel_format"][0] == "string"
        assert streams[1]["info"]["stream_id"] == 0x02C0FFEE

        s = [[
            '<?xml version="1.0"?><info><writer>LabRecorder xdfwriter'
            '</writer><first_timestamp>5.1</first_timestamp><last_timestamp>'
            '5.9</last_timestamp><sample_count>9</sample_count>'
            '<clock_offsets><offset><time>50979.76</time><value>-.01</value>'
            '</offset><offset><time>50979.86</time><value>-.02</value>'
            '</offset></clock_offsets></info>'
        ], ['Hello'], ['World'], ['from'], ['LSL'], ['Hello'], ['World'],
             ['from'], ['LSL']]
        t = np.array([5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9])
        assert streams[1]["time_series"] == s
        np.testing.assert_array_almost_equal(streams[1]["time_stamps"], t)
Ejemplo n.º 13
0
    def Xdf_Load(path):
        logging.basicConfig(
            level=logging.DEBUG)  # Use logging.INFO to reduce output.
        fname = path
        streams, fileheader = pyxdf.load_xdf(fname)

        print("Found {} streams:".format(len(streams)))
        for ix, stream in enumerate(streams):
            print(
                "Stream {}: {} - type {} - uid {} - shape {} at {} Hz (effective {} Hz)"
                .format(ix + 1, stream['info']['name'][0],
                        stream['info']['type'][0], stream['info']['uid'][0],
                        (int(stream['info']['channel_count'][0]),
                         len(stream['time_stamps'])),
                        stream['info']['nominal_srate'][0],
                        stream['info']['effective_srate']))
            if any(stream['time_stamps']):
                print("\tDuration: {} s".format(stream['time_stamps'][-1] -
                                                stream['time_stamps'][0]))
        print("Done.")
        return streams, fileheader
Ejemplo n.º 14
0
def XDFFile(filename: Union[Path, str]) -> Dict[str, XDFStream]:
    """load an :code:`xdf`-file and return a dictionary of its streams

    args
    ----
    filename: 
        the name of the xdffile

    returns
    -------
    streams: Dict[str, XDFStream]
        a collection of all :class:`~.XDFStream` s in the file. These can be indexed by their respective name

    """
    streams, _ = pyxdf.load_xdf(filename=str(filename))
    collection: Dict[str, XDFStream] = dict()
    for stream in streams:
        print("Parsing ", stream["info"]["name"][0])
        x = XDFStream(stream)
        collection[x.name] = x
    return collection
Ejemplo n.º 15
0
def replay(file_path, us_rate, repeat, verbose):
    """Replay .xdf file as LSL recording session
    Args:
        file_path: str
            path to .xdf file
        us_rate: int
            Sampling rate (Hz) to undersample original recording.
            If None it will keep the original sampling frequency
        repeat: int
            Number of times to repeat the recording
        verbose: bool
            Verbosity mode
    """

    print("Attempting to load xdf data")
    streams, header = load_xdf(file_path, dejitter_timestamps=True, synchronize_clocks=True)

    first_timestamp = streams[0]["time_stamps"][0]
    threads = list()
    for stream in streams:
        if len(stream["time_stamps"]) < 1:
            continue

        if stream["time_stamps"][0] < first_timestamp:
            first_timestamp = stream["time_stamps"][0]

    for stream in streams:
        if len(stream["time_stamps"]) < 1:
            continue

        delay = stream["time_stamps"][0] - first_timestamp
        t = threading.Timer(0, lsl_stream, [stream, delay, us_rate, repeat, verbose])
        t.daemon = True
        t.start()
        threads.append(t)

    while has_live_threads(threads):
        for t in threads:
            t.join(10)
Ejemplo n.º 16
0
Tester_age = 23
Tester_driverLicense = 0
Tester_sleepTime = 2407
Tester_testtime = 19

# 폴더 번호 설정
i = 0

# 데이터 저장 위치
Folder = r'C:\Users\ekdlw\Desktop\Bio Data Analysis\CSV_file'
File_name = f'\\{Tester_sex}{Tester_age}{Tester_driverLicense}{Tester_sleepTime}{Tester_testtime}_{i}.csv'

# 데이터 저장 시간
Cutting_time = Frame_rate * Data_Save_time

data, header = pyxdf.load_xdf(
    r'C:\Users\ekdlw\Desktop\Bio Data Analysis\XDF_file\20101001.xdf')

for stream in data:
    i = i + 1
    y = stream['time_series']
    x = stream['time_stamps']

    df1 = pd.DataFrame(y)
    df2 = pd.DataFrame(x)

    df1 = pd.concat([df1, df2], axis=1)

    File_name = f'\\{Tester_sex}{Tester_age}{Tester_driverLicense}{Tester_sleepTime}{Tester_testtime}_{i}.csv'
    df1.to_csv(Folder + File_name, index=False, columns=False)

    if isinstance(y, list):
for f in dataPath.glob('*.xdf'):
    print(f)
    #Load xdf files
    if len(re.findall(".xdf", f.name)) > 0:
        file = f

        task = re.findall("(?<=T[0-9]{2}_).+(?=\.xdf)", file.name)[0]
        subject = re.findall(".+(?=_S[0-9]{1})", file.name)[0]
        session = int(re.findall("(?<=_S)[0-9]{1}(?=_T)", file.name)[0])
        trial = int(re.findall("(?<=_T)[0-9]{2}(?=_)", file.name)[0])

        dstPath1 = Path('./data-processed/'
                        ) / "{:}_S{:d}_T{:d}_{:}_shimmer_ppg.txt".format(
                            subject, session, trial, task)

        data, header = pyxdf.load_xdf(file)

        #Get data and experiment markers
        for stream in data:
            if stream['info']['name'][0] == 'ExperimentMarkers':
                markers = stream['time_series']
                markersTime = stream['time_stamps']
            elif stream['info']['name'][0] == 'Shimmer_ppg':
                if stream['footer']['info']['first_timestamp'][0] != '0':
                    eegData = stream['time_series']
                    eegInfo = stream['info']
                    eegTime = stream['time_stamps']
            # elif stream['info']['name'][0] == 'NB-2015.10.15':
            #     if stream['footer']['info']['first_timestamp'][0] != '0':
            #         eegData = stream['time_series']
            #         eegInfo = stream['info']
Ejemplo n.º 18
0
import os
import matplotlib.pyplot as plt

data_path = '../bci4als/data/noam/2'
trial = 50
eeg_path = os.path.join(data_path, 'EEG.xdf')
trials_path = os.path.join(data_path, 'EEG_trials.pickle')
clean_path = os.path.join(data_path, 'EEG_clean.csv')
ch_names = [
    'C03', 'C04', 'P07', 'P089', 'O01', 'O02', 'F07', 'F08', 'F03', 'F04',
    'T07', 'T08', 'P03'
]
s_rate = 125

trials = pickle.load(open(trials_path, 'rb'))
trial_data = trials[trial].to_numpy()
full_data = pyxdf.load_xdf(eeg_path, [{
    'type': 'EEG'
}])[0][0]['time_series'][:, 3:]
clean_data = np.genfromtxt(clean_path, delimiter=',', skip_header=1)[:, 1:]

info = mne.create_info(ch_names, s_rate, verbose=False)
raw_trial = mne.io.RawArray(trial_data.T, info, verbose=False)
raw_full_data = mne.io.RawArray(full_data.T, info, verbose=False)
raw_clean_data = mne.io.RawArray(clean_data.T, info, verbose=False)

raw_trial.plot()
# raw_trial.plot_psd(picks=ch_names)
# fig_1 = raw_full_data.plot_psd(picks=ch_names)
# fig_2 = raw_clean_data.plot_psd(picks=ch_names)
Ejemplo n.º 19
0
import numpy as np
import pyxdf
from matplotlib import pyplot as plt

# File to test
TEST_FILE = 'C:\\Recordings\\CurrentStudy\\exp4\\untitled.xdf'

# Load it and get the channels
data = pyxdf.load_xdf(TEST_FILE)
channels = data[0][0]['info']['desc'][0]['channels'][0]

# Get all the channel names
channames = []
for channel in channels['channel']:
    print(channel)
    channames.append(channel['label'][0])
print(channames)

# Get the channel for the Mindwave raw data in `rawEeg`
raw_channel = "Fp1"
chanind = [c for c, n in enumerate(channames) if n == raw_channel][0]
print("rawEeg channel index: %s" % chanind)

# Gather all the rawEeg data and plot it
timeseries = data[0][0]['time_series']
raweeg = []
for row in timeseries:
    if np.isnan(row[chanind]): continue
    raweeg.append(row[chanind])

timestamps = data[0][0]['time_stamps']
Ejemplo n.º 20
0
    'chans_excluded': [],
    'segments_retained': []
}
for d in dirs:

    print(f'subj {dirs.index(d)}')
    chdir(exdir + '/recordings')
    chdir(d)
    files = [f for f in listdir() if '.xdf' in f and not '.p' in f]

    #f = files[0]
    for f in files:
        print(f'file {files.index(f)}')

        dat = pyxdf.load_xdf(f,
                             dejitter_timestamps=True,
                             synchronize_clocks=True)[0]
        # """data structure e.g.:
        #     0 - marker
        #     1 - resp. belt
        #     2 - pupil 18-21 pupil size
        #     3 - EEG marker
        #     4 - EEG data
        #     !!order is not consistent between datasets!!"""

        stream_indices = [dat[n]['info']['name'][0] for n in range(len(dat))]

        #% ECG
        #     # extract ECG and R peaks
        try:
            pre_trial, stim_trial, post_trial, resp_times = segment_recording(
Ejemplo n.º 21
0
#          Eric Larson <*****@*****.**>
#
# License: BSD-3-Clause

# %%

import os.path as op

import pyxdf

import mne
from mne.datasets import misc

fname = op.join(misc.data_path(), 'xdf',
                'sub-P001_ses-S004_task-Default_run-001_eeg_a2.xdf')
streams, header = pyxdf.load_xdf(fname)
data = streams[0]["time_series"].T
assert data.shape[0] == 5  # four raw EEG plus one stim channel
data[:4:2] -= data[1:4:2]  # subtract (rereference) to get two bipolar EEG
data = data[::2]  # subselect
data[:2] *= (1e-6 / 50 / 2)  # uV -> V and preamp gain
sfreq = float(streams[0]["info"]["nominal_srate"][0])
info = mne.create_info(3, sfreq, ["eeg", "eeg", "stim"])
raw = mne.io.RawArray(data, info)
raw.plot(scalings=dict(eeg=100e-6), duration=1, start=14)

# %%
# References
# ----------
# .. footbibliography::
Ejemplo n.º 22
0
def read_raw_xdf(fname, stream_id, srate="effective", prefix_markers=False, *args,
                 **kwargs):
    """Read XDF file.

    Parameters
    ----------
    fname : str
        Name of the XDF file.
    stream_id : int
        ID (number) of the stream to load.
    srate : {"nominal", "effective"}
        Use either nominal or effective sampling rate.
    prefix_markers : bool
        Whether or not to prefix markers with their corresponding stream ID.

    Returns
    -------
    raw : mne.io.Raw
        XDF file data.
    """
    if srate not in ("nominal", "effective"):
        raise ValueError(f"The 'srate' parameter must be either 'nominal' or 'effective' "
                         f"(got {srate}).")

    streams, _ = load_xdf(fname)
    for stream in streams:
        if stream["info"]["stream_id"] == stream_id:
            break  # stream found
    else:  # stream not found
        raise IOError(f"Stream ID {stream_id} not found.")
    if float(stream["info"]["nominal_srate"][0]) == 0:
        raise RuntimeError("Importing a marker stream is not supported, try importing a "
                           "regularly sampled stream instead.")

    n_chans = int(stream["info"]["channel_count"][0])
    fs = float(np.array(stream["info"][f"{srate}_srate"]).item())
    labels, types, units = [], [], []
    try:
        for ch in stream["info"]["desc"][0]["channels"][0]["channel"]:
            labels.append(str(ch["label"][0]))
            if ch["type"]:
                types.append(ch["type"][0])
            units.append(ch["unit"][0] if ch["unit"] else "NA")
    except (TypeError, IndexError):  # no channel labels found
        pass
    if not labels:
        labels = [str(n) for n in range(n_chans)]
    if not units:
        units = ["NA" for _ in range(n_chans)]
    info = mne.create_info(ch_names=labels, sfreq=fs, ch_types="eeg")
    # convert from microvolts to volts if necessary
    scale = np.array([1e-6 if u in ("microvolt", "microvolts") else 1 for u in units])
    raw = mne.io.RawArray((stream["time_series"] * scale).T, info)
    raw._filenames = [fname]
    first_samp = stream["time_stamps"][0]
    markers = match_streaminfos(resolve_streams(fname), [{"type": "Markers"}])
    for stream_id in markers:
        for stream in streams:
            if stream["info"]["stream_id"] == stream_id:
                break
        onsets = stream["time_stamps"] - first_samp
        prefix = f"{stream_id}-" if prefix_markers else ""
        descriptions = [f"{prefix}{item}" for sub in stream["time_series"] for item in sub]
        raw.annotations.append(onsets, [0] * len(onsets), descriptions)
    return raw
Ejemplo n.º 23
0
# -*- coding: utf-8 -*-
import pyxdf  # Open xdf files
import matplotlib.pyplot as plt  # used for plotting
import numpy as np  # Numeric library for python

"""## Open the singnals data
The data recorded during the lab is in the xdf format. It is oppened with the pyxdf library, getting the data, and a header with metadata from the experiment. The data object contains one object for every stream recorded during the lab. In this case, threre are three streams: the biosignals, the markers for the biosignals (not used here) and the markers from psychopy.

We visualize the signals and markers here:
"""

data, header = pyxdf.load_xdf('./analysis/raw/000.xdf')

plt.figure(figsize=(30, 7))

# Read the biosignals from the first stream
stream = data[0]
y = stream['time_series']
fs = int(stream["info"]["nominal_srate"][0])  # Store sample frequency (fs)
plt.plot(stream["time_stamps"], y)
ecg, resp, gsr = np.split(y, [1, 2], axis=1)  # Store three biosignals
t = stream["time_stamps"]  # Extract time array

# Read the markers from the third stream
stream = data[2]
markers = {}  # A variable to store the markers
for marker, ts in zip(stream["time_series"], stream["time_stamps"]):
    plt.axvline(x=ts, c="red")
    markers[marker[0]] = ts
plt.xlabel("Time (s)")
plt.ylabel("Amplitude ($\mu$V)")
Ejemplo n.º 24
0
#          Tristan Stenner
#
# License: BSD (2-clause)

import os
import logging
import pyxdf
import sys


logging.basicConfig(level=logging.DEBUG)  # Use logging.INFO to reduce output.
if len(sys.argv) > 1:
    fname = sys.argv[1]
else:
    fname = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'xdf_sample.xdf'))
streams, fileheader = pyxdf.load_xdf(fname)

print("Found {} streams:".format(len(streams)))
for ix, stream in enumerate(streams):
    print("Stream {}: {} - type {} - uid {} - shape {} at {} Hz (effective {} Hz)".format(
        ix + 1, stream['info']['name'][0],
        stream['info']['type'][0],
        stream['info']['uid'][0],
        (int(stream['info']['channel_count'][0]), len(stream['time_stamps'])),
        stream['info']['nominal_srate'][0],
        stream['info']['effective_srate'])
    )
    if any(stream['time_stamps']):
        print("\tDuration: {} s".format(stream['time_stamps'][-1] - stream['time_stamps'][0]))
print("Done.")
Ejemplo n.º 25
0
import seaborn as sns
sns.set(font_scale=1)
import matplotlib.pyplot as plt

from utils.utils import get_stream_names, extract_signal_stream
from utils.utils import float_index_to_time_index, time_index_to_float_index
from utils.utils import estimate_rate
from utils.utils import pandas_to_mne

print("Config LOADED")

k_file = 0

raw_xdf_fname = Config.raw_files[k_file]
streams, _ = load_xdf(raw_xdf_fname)
stream_names = get_stream_names(streams)
df_eeg_raw = extract_signal_stream(streams, 'Android_EEG_010026')
df_presentation_events = extract_signal_stream(streams, 'Presentation_Markers')

print("RAW EEG LOADED")

eeg_columns = [
    'Fp1', 'Fp2', 'Fz', 'F7', 'F8', 'FC1', 'FC2', 'Cz', 'C3', 'C4', 'T7', 'T8',
    'CPz', 'CP1', 'CP2', 'CP5', 'CP6', 'TP9', 'TP10', 'Pz', 'P3', 'P4', 'O1',
    'O2'
]
df_eeg_raw = float_index_to_time_index(df_eeg_raw)

duration = (df_eeg_raw.index[-1] - df_eeg_raw.index[0]).total_seconds() / 60
rate = estimate_rate(df_eeg_raw)
def get_spec(fname):
    """
    https://github.com/mne-tools/mne-python/blob/master/examples/time_frequency/plot_compute_raw_data_spectrum.py
    ==================================================
    Compute the power spectral density of raw data
    ==================================================
    This script shows how to compute the power spectral density (PSD)
    of measurements on a raw dataset. It also show the effect of applying SSP
    to the data to reduce ECG and EOG artifacts.
    """
    # Authors: Alexandre Gramfort <*****@*****.**>
    #          Martin Luessi <*****@*****.**>
    #          Eric Larson <*****@*****.**>
    # License: BSD (3-clause)

    print(__doc__)

    ###############################################################################
    # Load data
    # ---------
    #
    # We'll load a sample MEG dataset, along with SSP projections that will
    # allow us to reduce EOG and ECG artifacts. For more information about
    # reducing artifacts, see the preprocessing section in :ref:`documentation`.

    ## follow https://mne.tools/mne-bids/stable/auto_examples/read_bids_datasets.html

    streams, fileheader = pyxdf.load_xdf(fname)
    for stream in streams:
        if stream['info']['name'] == ['Delsys']:
            emg = stream
            print('Delsys found')

    fmin, fmax = 1, 50  # look at frequencies between 1 and 50 Hz
    n_fft = 1024  # the FFT size (n_fft). Ideally a power of 2
    tmin, tmax = 60 * 1, 60 * 3  # use the first 60s of data

    ###############################################################################
    # Plot a cleaned PSD
    # ------------------
    #
    # Next we'll focus the visualization on a subset of channels.
    # This can be useful for identifying particularly noisy channels or
    # investigating how the power spectrum changes across channels.
    #
    # We'll visualize how this PSD changes after applying some standard
    # filtering techniques. We'll first apply the SSP projections, which is
    # accomplished with the ``proj=True`` kwarg. We'll then perform a notch filter
    # to remove particular frequency bands.

    # And now do the same with SSP + notch filtering
    # Pick all channels for notch since the SSP projection mixes channels together
    spectra, freqs = mne.time_frequency.psd_welch(emg['time_series'],
                                                  fmin=fmin,
                                                  fmax=fmax,
                                                  tmin=tmin,
                                                  tmax=tmax,
                                                  n_overlap=150,
                                                  n_fft=n_fft,
                                                  average='mean')

    spectra = spectra.mean(axis=0)

    return spectra, freqs
Ejemplo n.º 27
0
Tester_driverLicense = 0
Tester_sleepTime = 2407
Tester_testtime = 19

# 폴더 번호 설정
i = 0

# 데이터 저장 위치
Folder = 'C:\\Users\\ekdlw\\Desktop\\TEST\\Bio'
File_name = f'\\{Tester_sex}{Tester_age}{Tester_driverLicense}{Tester_sleepTime}{Tester_testtime}_{i}.csv'

# 데이터 저장 시간
Cutting_time = Frame_rate * Data_Save_time

data, header = pyxdf.load_xdf(
    'C:\\Users\\ekdlw\\Desktop\\TEST\\Bio\\sub-P002\\ses-S001\\eeg\\sub-P002_ses-S001_task-Default_run-001_eeg.xdf'
)

for stream in data:
    i = i + 1
    y = stream['time_series']
    x = stream['time_stamps']

    df1 = pd.DataFrame(y)
    df2 = pd.DataFrame(x)

    df1 = pd.concat([df1, df2], axis=1)

    File_name = f'\\{Tester_sex}{Tester_age}{Tester_driverLicense}{Tester_sleepTime}{Tester_testtime}_{i}.csv'
    df1.to_csv(Folder + File_name)
Ejemplo n.º 28
0
def pupil_rebuild_video(xdf_file: str, draw_gaze: bool = True) -> None:
    """
    Rebuilds the Pupil world video from the given XDF file (if the file contains data from the Pupil Capture LSL relay).
    @param xdf_file: Path to the XDF file.
    @param draw_gaze: Whether to draw marker for gaze data (if gaze data is available). Defaults to True.
    """
    g = GAZE_CIRCLE_RADIUS
    xdf_dir = os.path.dirname(xdf_file)
    data, header = pyxdf.load_xdf(xdf_file)

    # Loading video stream
    for stream in data:
        if stream['info']['name'][0] == 'pupil_capture_video':
            frames = stream['time_series']
            frames_ts = stream['time_stamps']
            video_path = stream['info']['desc'][0]['video_path'][0]
            fps = ((frames[-1] - frames[0]) / (frames_ts[-1] - frames_ts[0])).flat[0]
            break
    else:
        raise Exception("No Pupil video found in XDF data file")
    if draw_gaze:
        # Loading gaze stream
        for stream in data:
            if stream['info']['name'][0] == 'pupil_capture' and stream['info']['type'][0] == 'Gaze':
                gazes = stream['time_series']
                gazes_ts = stream['time_stamps']
                break
        else:
            raise Exception("No Pupil Gaze data found in XDF data file to draw gaze overlay")

    input_fn = os.path.join(xdf_dir, "inputs.txt")
    output_fn = os.path.join(xdf_dir, "pupil_scene_video.mp4")

    # Writing concat file for FFmpeg
    with open(input_fn, "w+") as f:
        for frame, timestamp in zip(frames, frames_ts):
            base_fp = os.path.join(video_path, str(frame.flat[0]))
            fp = base_fp + ".jpg"
            if draw_gaze:
                # Finding closest gaze data to frame
                idx = (np.abs(gazes_ts - timestamp)).argmin()
                gaze = gazes[idx].flat
                # Get its gaze coords
                norm_x, norm_y = gaze[1], gaze[2]
                img = Image.open(fp)
                w, h = img.size
                # Scale coords to image
                x = norm_x * w
                y = (1 - norm_y) * h
                # Draw circle
                draw = ImageDraw.Draw(img)
                gaze_box = (x - g, y - g, x + g, y + g)
                draw.ellipse(gaze_box, outline='red', width=GAZE_CIRCLE_WIDTH)
                # Save new image
                fp = base_fp + "_gaze.jpg"
                img.save(fp)
            # FFmpeg wants forward slashes
            fp = fp.replace('\\', '/')
            f.write(f"file '{fp}'\n")

    (
        ffmpeg
        .input(input_fn, format='concat', safe=0)
        .filter('fps', fps=fps, round='up')
        .output(output_fn, vcodec="mjpeg", **{'q:v': '2'})
        .overwrite_output()
        .run()
    )

    os.remove(input_fn)
import pandas as pd
import numpy as np
import pyxdf
import cv2

if __name__ == '__main__':

    df = pd.read_csv('./UI08-T1-video_left_color_ts.txt', sep=',')

    df['ts'] = df['ts'] / 1e9

    data, header = pyxdf.load_xdf('./EX1U08_S01_T01_pegNormal_raw.xdf')
    # Get data and experiment markers
    for stream in data:
        if stream['info']['name'][0] == 'ExperimentMarkers':
            markers = stream['time_series']
            markersTime = stream['time_stamps']
        elif stream['info']['name'][0] == 'NB-2015.10.15' or stream['info'][
                'name'][0] == 'NB-2015.10.16':
            if stream['footer']['info']['first_timestamp'][0] != '0':
                eegData = stream['time_series']
                eegInfo = stream['info']
                eegTime = stream['time_stamps']

    start_time = float(markers[0][1])
    end_time = float(markers[1][1])

    df = df.loc[(df['ts'] > start_time) & (df['ts'] < end_time)]
    x = 0
    start_frame = df['idx'].values[0]
    end_frame = df['idx'].values[-1]
Ejemplo n.º 30
0
    def __init__(self, file, min_chunk_size=4):
        Node.__init__(self, None)

        filename, self._file_extension = os.path.splitext(file)
        self._events = []
        if self._file_extension in ['.gdf', '.set', '.vhdr']:
            if self._file_extension == '.gdf':
                self._raw = read_raw_gdf(file)
            elif self._file_extension == '.set':
                self._raw = read_raw_eeglab(file)
            elif self._file_extension == '.vhdr':
                self._raw = read_raw_brainvision(file)
            self._sampling_frequency = self._raw.info['sfreq']
            self._channels = self._raw.info.ch_names
            try:
                # to test
                events = find_events(self._raw)
                logging.debug('Get from find_events')
            except ValueError:
                events = events_from_annotations(self._raw)
                logging.debug('Get from events_from_annotations')
            nb_to_event = {events[1][key]: key for key in events[1]}
            for h in events[0]:
                try:
                    value = float(nb_to_event[h[2]])
                except ValueError:
                    value = nb_to_event[h[2]]
                self._events.append((h[0] / 1000, value))
            self._end_record = self._raw.times[-1]
            self._start_record = self._raw.times[0]
        elif self._file_extension == '.xdf':
            streams, header = pyxdf.load_xdf(file,
                                             synchronize_clocks=False,
                                             verbose=False)
            logging.info(f'Found {len(streams)} streams in xdf file')
            for ix, stream in enumerate(streams):
                sampling_frequency = float(stream['info']['nominal_srate'][0])
                if sampling_frequency == 0:
                    logging.debug(f'Get marker from stream {ix}')
                    for timestamp, event in zip(stream['time_stamps'],
                                                stream['time_series']):
                        self._events.append((timestamp, float(event)))
                else:
                    logging.debug(f'Get data from stream {ix}')
                    self._sampling_frequency = sampling_frequency
                    nb_chan = int(stream['info']['channel_count'][0])
                    self._channels = [(stream['info']['desc'][0]['channels'][0]
                                       ['channel'][i]['label'][0])
                                      for i in range(nb_chan)]
                    self._df = pd.DataFrame(stream['time_series'],
                                            stream['time_stamps'],
                                            self._channels)
                    self._start_record = stream['time_stamps'][0]
                    self._end_record = stream['time_stamps'][-1]

        self.marker_output = Port()

        self.marker_output.set_parameters(data_type='marker',
                                          channels=['marker'],
                                          sampling_frequency=0,
                                          meta='')

        self.output.set_parameters(data_type='signal',
                                   channels=self._channels,
                                   sampling_frequency=self._sampling_frequency,
                                   meta='')

        Node.log_instance(
            self, {
                'marquers output': self.marker_output.id,
                'sampling frequency': self._sampling_frequency,
                'channels': self._channels,
                'min chunk size': min_chunk_size,
                'from file': file
            })

        self._last_t = None
        self._min_period = min_chunk_size / self._sampling_frequency
        self._start_time = None
        self._flag = True