Git Product home page Git Product logo

pylsl's Introduction

pylsl

publish workflow PyPI version

This is the Python interface to the Lab Streaming Layer (LSL). LSL is an overlay network for real-time exchange of time series between applications, most often used in research environments. LSL has clients for many other languages and platforms that are compatible with each other.

Let us know if you encounter any bugs (ideally using the issue tracker on the GitHub project).

Installation

Prerequisites

On all non-Windows platforms and for some Windows-Python combinations, you must first obtain a liblsl shared library. See the liblsl repo documentation for further details.

Get pylsl from PyPI

  • pip install pylsl

Get pylsl from source

This should only be necessary if you need to modify or debug pylsl.

  • Download the pylsl source: git clone https://github.com/labstreaminglayer/pylsl.git && cd pylsl
  • From the pylsl working directory, run pip install ..
    • Note: You can use pip install -e . to install while keeping the files in-place. This is convenient for developing pylsl.

Usage

See the examples in pylsl/examples. Note that these can be run directly from the commandline with (e.g.) python -m pylsl.examples.{name-of-example}.

You can get a list of the examples with python -c "import pylsl.examples; help(pylsl.examples)"

liblsl loading

pylsl will search for liblsl first at the filepath specified by an environment variable named PYLSL_LIB, then in the package directory (default location for Windows), then finally in normal system library folders.

