Giter VIP home page Giter VIP logo

pyliesl's Introduction

Reiz

pyReiz is a low-level auditory and visual stimulus presentation suite wrapping pyglet, sending markers via a pylsl outlet. You can also read more extensive documentation online.

DOI MIT license PyPI version Build Status Coverage Status Documentation Status

basic-example

Installation

The requirements for pyReiz are pyglet and pylsl. They are checked, and if necessary installed, during pip install. There is also a dependency on pyttsx3 to allow on-demand synthesis of auditory cues from text. If you don't need that or can't acquire a version of pyttsx3 for your architecture, install pyreiz without the [tts] suffix.

Windows

pip install Reiz[tts]

Linux

The most recent version of pylsl is not yet on pypi. A solution is to install libsl manually. You download a recent build of liblsl from https://github.com/sccn/liblsl/releases. Afterwards, install pylsl directly from github.

pip install git+https://github.com/labstreaminglayer/liblsl-Python.git
pip install Reiz[tts]

Mac

On Mac, tts and reiz-marker are not supported. These functionalities will be mocked, so at least, you can develop on Mac to deploy on Linux or Windows.

pip install Reiz

Development

git clone https://github.com/pyreiz/pyreiz.git
cd pyreiz
pip install -e .[tts]

Test your installation

After you installed Reiz, you can give it a test-run by calling python -m reiz.examples.basic from your terminal. This should start a throwaway MarkerServer, and present a series of visual and auditory stimuli. If anything does not work out, inform us of the issue.

Additional Information

Create your own experiment

Examples can be found in reiz/examples. A quite extensively documented basic example can be found here: basic example.

Recording

Because all markers are send via LSL, i suggest recording with Labrecorder. Use at least 1.13, as this version supports BIDS-conform recording, offers a remote interface and has a critical timing bugfix included.

Requirements

