Skip to content

htil/LSL-Test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LSL Test — Electron → LSL demo + XDF analysis

This repo contains:

  • electron-lsl-demo/ — Electron app that publishes two LSL marker streams:
    • MouseEvents (JSON markers: move and click, includes t_ms, x, y, btn)
    • MicMarkers (mic_start / mic_stop manual markers)
    • Also includes lsl-bridge.py (Python WebSocket → LSL bridge)
  • xdf-analysis/ — Python tools to inspect XDF files (analyze_xdf.py, requirements.txt)

This README explains how to run the demo, record with LabRecorder, and analyze the saved XDF recordings.


Requirements

  • Node.js + npm (for Electron)
  • Python 3.8+ (for the bridge and analysis)
  • LabRecorder (to record streams to .xdf) — see links below

LabRecorder resources:

Install LabRecorder first (download the appropriate binary for Windows and install).


Quick setup (one-time)

  1. Install Node dependencies for the Electron app:
cd 'C:\dev\scratch\LSL Test\electron-lsl-demo'
npm install
  1. Prepare Python environment for the analyzer (recommended: venv):
cd 'C:\dev\scratch\LSL Test\xdf-analysis'
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
  1. Install Python deps for the bridge (if you will run it manually; included in README steps below):
python -m pip install --user pylsl websockets

Run the demo + bridge

You can run both the Python LSL bridge and the Electron app together manually in two terminals.

Terminal 1 — start the Python bridge:

cd 'C:\dev\scratch\LSL Test\electron-lsl-demo'
python .\lsl-bridge.py

Terminal 2 — start Electron:

cd 'C:\dev\scratch\LSL Test\electron-lsl-demo'
npm start

Notes:

  • The bridge publishes real LSL marker streams via pylsl. The preload will use the native Node LSL addon if installed; otherwise it sends markers to the bridge.
  • If the Electron window shows LSL: fallback (no network) then the bridge isn't connected. Restart the bridge and then restart Electron (or check DevTools console for WebSocket errors).

Record with LabRecorder

  1. Launch LabRecorder application.
  2. Click Update in the LabRecorder window. You should see the streams:
    • MouseEvents
    • MicMarkers
  3. Check those streams (tick boxes), choose a save folder, then click Start.
    • For your setup the save path (example) is:
      C:\Users\vdingram\Documents\CurrentStudy\sub-P001\ses-S001\eeg
      
    • LabRecorder will save an XDF file in that folder (filename depends on LabRecorder settings and your Study template).
  4. Interact with the Electron window while recording:
    • Move the mouse (move markers)
    • Click (click markers)
    • Toggle the Mic button (pushes mic_start / mic_stop markers)
  5. Stop recording in LabRecorder → this finalizes the .xdf.

Important:

  • The mic markers are manual event markers (NOT audio). Use them as trial or block boundaries (e.g., mic_start marks the start of a response window; mic_stop marks the end).
  • If LabRecorder does not list the streams after clicking Update:
    • Ensure the bridge is running (start it before Electron).
    • Allow python.exe and electron.exe through Windows Firewall.
    • Use the pylsl check (below) to confirm streams exist.

Quick stream check (run in any terminal while bridge+Electron are running):

python -c "from pylsl import resolve_streams; print([s.name() for s in resolve_streams()])"

Move the recorded XDF into the analysis folder

After LabRecorder saves the XDF (example path above), move or copy that .xdf into the xdf-analysis folder so the analysis tools can find it easily.

Example (PowerShell):

# adjust file name to the actual saved file name
Copy-Item "C:\Users\$User$\Documents\CurrentStudy\sub-P001\ses-S001\eeg\sub-P001_ses-S001_task-YourTask_run-001_eeg.xdf" `
          "C:\dev\scratch\LSL Test\xdf-analysis\test.xdf"

(You can also use Move-Item instead of Copy-Item if you want to relocate the file.)


Analyze the XDF

Activate the analysis venv (if not already active):

cd 'C:\dev\scratch\LSL Test\xdf-analysis'
.\.venv\Scripts\Activate.ps1

Basic summary (first 5 markers)

python .\analyze_xdf.py --file ".\test.xdf"

Show all markers (prints every marker row)

python .\analyze_xdf.py --file ".\test.xdf" --show-all

Useful plotting and analysis flags

  • Timeline (moves + clicks; mic windows shaded):
python .\analyze_xdf.py --file ".\test.xdf" --timeline --plot
  • Heatmap of mouse positions:
python .\analyze_xdf.py --file ".\test.xdf" --heatmap --plot
  • Event-rate timeseries (events per second by kind):
python .\analyze_xdf.py --file ".\test.xdf" --event-rate --plot
  • Compute reaction times (for each mic_start → first click after it, printed in ms):
python .\analyze_xdf.py --file ".\test.xdf" --reaction-times
  • Combine plots:
python .\analyze_xdf.py --file ".\test.xdf" --timeline --heatmap --event-rate --plot

Notes:

  • --plot is a convenience: it causes timeline/heatmap/event-rate (depending on flags) to render and show.
  • If plotting libraries are missing the script will print an informative message; make sure matplotlib and seaborn are installed inside the venv.

Practical example workflow (end-to-end)

  1. Ensure LabRecorder is installed.
  2. Start the demo:
cd 'C:\dev\scratch\LSL Test\electron-lsl-demo'
npm start
  1. Open LabRecorder, click Update, select MouseEvents and MicMarkers, set save folder to:
C:\Users\vdingram\Documents\CurrentStudy\sub-P001\ses-S001\eeg
  1. Click Start in LabRecorder and run the task in the Electron window (move/click, toggle mic).
  2. Click Stop in LabRecorder. Copy the saved .xdf into xdf-analysis as test.xdf (see copy command above).
  3. Activate venv and run the analyzer:
cd 'C:\dev\scratch\LSL Test\xdf-analysis'
.\.venv\Scripts\Activate.ps1
python .\analyze_xdf.py --file ".\test.xdf" --timeline --heatmap --reaction-times --plot

Troubleshooting

  • Bridge not connected:

    • Start the Python bridge before starting Electron.
    • Check Electron DevTools (Ctrl+Shift+I) Console for WebSocket errors.
  • Streams still not visible in LabRecorder:

    • Check that pylsl resolves streams (see quick stream check above).
    • Check Windows Firewall or antivirus blocking UDP multicast/discovery.
  • Analyzer errors:

    • Activate the venv and confirm dependencies installed (pip install -r requirements.txt).
    • XDF file locked by LabRecorder — ensure LabRecorder has finished/stopped recording.

Notes about markers and timestamps

  • MouseEvents payload example:

    {"t_ms": 21020.7, "kind": "move", "x": 403, "y": 518}
    • t_ms: performance.now() in milliseconds (app-local, monotonic).
    • kind: move or click
    • x, y: pixel coordinates
    • btn: mouse button for clicks (0 = left, etc.)
  • MicMarkers payload example:

    {"t_ms": 24129, "kind": "mic_start"}
    • These are manual markers (no audio). Use mic_start / mic_stop as trial/recording window boundaries or anchors to compute reaction times.
  • analyze_xdf.py uses pyxdf.load_xdf(..., synchronize_clocks=True) to align LSL clocks and make timestamps comparable across streams.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published