If the shared object is not installed onto a standard search path (or it is but can't be found for some other bug), then we recommend that you copy it to the pylsl installed module path's lib subfolder. i.e. {path/to/env/}site-packages/pylsl/lib.

  • The site-packages/pylsl path will only exist after you install pylsl in your Python environment.
  • You may have to create the lib subfolder.
  • Use python -m site to find the "site-packages" path.
  • Use cp -L on platforms that use symlinks.

Alternatively, you can use an environment variable. Set the PYLSL_LIB environment variable to the location of the library or set LD_LIBRARY_PATH to the folder containing the library. For example,

  1. PYLSL_LIB=/usr/local/lib/liblsl.so python -m pylsl.examples.{name-of-example}, or
  2. LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python -m pylsl.examples.{name-of-example}

For maintainers

Continuous Integration

pylsl uses continuous integration and distribution. GitHub Actions will upload a new release to pypi whenever a Release is created in GitHub. Before creating the GitHub release, be sure to bump the version number in pylsl/version.py and consider updating the liblsl dependency in .github/workflows/publish-to-pypi.yml.

Linux Binaries Deprecated

We recently stopped building binary wheels for Linux. In practice, the manylinux dependencies were often incompatible with real systems.

Manual Distribution

  1. Manual way:
    1. rm -Rf build dist *.egg-info
    2. python setup.py sdist bdist_wheel
    3. Additional steps on Linux:
      • auditwheel repair dist/*.whl -w dist
      • rm dist/*-linux_x86_64.whl
    4. twine upload dist/*
  2. For conda
    1. build liblsl: conda build ../liblsl/
    2. conda build .

Known Issues with Multithreading on Linux

  • At least for some versions of pylsl, it has been reported that running on Linux one cannot call pylsl functions from a thread that is not the main thread. This has been reported to cause access violations, and can occur during pulling from an inlet, and also from accessing an inlets info structure in a thread.
  • Recent tests with multithreading (especially when safeguarding library calls with locks) using Python 3.7.6. with pylsl 1.14 on Linux Mint 20 suggest that this issue is solved, or at least depends on your machine. See #29

Acknowledgments

Pylsl was primarily written by Christian Kothe while at Swartz Center for Computational Neuroscience, UCSD. The LSL project was funded by the Army Research Laboratory under Cooperative Agreement Number W911NF-10-2-0022 as well as through NINDS grant 3R01NS047293-06S1. pylsl is maintained primarily by Chadwick Boulay. Thanks for contributions, bug reports, and suggestions go to Bastian Venthur, David Medine, Clemens Brunner, and Matthew Grivich.

pylsl's People

Contributors

agricolab avatar cboulay avatar charlesbmi avatar chkothe avatar dmedine avatar florin-pop avatar kyucrane avatar mscheltienne avatar schnoy avatar stfnrpplngr avatar tstenner avatar xloem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pylsl's Issues

Time Synchronization Issue

Hello guys!

I am currently using the Pylsl interface for sending event markers to an EEG signal, being acquired by the Enobio 8 headset, using their proprietary NIC software, as is recommended (instead of sending markers by TCP), as we need to analyze ERPs.

The experiment itself was designed using PsychoPy, with the Python code being generated using the standalone version, and then the Pylsl library was added to the generated code.

In a (possibly) unrelated note, I needed to delete the importing of the GUI module, as it seemed to be incompatible with the Pylsl interface (no events would be sent to the signal if it was used).

However, when I tried to test the latency of the event marking in the signal, I verified that the events always appeared earlier in the signal, than what the timestamp in python was at the time - basically, I got the python timestamp using:

int(round(datetime.datetime.now( ).timestamp( ) * 1000))

which was always ahead of the signals' timestamp. The difference in time was also not consistent, sometimes being 6 ms, and at others upwards of 30 ms (and always rising from the start of the experiment), which would render me unable to check for ERPs properly.

I'm using Python 3.6.4 from the Anaconda distribution, on macOS Sierra 10.12.6, and the Python timestamp is being calculated both immediately before and immediately after the push_sample, being the same in most situations.

Thanks in advance,

Igor Rodrigues

Improve findability in github search

I just found out that a search in github for pylsl does not show this repo. This is likely because neither title nor description contain this term. Github looks also into the description when searching. Adding pylsland possibly also labstreaminglayer and LSL to the description would therefore probably solve this issue. Another option are adding topics, they are searchable with hashtags.

Having problems which I never encountered before. Please help.

Traceback (most recent call last):
  File "1.py", line 1, in <module>
    import pylsl
  File "C:\Users\rakes\anaconda3\lib\site-packages\pylsl\__init__.py", line 2, in <module>
    from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,\
  File "C:\Users\rakes\anaconda3\lib\site-packages\pylsl\pylsl.py", line 1217, in <module>
    lib = CDLL(libpath)
  File "C:\Users\rakes\anaconda3\lib\ctypes\__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\rakes\anaconda3\lib\site-packages\pylsl\lib\liblsl64.dll' (or one of its dependencies). Try using the full path with constructor syntax.

[Question] Send and Receive Stream on same computer?

Hi, I am working on building LSL for MNE-Python and I am doing some local testing. I was wondering if it is possible to both create a stream and read from the stream from the same computer. Currently I am creating a mock stream using the example and I am trying to consume it in another Python instance.

BUG: Weird interaction with other modules

This bit of code is adapted from two pylsl examples and just starts one thread to send samples and receives them in the main thread, works on Linux (Ubuntu 20.10, pip) as it correctly starts printing a bunch of random samples:

import time
from multiprocessing import Process
from random import random as rand

from pylsl import StreamInfo, StreamOutlet, local_clock, resolve_stream, StreamInlet
import scipy.fft


def _send():
    info = StreamInfo('BioSemi', 'EEG', 8, 100, 'float32', 'myuid34234')
    outlet = StreamOutlet(info)
    start_time = local_clock()
    sent_samples = 0
    while True:
        elapsed_time = local_clock() - start_time
        required_samples = int(100 * elapsed_time) - sent_samples
        for sample_ix in range(required_samples):
            # make a new random n_channels sample; this is converted into a
            # pylsl.vectorf (the data type that is expected by push_sample)
            mysample = [rand() for _ in range(8)]
            # now send it
            outlet.push_sample(mysample)
        sent_samples += required_samples
        # now send it and wait for a bit before trying again.
        time.sleep(0.01)


print('Starting serving process')
process = Process(target=_send, daemon=True)
process.start()

print("looking for an EEG stream...")
streams = resolve_stream('type', 'EEG')
inlet = StreamInlet(streams[0])
while True:
    sample, timestamp = inlet.pull_sample()
    print(timestamp, sample)

However, if I move the import scipy.fft to before the pylsl import, things break. The stream is never found and it just hangs on the resolve_stream step. I narrowed the from scipy import fft issue down to it being due to an import of scipy.fft._pocketfft.pypocketfft, which is a pybind11-compiled module. (I can also experience it when other modules are imported in that same spot in the script, so I don't think it's specific to SciPy, though.)

This is on Linux, where I noticed there is a known issue that multiple threads are not supported. Is this what is meant by "not supported" in that it might work in some situations but not others depending on the import order? If so, is it expected that the conda-forge version will not have this problem, or is it some fundamental limitation? Also I'm not sure if this is related to #6 / #5 or not.

The above example is a minimized version of how we unit test and build docs for MNE-Realtime, hence my interest in it being fixed if at all possible.

More configuration options for liblsl library resolution

Tangentially related to #6, I'd like an option to load either a specific library (as absolute path, e.g. /foo/bar/liblsl.so, a libname to be resolved by the system linker / in LD_LIBRARY_PATH (e.g. lsl or lsl64) or the standard behavior (look for an included liblsl).

The option could then be either set as environment variable (like MPLBACKEND for matplotlib) or as constant before loading pylsl (PYLSL_LIB='/foo/liblsl.so'; import pylsl).

Problem importing pylsl in Windows 10 (Python-3.8.5)

Hello, I'm trying to do some tests combining pygame and pylsl using Windows 10 for some simple neurofeedback demos.

I'm using Python 3.8.5

Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32

I installed pylsl using pip version 20.2.1 ( python3 -m pip install pylsl ). This seems to install pylsl successfully:

Name: pylsl
Version: 1.13.6
Summary: Python interface to the Lab Streaming Layer
Home-page: https://github.com/labstreaminglayer/liblsl-Python
Author: Christian Kothe
Author-email: [email protected]
License: MIT
Location: c:\users\gganis\python38-32\lib\site-packages
Requires:
Required-by:

However, when I try to import pylsl within the Python3 shell I get this error:

Traceback (most recent call last):
File "", line 1, in
File "C:\Users\gganis\Python38-32\lib\site-packages\pylsl_init_.py", line 2, in
from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,
File "C:\Users\gganis\Python38-32\lib\site-packages\pylsl\pylsl.py", line 1222, in
lib.lsl_library_info.restype = c_char_p
File "C:\Users\gganis\Python38-32\lib\ctypes_init_.py", line 386, in getattr
func = self.getitem(name)
File "C:\Users\gganis\Python38-32\lib\ctypes_init_.py", line 391, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'lsl_library_info' not found

Any thoughts on what might be off? Thanks.

LSL and PyInstaller

Hi, I was trying to pack a small executable with PyInstaller on a small anaconda environment using few packages, pylsl among them. The script works fine if launched via terminal, but once packed in a .exe, I encounter this error.

Have you ever experienced an issue of this kind?

PerformanceTest is incompatible with PyQtGraph 0.11

Almost all examples run without issues (after i pip install pyqtgraph) but python PerformanceTest.py fails with

Created outlet with name BetaGen and type EEG
Created outlet with name GeneratedCentreOutMarkers and type Markers
looking for an EEG stream...
Reading from inlet named BetaGen with channels ['RAW1', 'SPK1', 'RAW2', 'SPK2', 'RAW3', 'SPK3'] sending data at 16384.0 Hz
Looking for stream with type Markers
Reading from inlet named GeneratedCentreOutMarkers with channels ['EventMarkers']
Traceback (most recent call last):
  File "PerformanceTest.py", line 308, in <module>
    qwindow.parent().setWindowTitle("pylsl PerformanceTest")
AttributeError: 'NoneType' object has no attribute 'setWindowTitle'

Edit:
But i get the same error in master (l300), so it must be sth else than your changes. pyqtgraph==0.11.0

Originally posted by @agricolab in #33 (comment)

crash with sklearn on my system

This happens only when pylsl is imported first:

>>> import pylsl
>>> import sklearn
*** Error in `python3': free(): invalid pointer: 0x00007f6446a63bc0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81299)[0x7f645fb39299]
/lib64/libstdc++.so.6(_ZNSt6locale5_Impl16_M_install_facetEPKNS_2idEPKNS_5facetE+0x142)[0x7f64467cded2]
/lib64/libstdc++.so.6(_ZNSt6locale5_ImplC1Em+0x1e3)[0x7f64467ce323]
/lib64/libstdc++.so.6(+0x71295)[0x7f64467cf295]
/lib64/libpthread.so.0(+0x620b)[0x7f646059520b]
/lib64/libstdc++.so.6(+0x712e1)[0x7f64467cf2e1]
/lib64/libstdc++.so.6(_ZNSt6localeC2Ev+0x13)[0x7f64467cf323]
/lib64/libstdc++.so.6(_ZNSt8ios_base4InitC2Ev+0xbc)[0x7f64467cc17c]
/home/user/.local/lib/python3.8/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-38-x86_64-linux-gnu.so(+0x77f0)[0x7f64464ae7f0]
/lib64/ld-linux-x86-64.so.2(+0xf9c3)[0x7f64610499c3]
/lib64/ld-linux-x86-64.so.2(+0x1459e)[0x7f646104e59e]
/lib64/ld-linux-x86-64.so.2(+0xf7d4)[0x7f64610497d4]
/lib64/ld-linux-x86-64.so.2(+0x13b8b)[0x7f646104db8b]
/lib64/libdl.so.2(+0xfab)[0x7f646038bfab]
/lib64/ld-linux-x86-64.so.2(+0xf7d4)[0x7f64610497d4]
/lib64/libdl.so.2(+0x15ad)[0x7f646038c5ad]
/lib64/libdl.so.2(dlopen+0x31)[0x7f646038c041]
/usr/local/lib/libpython3.8.so.1.0(_PyImport_FindSharedFuncptr+0x183)[0x7f6460c7d573]
/usr/local/lib/libpython3.8.so.1.0(_PyImport_LoadDynamicModuleWithSpec+0x2ae)[0x7f6460c344ae]
/usr/local/lib/libpython3.8.so.1.0(+0x24fb81)[0x7f6460c31b81]
/usr/local/lib/libpython3.8.so.1.0(+0x112e13)[0x7f6460af4e13]
/usr/local/lib/libpython3.8.so.1.0(PyVectorcall_Call+0x5d)[0x7f6460a961bd]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xa630)[0x7f6460a59860]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x13ab)[0x7f6460c02c4b]
/usr/local/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x15f)[0x7f6460a9386f]                                                                                                      [85/118]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xa925)[0x7f6460a59b55]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x9023)[0x7f6460a58253]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x889a)[0x7f6460a57aca]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x889a)[0x7f6460a57aca]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x889a)[0x7f6460a57aca]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(+0xb22bc)[0x7f6460a942bc]
/usr/local/lib/libpython3.8.so.1.0(_PyObject_CallMethodIdObjArgs+0x10f)[0x7f6460a9452f]
/usr/local/lib/libpython3.8.so.1.0(PyImport_ImportModuleLevelObject+0x4ff)[0x7f6460c32f1f]
/usr/local/lib/libpython3.8.so.1.0(+0x21ad2f)[0x7f6460bfcd2f]
/usr/local/lib/libpython3.8.so.1.0(PyCFunction_Call+0x147)[0x7f6460a963b7]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xa630)[0x7f6460a59860]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x13ab)[0x7f6460c02c4b]
/usr/local/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x15f)[0x7f6460a9386f]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x889a)[0x7f6460a57aca]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x13ab)[0x7f6460c02c4b]
/usr/local/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x15f)[0x7f6460a9386f]
/usr/local/lib/libpython3.8.so.1.0(+0xb22bc)[0x7f6460a942bc]
/usr/local/lib/libpython3.8.so.1.0(_PyObject_CallMethodIdObjArgs+0x10f)[0x7f6460a9452f]
/usr/local/lib/libpython3.8.so.1.0(PyImport_ImportModuleLevelObject+0x62c)[0x7f6460c3304c]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xb500)[0x7f6460a5a730]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x13ab)[0x7f6460c02c4b]
/usr/local/lib/libpython3.8.so.1.0(PyEval_EvalCodeEx+0x93)[0x7f6460c033c3]
/usr/local/lib/libpython3.8.so.1.0(PyEval_EvalCode+0x3b)[0x7f6460c0340b]
/usr/local/lib/libpython3.8.so.1.0(+0x21bbb2)[0x7f6460bfdbb2]
/usr/local/lib/libpython3.8.so.1.0(+0x112e13)[0x7f6460af4e13]
/usr/local/lib/libpython3.8.so.1.0(PyVectorcall_Call+0x5d)[0x7f6460a961bd]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xa630)[0x7f6460a59860]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x13ab)[0x7f6460c02c4b]                                                                                                   [52/118]
/usr/local/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x15f)[0x7f6460a9386f]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0xa925)[0x7f6460a59b55]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
/usr/local/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x9023)[0x7f6460a58253]
/usr/local/lib/libpython3.8.so.1.0(+0x6c0a1)[0x7f6460a4e0a1]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:02 402913258                          /usr/local/bin/python3.8
00600000-00601000 r--p 00000000 fd:02 402913258                          /usr/local/bin/python3.8
00601000-00602000 rw-p 00001000 fd:02 402913258                          /usr/local/bin/python3.8
012ad000-017f2000 rw-p 00000000 00:00 0                                  [heap]
7f6440000000-7f6440021000 rw-p 00000000 00:00 0 
7f6440021000-7f6444000000 ---p 00000000 00:00 0 
7f64464a7000-7f6446559000 r-xp 00000000 fd:02 432834388                  /home/user/.local/lib/python3.8/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-38-x86_64-linux-gnu.so
7f6446559000-7f6446758000 ---p 000b2000 fd:02 432834388                  /home/user/.local/lib/python3.8/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-38-x86_64-linux-gnu.so
7f6446758000-7f644675a000 rw-p 000b1000 fd:02 432834388                  /home/user/.local/lib/python3.8/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-38-x86_64-linux-gnu.so
7f644675a000-7f644675e000 rw-p 00000000 00:00 0 
7f644675e000-7f6446847000 r-xp 00000000 fd:02 76539                      /usr/lib64/libstdc++.so.6.0.19
7f6446847000-7f6446a46000 ---p 000e9000 fd:02 76539                      /usr/lib64/libstdc++.so.6.0.19
7f6446a46000-7f6446a4e000 r--p 000e8000 fd:02 76539                      /usr/lib64/libstdc++.so.6.0.19
7f6446a4e000-7f6446a50000 rw-p 000f0000 fd:02 76539                      /usr/lib64/libstdc++.so.6.0.19
7f6446a50000-7f6446a65000 rw-p 00000000 00:00 0 
7f6446aae000-7f6446ab7000 r-xp 00000000 fd:02 142071259                  /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_uarray/_uarray.cpython-38-x86_64-linux-gnu.so
7f6446ab7000-7f6446cb7000 ---p 00009000 fd:02 142071259                  /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_uarray/_uarray.cpython-38-x86_64-linux-gnu.so
7f6446cb7000-7f6446cb8000 rw-p 00009000 fd:02 142071259                  /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_uarray/_uarray.cpython-38-x86_64-linux-gnu.so
7f6446cb8000-7f6446cf8000 rw-p 00000000 00:00 0 
7f6446cf8000-7f6446d06000 r-xp 00000000 fd:02 36621292                   /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_ccallback_c.cpython-38-x86_64-linux-gnu.so
7f6446d06000-7f6446f06000 ---p 0000e000 fd:02 36621292                   /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_ccallback_c.cpython-38-x86_64-linux-gnu.so
7f6446f06000-7f6446f08000 rw-p 0000e000 fd:02 36621292                   /home/user/.local/lib/python3.8/site-packages/scipy/_lib/_ccallback_c.cpython-38-x86_64-linux-gnu.so
7f6446f08000-7f6446fc8000 rw-p 00000000 00:00 0 
7f6446fc8000-7f6447064000 r-xp 00000000 fd:02 1190750                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_generator.cpython-38-x86_64-linux-gnu.so
7f6447064000-7f6447264000 ---p 0009c000 fd:02 1190750                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_generator.cpython-38-x86_64-linux-gnu.so
7f6447264000-7f6447288000 rw-p 0009c000 fd:02 1190750                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_generator.cpython-38-x86_64-linux-gnu.so
7f6447288000-7f644728b000 rw-p 00000000 00:00 0                                                                                                                                       [19/118]
7f644728b000-7f6447296000 r-xp 00000000 fd:02 1190744                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_sfc64.cpython-38-x86_64-linux-gnu.so
7f6447296000-7f6447496000 ---p 0000b000 fd:02 1190744                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_sfc64.cpython-38-x86_64-linux-gnu.so
7f6447496000-7f6447497000 rw-p 0000b000 fd:02 1190744                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_sfc64.cpython-38-x86_64-linux-gnu.so
7f6447497000-7f6447498000 rw-p 00000000 00:00 0 
7f6447498000-7f64474a7000 r-xp 00000000 fd:02 1190743                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_pcg64.cpython-38-x86_64-linux-gnu.so
7f64474a7000-7f64476a7000 ---p 0000f000 fd:02 1190743                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_pcg64.cpython-38-x86_64-linux-gnu.so
7f64476a7000-7f64476a9000 rw-p 0000f000 fd:02 1190743                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_pcg64.cpython-38-x86_64-linux-gnu.so
7f64476a9000-7f64476bb000 r-xp 00000000 fd:02 1190753                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_philox.cpython-38-x86_64-linux-gnu.so
7f64476bb000-7f64478ba000 ---p 00012000 fd:02 1190753                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_philox.cpython-38-x86_64-linux-gnu.so
7f64478ba000-7f64478bc000 rw-p 00011000 fd:02 1190753                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_philox.cpython-38-x86_64-linux-gnu.so
7f64478bc000-7f64478bd000 rw-p 00000000 00:00 0 
7f64478bd000-7f64478d5000 r-xp 00000000 fd:02 1190756                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_mt19937.cpython-38-x86_64-linux-gnu.so
7f64478d5000-7f6447ad4000 ---p 00018000 fd:02 1190756                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_mt19937.cpython-38-x86_64-linux-gnu.so
7f6447ad4000-7f6447ad7000 rw-p 00017000 fd:02 1190756                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_mt19937.cpython-38-x86_64-linux-gnu.so
7f6447ad7000-7f6447b30000 r-xp 00000000 fd:02 1190769                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_bounded_integers.cpython-38-x86_64-linux-gnu.so
7f6447b30000-7f6447d30000 ---p 00059000 fd:02 1190769                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_bounded_integers.cpython-38-x86_64-linux-gnu.so
7f6447d30000-7f6447d32000 rw-p 00059000 fd:02 1190769                    /home/user/.local/lib/python3.8/site-packages/numpy/random/_bounded_integers.cpython-38-x86_64-linux-gnu.so
7f6447d32000-7f6447d34000 rw-p 00000000 00:00 0 
7f6447d34000-7f6447d4b000 r-xp 00000000 fd:02 146419526                  /usr/local/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so
7f6447d4b000-7f6447f4b000 ---p 00017000 fd:02 146419526                  /usr/local/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so
7f6447f4b000-7f6447f4c000 r--p 00017000 fd:02 146419526                  /usr/local/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so
7f6447f4c000-7f6447f4d000 rw-p 00018000 fd:02 146419526                  /usr/local/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so
7f6447f4d000-7f6447f58000 r-xp 00000000 fd:02 147016158                  /usr/local/lib/python3.8/lib-dynload/_blake2.cpython-38-x86_64-linux-gnu.so
7f6447f58000-7f6448157000 ---p 0000b000 fd:02 147016158                  /usr/local/lib/python3.8/lib-dynload/_blake2.cpython-38-x86_64-linux-gnu.so
7f6448157000-7f6448158000 r--p 0000a000 fd:02 147016158                  /usr/local/lib/python3.8/lib-dynload/_blake2.cpython-38-x86_64-linux-gnu.so
7f6448158000-7f6448159000 rw-p 0000b000 fd:02 147016158                  /usr/local/lib/python3.8/lib-dynload/_blake2.cpython-38-x86_64-linux-gnu.so
7f6448159000-7f64481b9000 r-xp 00000000 fd:02 91067                      /usr/lib64/libpcre.so.1.2.0
7f64481b9000-7f64483b9000 ---p 00060000 fd:02 91067                      /usr/lib64/libpcre.so.1.2.0
7f64483b9000-7f64483ba000 r--p 00060000 fd:02 91067                      /usr/lib64/libpcre.so.1.2.0
7f64483ba000-7f64483bb000 rw-p 00061000 fd:02 91067                      /usr/lib64/libpcre.so.1.2.0
7f64483bb000-7f64483df000 r-xp 00000000 fd:02 91079                      /usr/lib64/libselinux.so.1
7f64483df000-7f64485de000 ---p 00024000 fd:02 91079                      /usr/lib64/libselinux.so.1
7f64485de000-7f64485df000 r--p 00023000 fd:02 91079                      /usr/lib64/libselinux.so.1
7f64485df000-7f64485e0000 rw-p 00024000 fd:02 91079                      /usr/lib64/libselinux.so.1
7f64485e0000-7f64485e2000 rw-p 00000000 00:00 0 
7f64485e2000-7f64485f8000 r-xp 00000000 fd:02 626528                     /usr/lib64/libresolv-2.17.so
7f64485f8000-7f64487f8000 ---p 00016000 fd:02 626528                     /usr/lib64/libresolv-2.17.so
7f64487f8000-7f64487f9000 r--p 00016000 fd:02 626528                     /usr/lib64/libresolv-2.17.so
7f64487f9000-7f64487fa000 rw-p 00017000 fd:02 626528                     /usr/lib64/libresolv-2.17.so
7f64487fa000-7f64487fc000 rw-p 00000000 00:00 0 
7f64487fc000-7f64487ff000 r-xp 00000000 fd:02 98056                      /usr/lib64/libkeyutils.so.1.5
7f64487ff000-7f64489fe000 ---p 00003000 fd:02 98056                      /usr/lib64/libkeyutils.so.1.5
7f64489fe000-7f64489ff000 r--p 00002000 fd:02 98056                      /usr/lib64/libkeyutils.so.1.5
7f64489ff000-7f6448a00000 rw-p 00003000 fd:02 98056                      /usr/lib64/libkeyutils.so.1.5
7f6448a00000-7f6448a0e000 r-xp 00000000 fd:02 91016                      /usr/lib64/libkrb5support.so.0.1
7f6448a0e000-7f6448c0e000 ---p 0000e000 fd:02 91016                      /usr/lib64/libkrb5support.so.0.1
7f6448c0e000-7f6448c0f000 r--p 0000e000 fd:02 91016                      /usr/lib64/libkrb5support.so.0.1
7f6448c0f000-7f6448c10000 rw-p 0000f000 fd:02 91016                      /usr/lib64/libkrb5support.so.0.1
7f6448c10000-7f6448c41000 r-xp 00000000 fd:02 91008                      /usr/lib64/libk5crypto.so.3.1
7f6448c41000-7f6448e40000 ---p 00031000 fd:02 91008                      /usr/lib64/libk5crypto.so.3.1Aborted (core dumped)

access violation reading 0xFFFFFFFFFFFFFFFF

Exception in thread Thread-4:
Traceback (most recent call last):
  File "C:\Users\Gerbuiker\AppData\Local\Programs\Python\Python37\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\Gerbuiker\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "C:/Users/Gerbuiker/PycharmProjects/LabEnvironment/receive_data.py", line 14, in read_stream
    ch_labels.append(ch.child_value("label"))
  File "C:\Users\Gerbuiker\Documents\Virtualenvs\HITLab\lib\site-packages\pylsl\pylsl.py", line 985, in child_value
    res = lib.lsl_child_value_n(self.e, str.encode(name))
OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF

Happens sporadically so I'm not sure how to reproduce it but I'm reading multiple streams, one stream per thread.

Distributing pylsl on Linux

It looks like the huge effort from @tstenner and me to get a manylinux pip-installable pylsl was all for naught. While we succeeded in creating the manylinux-compatible wheel, it turns out that this is not in fact functional, at least on Ubuntu 18.04, because of some incompatibility between lslboost and pthread. See #5

Step 1: We need better testing on the build systems. I was only testing that the shared object could load and we could get the library version, but I didn't test anything that interacted with boost or threading, so that's how this problem was able to sneak through.

Step 2: We need an alternative way to distribute pylsl.

  • Option A: We could go back to using a single wheel for all platforms, and that wheel will contain liblsl compiled for every possible platform. This will require weird naming schemes and a very large wheel even though individual platforms will only use 1/8th of the file size.

  • Option B: pip and conda for win & mac, conda only for Linux.

  • Option C: Only the Windows wheels have compiled binaries, on all other platforms...

    • rely on liblsl being installed on the system. (e.g.. /usr/local/lib); or
    • create a setup script that builds/downloads liblsl.
  • Option D: Instead focus our efforts on fixing whatever the compatibility issue is between lslboost and (ancient?) pthread. This is probably a waste of time.

Having trouble importing pylsl

Hi everyone, I having trouble importing pylsl. Everytime I try to import it I get:

Traceback (most recent call last):
File "C:/Users/computer/PycharmProjects/pythonProject1/MuseRead.py", line 33, in
import pylsl
File "C:\Users\computer\PycharmProjects\pythonProject1\venv\lib\site-packages\pylsl_init_.py", line 2, in
from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,
File "C:\Users\computer\PycharmProjects\pythonProject1\venv\lib\site-packages\pylsl\pylsl.py", line 1217, in
lib = CDLL(libpath)
File "C:\Users\computer\AppData\Local\Programs\Python\Python37\lib\ctypes_init_.py", line 364, in init
self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

I'm tried looking at the installation guide for pylsl and the only thing I can see is to use pip install pylsl which is what I used.

Thanks in advance to everyone that helps.

lib-finding code should search package/lib first before searching system PATH

The lib finding code iterates through all possible combinations of library naming schemes. For each prefix-suffix combination, it first attempts the local dir then it attempts the system paths before moving on to the next combination.

I think this is the reason why more errors were reporting DLL errors with pylsl recently: it was finding old liblsl(32|64).dll on the PATH before it reached the correct naming scheme for the dll that's in the package/lib dir.

This should be changed so that it first searches through all combinations in the package/lib dir, then if that fails it searches at the system level. This requires a small refactor to so as to not duplicate the search code.

If someone else is in the mood to do that then you are more than welcome. Otherwise I'll add it to my lossy queue.

Byte order conversion on the raspberry pi.

Hi,

I've been experimenting with LSL on the Raspberry Pi in the past few days and so far so good, it's installed and I'm able to exchange some data with a Windows PC.

The issue comes when I tried to send a string from the PC to the Pi. I keep getting an error from "data_receiver.cpp" line 342 that says "Stream transmission broke off (The byte order conversion requested by the other party is not supported.)".

I've had a look at the "data_receiver.cpp" script and I've identified that the error is thrown from line 231 when using the can_convert_endian() function. So I'm guessing this is returning false and the error is thrown.

Based on these observations, my questions is: Is there some conversion I'm not doing when sending strings from the PC to the Pi?

A good way to reproduce this is to run the "SendStringMarkers.py script" on the PC and the "ReceiveStringMarkers.py" on the Pi.

For reference, I'm using PyLSL version 1.15.0 on Raspberry Pi 3B.

Thanks in advance for your help.

Cheers,
Vincent G.

how to resolve stream from another pc

excuse me, I got a question. I am trying to run OpenSingnals software on computer A, and I want to get the stream on computer B, I put the two computers in one inner network, and used the param 'hostname' to get, but I failed, can anyone tell me how to do it? Should I try some other params like 'IP address'? thx!

pip installer broken - find_liblsl_libraries() doesn't find binary with name 'lib'

find_liblsl_libraries() doesn't find binary with name 'lib'

On ubuntu 22, using pipenv for dependency management, version 2022.7.4

Steps to reproduce

  1. $ pip install pylsl
  2. run python interpreter and import pylsl

Error
RuntimeError: LSL binary library file was not found. Please make sure that the binary file can be found in the package lib folder

Cause
observe that pip installer creates binary file called 'lib'. find_liblsl_libraries() needs a .so file.

Temporary fix
$ mv $SITE_PACKAGES/pylsl/lib $SITE_PACKAGES/pylsl/liblsl.so
$ mkdir $SITE_PACKAGES/pylsl/lib
$ mv $SITE_PACKAGES/pylsl/liblsl.so $SITE_PACKAGES/pylsl/lib

Long term fix
fix pip installer so that binary is called liblsl.so not lib

Unable to stream data from multiple sources at the same time

Hi,

I'm trying to stream from 2 different data sources (computers A and B) to another computer (C). Computers A and B are connected to C via 2 different network adapters.

When computers A or B are connected to C by themselves, there isn't any issue, but when both are connected to C, only the data stream from A or B will work, depending on the network adapter which has higher priority.

Has anyone faced similar issues before?

No support for variable-length binary data

The XDF format specification explicitly states support for

non-numeric (i.e., string or binary) values, [with] a variable-length encoding

To my knowledge, the only supported variable-length type in pylsl is pylsl.cf_string.

The issue is that the pylsl.StreamOutlet.push_sample() implementation only accepts unicode strings. It does not support objects of type bytes, etc.

Is there a reason why byte-like objects are not supported?

Suggested solution: Wrap the .encode("utf-8") in a try-except block that catches the attribute error in case the user passed bytes-like objects, see https://stackoverflow.com/a/34870210.

I would like to start working on a PR as soon as one of the developers (maybe @cboulay) confirms the issue and signs off on the suggested solution.

Motivation: Support for variable-length binary data is crucial for the upcoming Pupil Labs LSL Relay plugin changes.

Integration of Intel realsense with lsl

Hello everyone,
I am working on the task where i have to synchronize the timestamps from 2 different sensors (i.e. Infrared images from Intel realsense and EEG signals (with open signals)). I have a separate script with which stream the images from intel realsense and I have the script (https://github.com/biosignalsplux/opensignals-samples/blob/master/LSL/Python/lsl_sample.py) which can give me the values at every timestamp.
I have questions regarding how to integrate the realsense images with the lsl layer ?

liblsl64.dll cannot be found

Hello, I am trying to make pylsl work on Windows 7, using Python 3.8.5.

When import pylsl I get the follosing traceback:

In [1]: import pylsl
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-1-d9db44c5cf92> in <module>
----> 1 import pylsl

c:\users\nirx1\anaconda3\envs\psychopy\lib\site-packages\pylsl\__init__.py in <m
odule>
      1 # (not using import * for Python 2.5 support)
----> 2 from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float3
2,\
      3     cf_double64, cf_string, cf_int32, cf_int16, cf_int8, cf_int64,\
      4     cf_undefined, protocol_version, library_version, library_info, local
_clock,\
      5     proc_ALL, proc_none, proc_clocksync, proc_dejitter, proc_monotonize,
 proc_threadsafe,\

c:\users\nirx1\anaconda3\envs\psychopy\lib\site-packages\pylsl\pylsl.py in <modu
le>
   1215                        "subfolder of the pylsl package or the system sea
rch "
   1216                        "path). Alternatively, specify the env var PYLSL_
LIB")
-> 1217 lib = CDLL(libpath)
   1218
   1219 # set function return types where necessary

c:\users\nirx1\anaconda3\envs\psychopy\lib\ctypes\__init__.py in __init__(self,
name, mode, handle, use_errno, use_last_error, winmode)
    379
    380         if handle is None:
--> 381             self._handle = _dlopen(self._name, mode)
    382         else:
    383             self._handle = handle

FileNotFoundError: Could not find module 'c:\users\nirx1\anaconda3\envs\psychopy
\lib\site-packages\pylsl\lib\liblsl64.dll' (or one of its dependencies). Try usi
ng the full path with constructor syntax.

Then I go to check the path and liblsl64.dll is indeed on the specified path, on the lib\ folder, so I don't know what else to include in order for the library to work. I installed pylsl via pip.

Errors in 1.13.1: Error during resolve_byprop: lslboost:: recursive_mutex constructor failed in pthread::cond_init

OS: Ubuntu 18.04
pylsl version: 1.13.1
Python in Conda:

root@machine:~# python
Python 3.5.5 | packaged by conda-forge | (default, Jul 23 2018, 23:45:43) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] on linux

pip install -I pylsl==1.13.1

root@machine:~# python ReceiveData.py
looking for an EEG stream...
Error during resolve_byprop: lslboost:: recursive_mutex constructor failed in pthread::cond_init: Invalid argument
[]
Traceback (most recent call last):
  File "ReceiveData.py", line 16, in <module>
    inlet = StreamInlet(streams[0])
IndexError: list index out of range
root@engineering:~# 

FIX:

Remove new version, install 1.12.2:

pip uninstall pylsl
pip install -I pylsl==1.12.2

Then everything is fine, the data appearing in console.

PyLSL in Docker

Hi, I'd like to run PyLSL to Docker, I was wondering which port of my container I should expose to get the data from the OpenBCI GUI ? Usually pylsl uses which port to establish the TCP connection ?

Compilation error for macOS<10.15

Hi

I am using conda with python 3.6.12 on macOS 10.13.6 (high sierra). I successfully installed pylsl via pip but when running import pylsl I got the error below. This is a known macOS compatibility issue as pre 10.15 versions can not work with ____chkstk_darwin.

I tried downloading and building the 1.13.1 release with the macOS10.13 precompiled code but I get an egg error that I was unable to solve (see attached file), I think there might be a setup.py file missing? Finally I downloaded the zip from github and tried to follow the readthedocs guide but it doesn't seem to work for version 1.13 which doesn't have a cmakefilelist or setup files.

Could you please point me to where there are high sierra compatible files, or a guide on how to build from the 1.13 release?

Thanks,
Sari
egg_error.txt

Traceback (most recent call last):
File "/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/pylsl.py", line 1267, in
lib = CDLL(libpath)
File "/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/ctypes/init.py", line 348, in init
self._handle = _dlopen(self._name, mode)
OSError: dlopen(/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/lib/liblsl.dylib, 6): Symbol not found: ____chkstk_darwin
Referenced from: /Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/lib/liblsl.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
in /Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/lib/liblsl.dylib

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "", line 1, in
File "/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/init.py", line 2, in
from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,
File "/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/pylsl.py", line 1281, in
raise RuntimeError(err_msg + "\n " + __dload_msg)
RuntimeError: liblsl library '/Users/admin/opt/anaconda3/envs/psychopy/lib/python3.6/site-packages/pylsl/lib/liblsl.dylib' found but could not be loaded - possible platform/architecture mismatch.

You can download the correct LSL library for your platform from the liblsl releases page assets: https://github.com/sccn/liblsl/releases

pylsl not working on RaspberryPi

Not sure how many LSL users out there on RaspberryPi, but I had a project recently and noticed a couple problems:

The distro that pip fetches on a pi does not come with a 32-bit build of liblsl. I also assume that the 64 bit builds that it does come with are not compiled for the ARM chip on a pi.

Also, after compiling the source(1.14.0), the library still doesn't work because of the name change. pylsl is still looking for liblsl32.so, not liblsl.so.

Looks like this was already handled (and I vaguely recall talking about it) in the module loading code in pylsl so I guess the only thing to do would be to roll a pi distro for pip. Again, probably not a high priority task, but I thought I would make a note of it before I forget.

I have some 32-bit liblsl.so's compiled for Raspberry Pi hot off the presses if anyone needs them.

Cannot stream on multiple outlets

This is an example program that streams on two different outlets:

#!/usr/bin/python3    
                                                 
import time

import pylsl


def main():     
    info1 = pylsl.StreamInfo(
            "POS", "Test", 1, pylsl.IRREGULAR_RATE, 'float32', 'myuid34234')
    info2 = pylsl.StreamInfo(
            "NEG", "Test", 1, pylsl.IRREGULAR_RATE, "int16", 'myuid43432')

    # next make an outlet
    outlet1 = pylsl.StreamOutlet(info1)
    outlet2 = pylsl.StreamOutlet(info2)                                                    
                                                                    
    seq: int = 0
    while True:                                                     
        outlet1.push_sample([time.time()])
        if seq % 3 == 0:
            outlet2.push_sample([seq % 65536])
        seq += 1
        time.sleep(0.01)


if __name__ == '__main__':
    main()

If I run it and resolve the available streams, only NEG will appear. I observe the same with muse-lsl, where if I stream more than one type of sensors, only the last outlet opened will appear for discovery

This is with liblsl 1.16.2b1 and pylsl 1.16.1

Floating point precision

Hi,

I'm trying to send floating numbers over LSL but on the receiving end the data is quite mangled.
I installed pylsl using miniconda and thus am using the LSL binaries from there.

I tried both cf_float32 and cf_double64 dtypes.

from pylsl import StreamInfo, cf_float32, cf_double64

stream = StreamInfo(name="send_test_loop", type="command", channel_count=2, nominal_srate=0, channel_format=cf_float32, source_id="send_test")
outlet = stream_outlet(stream)

while True:
    outlet.push_sample([1_667_829_964.917_448_951_321,1_667_829_879.516_441_684_745])

I have captured the output with LabRecorder, saved the result as an .xdf file and inspected it.

The resulting values if using cf_float32 in the .xdf files are:

array([1.6678300e+09, 1.6678299e+09], dtype=float32)

[0:2] : [1667830000.0, 1667829900.0]
dtype: dtype('float32')
max: 1667830000.0
min: 1667829900.0
shape: (2,)
size: 2

The resulting values if using cf_float64 in the .xdf files are:

array([1.66782996e+09, 1.66782988e+09])

[0:2] : [1667829964.9174, 1667829879.5164]
dtype: dtype('float64')
max: 1667829964.9174
min: 1667829879.5164
shape: (2,)
size: 2

Neither of which are the expected (IEEE 754) precision's. pylsl.py states the following:

# For up to 24-bit precision measurements in the appropriate physical unit (
# e.g., microvolts). Integers from -16777216 to 16777216 are represented
# accurately.
cf_float32 = 1
# For universal numeric data as long as permitted by network and disk budget.
#  The largest representable integer is 53-bit.
cf_double64 = 2

But even if cf_float32 is encoded using a 24-bit (binary?) floating point encoding I would expect a better precision. Is it encoded using a fixed point encoding? And from a 64-bit binary floating point encoding I would also expect an higher precision then is achieved.

What is going on here, am I missing something? We want to send large float numbers with a decent precision, and this issue is causing a major problem for us.

edit: I was misunderstanding the expected precision's of single- and double-precision floating point implementations. The values are as expected, I will close the issue.

Pylsl on Nvidia Jetson Nano with Ubuntu Image

Hello all,

I apologize in advance if my post is improper. I am a bit of an outsider to the software development world. I am trying to use pylsl on an Nvidia Jetson Nano running an Ubuntu 18.04 image. I have run the following:

pip install pylsl

with the output:

Collecting pylsl
Using cached https://files.pythonhosted.org/packages/a9/63/ffa84bb429d1b42a7b3451e11847cbfb95a2151ed4016c99e1ba732f7252/pylsl-1.12.2-py2.py3-none-any.whl
Installing collected packages: pylsl
Successfully installed pylsl-1.12.2

Which seems fine to me. Then when trying to import in python I get the error:

Traceback (most recent call last):
File "", line 1, in
File "/home/teamlary/.local/lib/python2.7/site-packages/pylsl/init.py", line 2, in
from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,
File "/home/teamlary/.local/lib/python2.7/site-packages/pylsl/pylsl.py", line 1200, in
lib = CDLL(libpath)
File "/usr/lib/python2.7/ctypes/init.py", line 366, in init
self._handle = _dlopen(self._name, mode)
OSError: /home/teamlary/.local/lib/python2.7/site-packages/pylsl/liblsl64.so: cannot open shared object file: No such file or directory

I also get an identical issue when using pip3 and python3. Has anyone encountered a similar issue? Any suggestions on the best way to get this working would be very much appreciated!

Cheers,

Shawhin Talebi
Underpaid Research Assistant

liblsl on a Raspberry pi

Hi,

I'm trying to run LSL on a RPi (Raspbian Lite kernel version 5.10). I pip installed pylsl on Python 3.7 and then cloned liblsl following the instructions on the repo, and ran a shell script to build liblsl.so, which happened without any issues. I then, created a symlink for the .so file in my [home]/env/lib/python3.7/site-packages/pylsl/lib However everytime I try to run a test using lsl, I get an error that the LSL binary file couldn't be found. I also set up the PYLSL_LIB environment variable pointing to the dir where I built the .so file, but that didn't work either.

My PYLSL_LIB env variable is pointing to the dir where I built the so file: [home]/liblsl/

What could I be missing? Thanks!

Recording marker stream with lab recorder

Hello,

I am having trouble recording a marker stream written in python along with the output stream. When I open the xdf file in eeglab, all of the markers are bunched up at the end of the recording. I know it's not my code, because this happens even for the example code you provide. The one thing that is the same is that I am testing this on .set data streaming over neuropype. Any idea what my issue might be? Thanks.

-Alex

How to correctly match different data streams

Hello Guys,

First of all i apologise if this is not the right channel for posting this question as it is not a working issue, though practical. Let me know if I should use another channel.

I am using LSL to read data streams from different devices and so far i am reading the the streams with the corrected timestamp.

I want to create a unique dataset that match the data streams in time using the timestamps. So i would like to know how you do it. The problem that i have found is that the timestamps between streams don't fully match at millisecond level, which puts me off from doing the merge directly. Also another problem is that the sampling rate of the devices is different. So in a second you can have 500 samples from one device and 1000 or more from another. This also provides a another problematic to take into account.

I know you have an app called labrecorder. So i though that you might have gone through this problem before and might know the best way to merge the data streams.

If you can tell me a hint that would be great!

Thanks a lot in advance!

Andrés

Closing Inlet with `inlet.close_stream()` does not de-register as "consumer"

Hi,

I am using LSL C# to send data, and LSL Python to receive data.
I have set up my C# to display a message when consumers are connected (for peace of mind when data are being collected).

However, when I close the inlet stream (or e.g. quit python) the outlet still returns true as having consumers:

outlet.have_consumers(); // true

Am I closing wrong, or something else I am missing?

Pylsl precision problems

Below you can see a test of outlet and inlet data. Only 5 significant numbers are equal. Is this normal?

***OUTLET_DATA
STAMP:[17179.395466097]
SAMPLE:[52.057985450431254, 47.2703647175461, 15.023354318885762, 56.304367890891285, 42.92836237812874, 25.00853755102409, 26.02998306266926, 40.27109700121555, 4.996895512545263, 33.472730456238885, 39.705453031294994, 84.91143736067775, 62.38916076898047, 27.758021899765893, 51.15501291708292, 89.9828961474747, 33.95563917840357, 31.503025009413797, 45.33956661540789, 51.09868060197509, 21.734038834742563, 71.64371584605918, 86.05013294594738, 61.075437121788035, 13.544131172100393, 10.255098534937835, 39.304440040989775, 31.73323912424252, 19.11649928209035, 69.97309570675311, 24.876553585727113, 95.42718716719125]

***INLET_DATA
STAMP:[17179.395466097]
SAMPLE:[52.057987213134766, 47.270362854003906, 15.023354530334473, 56.30436706542969, 42.92836380004883, 25.00853729248047, 26.029983520507812, 40.271095275878906, 4.9968953132629395, 33.47272872924805, 39.70545196533203, 84.91143798828125, 62.38916015625, 27.75802230834961, 51.15501403808594, 89.98289489746094, 33.95563888549805, 31.50302505493164, 45.33956527709961, 51.09868240356445, 21.734039306640625, 71.64371490478516, 86.05013275146484, 61.075435638427734, 13.5441312789917, 10.255098342895508, 39.304439544677734, 31.733238220214844, 19.116498947143555, 69.97309875488281, 24.876554489135742, 95.42718505859375]

CODE USED FOR PRINTING THE DATA
outlet.py:

from pylsl import StreamInfo, StreamOutlet, local_clock
sampleRate = 1000
channel_number = 32
info = StreamInfo('Actichamp', 'EEG', channel_number, sampleRate, 'float32', 'myuid2424')
outlet = StreamOutlet(info, 10, 360)
start_time=local_clock() #s
elapsed_time=local_clock()-start_time #s
while elapsed_time<=100:
    sample=[]
    for i in range(channel_number):
        sample.append(random.random())
    offset = 100 
    m_array = np.array(sample)*offset
    sample = m_array.tolist()
    sample_stamp = [local_clock()-0.125]
    outlet.push_sample(sample, sample_stamp[0])
    print('**********************OUTLET_DATA*******************')
    print('STAMP:'+str(sample_stamp))
    print('SAMPLE:'+str(sample))
    time.sleep(1/float(sampleRate))
    elapsed_time=local_clock()-start_time

inlet.py:

from pylsl import StreamInlet, resolve_stream
print("looking for an EEG stream...")
streams = resolve_stream('type', 'EEG')
inlet = StreamInlet(streams[0])
while True:
    chunk, timestamps = inlet.pull_chunk()
    if timestamps:
        print('**********************INLET_DATA*******************')
        print('SAMPLE_STAMP:'+str(timestamps))
        print('SAMPLE:'+str(chunk))

Cheers,
NC

Missing cf_int64 support needs better error message

Currently there are no lib.lsl_push_ or lib.lsl_pull_ methods mapped for cf_int64.
However, when one attempts to use this format, the error returned is 'list' object is not callable, because instead of a proper method, the map returns [].

I think there needs to be an error raised when a stream is opened with this channel format.

Which pylsl?

From @klanderson on October 1, 2018 22:36

The most recently modified version is at labstreaminglayer/liblsl-Python

Other versions are: labstreaminglayer/tree/master/LSL/liblsl-Python and chkothe/pylsl

It appears that pip installs the version from labstreaminglayer/tree/master/LSL/liblsl-Python, because pylsl.library_info() is not implemented.

I'd like to use pylsl.library_info(). Is it safe to rely on labstreaminglayer/liblsl-Python as the official version?

Copied from original issue: sccn/labstreaminglayer#349

StreamInlet.Time correction not working!

Hello guys,

I am streaming EEG data using NIC software with ENOBIO. I see the stream of data both with matlab and python.

My problem is that the StreamInlet object is not able to call the function time_correction. It does call but it last forever. I am placing a timeout of 60 seconds and timer expires before i can get the time_correction calculated. Additionally, i am able to see my stream of data and also i am able to call pull_sample and pull_chunk. So, i don't know why it is not able to apply time_correction.

Do you know what it might be the cause of my error ?

I am using python 3.6.6. I installed pylsl with pip and had not problems. In matlab it is able of calling time_correction without waiting too much.

Thank you a lot in advance!

Andrés

software architecture problem with pylsl & multiprocess.Process Python

Dear all,
I'd like to use LSL within a Python multiprocess.Process for reading in data from a stream with inlet.pull_chunk (and I am using a Windows machine Python 3.8). I'm working on Spyder Conda and I need to run 3/4 processes contemporary of which the first has the inlet object as argument for pulling the chunk in a while loop. After the creation of the inlet object in the main script, when the first process is started, I get the following exception however:

ctypes objects containing pointers cannot be pickled.

and later:

Traceback (most recent call last):
File "", line 1, in
File "C:\Users\Matteo\anaconda3\envs\ISO-CLS\lib\site-packages\multiprocess\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:\Users\Matteo\anaconda3\envs\ISO-CLS\lib\site-packages\multiprocess\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
File "C:\Users\Matteo\anaconda3\envs\ISO-CLS\lib\site-packages\dill_dill.py", line 373, in load
return Unpickler(file, ignore=ignore, **kwds).load()
File "C:\Users\Matteo\anaconda3\envs\ISO-CLS\lib\site-packages\dill_dill.py", line 646, in load
obj = StockUnpickler.load(self)
EOFError: Ran out of input

If I use threading module there are no problems and the inlet object provides the requested of pulling chunk. I don't have the necessary skill to create and to develop a wrapper file to solve this problem, like have been suggested me, but I'd like to know if there is a smart solution.

If there is someone that can help me, will have my esteem and attention!

best regards

Matteo

Support for pushing arbitrary byte sequences in cf_string channels

We would like to transmit arbitrary byte sequences using pylsl and cf_string channels. Unfortunately, the current pylsl implementation does not support that. Technically, it should work just fine though.

liblsl states the following about the cft_string channel format:

/** For variable-length ASCII strings or data blobs, such as video frames, complex event
      descriptions, etc. */
cft_string = 3,

For the user's convenience, pylsl cf_string outlets accept Python str objects and encode them on the fly. Similarly, the cf_string inlets decode incoming byte strings to str objects.

While this is helpful 99% of the time, it makes sending/receiving arbitrary byte strings impossible, e.g. when one wants to transmit encoded video frame data. Decoding our bytestring to utf-8 first and then have pylsl encode it again is unfortunately not a viable workaround as not all byte sequences can be decoded to utf-8.

Proposed solution

We suggest adding a boolean flag to the corresponding pull_* and push_* function that indicates wether the data should be encoded/decoded, defaulting to True. This should fit conceptionally, given that it is the users responsibility to interpret the data.

Dear pylsl maintainers, what do you think about this proposal?

/cc @ClaraKuper

liblsl 1.14 and python 3.8 -- Exception on creating XML element.

Python 3.8.5 installed via conda, using pylsl wheel built with liblsl 1.14b03

import pylsl
info = pylsl.StreamInfo(channel_count=3, channel_format=pylsl.cf_string)
chans = info.desc().append_child("channels")

Unhandled exception in event loop:
File "C:\Users\Chad.conda\envs\pylsl114\lib\asyncio\proactor_events.py", line 768, in _loop_self_reading
f.result() # may raise
File "C:\Users\Chad.conda\envs\pylsl114\lib\asyncio\windows_events.py", line 808, in _poll
value = callback(transferred, key, ov)
File "C:\Users\Chad.conda\envs\pylsl114\lib\asyncio\windows_events.py", line 457, in finish_recv
raise ConnectionResetError(*exc.args)

Exception [WinError 995] The I/O operation has been aborted because of either a thread exit or an application request
Press ENTER to continue...

I swapped to python 3.7, used the exact same wheel, and couldn't reproduce the issue.

Forward-compatibility with lsl.dll naming scheme when dll not on system path

While util.find_library('lsl') would find lsl.dll if it were on a search path, it doesn't find it if it's only in the pylsl/lib folder.
Solution: change

libbasepath = os.path.join(os.path.dirname(__file__), 'lib', 'liblsl')
for debugsuffix in ['', '-debug']:
    for bitness in ['', str(8 * struct.calcsize("P"))]:
        path = libbasepath + bitness + debugsuffix + libsuffix

to

libbasepath = os.path.join(os.path.dirname(__file__), 'lib')
for libprefix in ['', 'lib']:
    for debugsuffix in ['', '-debug']:
        for bitness in ['', str(8 * struct.calcsize("P"))]:
            path = os.path.join(libbasepath, libprefix + 'lsl' + bitness + debugsuffix + libsuffix)

I will deal with this later.

LSL buffer issue

I am using LSL to stream EEG, fNIRS, and Eye tracker data. I'm using PyQT5 to plot those data streams. The issue I am having is initially there isn't a delay in plots but over some period of time (say an hour), there is a huge delay in the plots. One thing I observed is my EEG is streaming at 500hz so after I stop the streams, for like 2 hours my program will continue to plot the streams. Does LSL have a built-in buffer?

If so how do I control the buffer?

OSError: [WinError 193] %1 is not a valid Win32 application

from pylsl import StreamInlet, resolve_stream
File "C:\Users\rakes\AppData\Local\Programs\Python\Python38\lib\site-packages\pylsl_init_.py", line 2, in
from .pylsl import IRREGULAR_RATE, DEDUCED_TIMESTAMP, FOREVER, cf_float32,
File "C:\Users\rakes\AppData\Local\Programs\Python\Python38\lib\site-packages\pylsl\pylsl.py", line 1217, in
lib = CDLL(libpath)
File "C:\Users\rakes\AppData\Local\Programs\Python\Python38\lib\ctypes_init_.py", line 373, in init
self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

standalone-compilation not working on Raspberry Pi

i tried to execute the standalone_compilation_linux.sh on my raspberry pi 3 after cloning the entire sccn/liblsl file into my liblsl-Python/pylsl/lib. However, once i execute the standalone_compilation_linux.sh, a list of error appear.

/thirdparty/loguru/loguru.cpp:907:91: error: invalid conversion from 'int' to 'loguru::close_handler_t {aka void ()(void*)}' [-fpermissive]
thirdparty/loguru/loguru.cpp:907:91: error: invalid conversion from 'loguru::flush_handler_t {aka void ()(void)}' to 'unsigned int' [-fpermissive]
thirdparty/loguru/loguru.cpp: At global scope:
thirdparty/loguru/loguru.cpp:913:33: error: redefinition of 'const char* loguru::get_verbosity_name'
const char* get_verbosity_name(Verbosity verbosity)
^
In file included from thirdparty/loguru/loguru.cpp:23:0:
thirdparty/loguru/loguru.hpp:593:14: error: 'const char* loguru::get_verbosity_name' previously defined here
const char* get_verbosity_name(Verbosity verbosity);
^
*/ and many other errors

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.