The key requirements for pyReiz are pyglet and pylsl. We require pylsl>=1.13 because a timing issue was fixed in that version (see sccn/liblsl#8), and pyglet>1.4 because there was a breaking change between 1.3 and 1.4 in the way audio was generated and played (see #2). For text-to-speech, which is included with [tts], a key requirement is pyttsx3.

Acknowledgments

I adapted code from Cocos2d for generation of some openGL primitives.

pyliesl's People

Contributors

agricolab avatar jasmainak avatar moan0s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pyliesl's Issues

FileNotFoundError with labrecorder on MacOS

I installed the labrecorder on MacOS and did the following:

import liesl

recorder = liesl.Recorder(
    path_to_cmd='/usr/local/opt/labrecorder/LabRecorder/LabRecorder.app/Contents/MacOS/LabRecorder')

but I get the following:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
~/Documents/github_repos/neurobooth-os/examples/record_using_lisel.py in <module>
     41 subject = "demo_subject"
     42 
---> 43 recorder = liesl.Recorder(
     44     '/usr/local/opt/labrecorder/LabRecorder/LabRecorder.app/Contents/MacOS/LabRecorder')
     45 session = liesl.Session(prefix=subject,

~/anaconda3/envs/neurobooth/lib/python3.8/site-packages/liesl/files/labrecorder/cli_wrapper.py in __init__(self, path_to_cmd)
     77     def __init__(self, path_to_cmd: str = None) -> None:
     78         self.streamargs = None
---> 79         self.cmd = find_lrcmd(path_to_cmd)
     80 
     81     def bind(self, streamargs: List[dict,] = [None]) -> None:

~/anaconda3/envs/neurobooth/lib/python3.8/site-packages/liesl/files/labrecorder/cli_wrapper.py in find_lrcmd(path_to_cmd)
     48 
     49     # if nothing worked, we end here
---> 50     raise FileNotFoundError("No valid path to LabRecorder")
     51 
     52 

FileNotFoundError: No valid path to LabRecorder

It looks like the path_to_cmd is ignored for MacOS. Is there a possibility to support this option? Thank you!

Pip install fails

I tried to install liesl on my Ubuntu 19.10 With Intel Intel® Core™ i7-3610QM CPU (64 bit)

$ pip install liesl
Collecting liesl
  Using cached https://files.pythonhosted.org/packages/16/a9/57ad1dc14b75caccffdf0cae77f9780c961a05f9c3f5e71a1548e81670f5/liesl-0.3.4.3.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-OwKjpQ/liesl/setup.py", line 4, in <module>
        with (Path(__file__).parent / "readme.md").open() as f:
      File "/home/juli/.local/lib/python2.7/site-packages/pathlib.py", line 1077, in open
        return io.open(str(self), mode, buffering, encoding, errors, newline)
    IOError: [Errno 2] No such file or directory: '/tmp/pip-install-OwKjpQ/liesl/readme.md'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-OwKjpQ/liesl/

Stream with one channel fails loading

For any stream with only one channel, liesl fails loading this stream.
Calling streams = XDFFile(xdffile) with a file that has such a stream in it fails at the function

def channel_labels(self) -> Union[List[str], None]:
        "get the channel labels as a list of strings"
        if self.desc is not None:
            return [i["label"] for i in self.desc["channels"]["channel"]]
        else:
            return None

when e.g.
self.desc["channels"]["channel"] = {'label': 'Force', 'unit': 'N', 'type': 'vernier'}
A working stream has the format
[{'label': 'Fp1', 'type': 'EEG', 'unit': 'microvolts'}, {'label': 'Fp2', 'type': 'EEG', 'unit': 'microvolts'}]

Solution could be

def channel_labels(self) -> Union[List[str], None]:
        "get the channel labels as a list of strings"
        if self.desc is not None:
            try:
                return [i["label"] for i in self.desc["channels"]["channel"]]
            except TypeError:
                return [self.desc["channels"]["channel"]['label']]
        else:
            return None

LabRecorderCLI wrapper records streams multiple times on Linux

When only a single stream is recorded, everything works fine. When two streams are selected for recording, they are recorded into the xdf twice.

Induce

Prepare two mock streams with

liesl mock
liesl mock --type Marker

start a python session and run

from liesl.api import Recorder
import time
r = Recorder
r.bind([{"type":"EEG"},{"type":"Marker"}])
r.start_recording()
time.sleep(3)
r.stop_recording()

inspect the file from the terminal with

liesl xdf recording_R001.xdf

returns on Win10 with Python 3,.9.1:

Loading recording_R001.xdf concisely

Name                             Type        Ch   Fs                      Source
--------------------------------------------------------------------------------
Liesl-Mock-EEG                   EEG         8   1000.0               84932102909
Liesl-Mock-Marker               Marker       1    0.0               118257554116

but on Linux Mint with Python 3.7.6

Loading recording_R001.xdf concisely

Name                             Type        Ch   Fs                      Source
--------------------------------------------------------------------------------
Liesl-Mock-Marker               Marker       1   0.000000000000000             8744283295937
Liesl-Mock-Marker               Marker       1   0.000000000000000             8744283295937
Liesl-Mock-EEG                   EEG         8   1000.000000000000             8729561856449
Liesl-Mock-EEG                   EEG         8   1000.000000000000             8729561856449

Problem with dejittering time stamps

During loading, pyxdf.load_xdf automatically tries to dejitter the timestamps. This requires a linear regression on the measured timestamps. This step apparently failed.
Error message:
Error reading chunk length
Traceback (most recent call last):
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/pyxdf/pyxdf.py", line 237, in load_xdf
chunklen = _read_varlen_int(f)
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/pyxdf/pyxdf.py", line 487, in _read_varlen_int
raise RuntimeError("invalid variable-length integer encountered.")
RuntimeError: invalid variable-length integer encountered.
got zero-length chunk, scanning forward to next boundary chunk.

Intel MKL ERROR: Parameter 6 was incorrect on entry to DGELSD.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/liesl/files/xdf/load.py", line 147, in XDFFile
streams, _ = pyxdf.load_xdf(filename=str(filename))
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/pyxdf/pyxdf.py", line 377, in load_xdf
temp = _jitter_removal(
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/pyxdf/pyxdf.py", line 661, in _jitter_removal
mapping = np.linalg.lstsq(X, y, rcond=-1)[0]
File "<**array_function** internals>", line 5, in lstsq
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 2306, in lstsq
x, resids, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj)
File "/home/tianlu/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 100, in _raise_linalgerror_lstsq
raise LinAlgError("SVD did not converge in Linear Least Squares")
numpy.linalg.LinAlgError: SVD did not converge in Linear Least Squares

Loading the file with pyxdf.load_xdf(filename=str(filename), dejitter_timestamps=False) works.

Thanks Robert! 😄

[bug] Dependency on specific liblsl version

After installing liblsl and trying to run liesl I get the following error. I suspect that the LabRecorder contained here somehow depends on a specific lsl version?

ConnectionError: b'/home/moanos/software/record-neon/venv/lib/python3.11/site-packages/liesl/files/labrecorder/lib/LabRecorderCLI: error while loading shared libraries: liblsl64.so.1.13.0: cannot open shared object file: No such file or directory\n'

A very dirty workaround is to do

sudo cp /usr/lib/liblsl.so /usr/lib/liblsl64.so.1.13.0

This can mess up your system, do not try unless you exacly know what you are doing

I tested on Ubuntu via provided deb file and arch via the AUR package.

cli_wrapper streams selected multiple times error [via email]

Wir nutzen den cli_wrapper schon seit einiger Zeit sehr erfolgreich in diversen Studien. Dabei nutzen wir einen raspberry pi zum aufzeichnen unterschiedlicher LSL-Streams (meist ein Marker, ein Audio und ein EEG stream parallel) unter Linux. [...] Heute wollte ich einen Marker-, und zwei EEG-LSL-Streams gleichzeitig aufzeichnen um einen Verstärkervergleich durchzuführen. Obwohl die EEG-Streams unterschiedliche Namen besitzen erhalte ich folgende Fehlermeldung: "Some streams were selected multible times". Ist dies ein Bug? Wenn ich die Streams manuell initialisiere und dabei den Typ der Streams in EEG1 und EEG2 ändere erscheint dieser Fehler nicht. Wir würden dennoch gern die Möglichkeit besitzen, mit unserer Aufnahme-Box auch auch EEG-LSL-Streams aufnehme zu können, die mit der Smarting-Streemer-Software erstellt wurden. Diese ermöglicht es leider nur die Namen der Streams zu definieren. Der Typ ist dann immer "EEG".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.