Event broadcaster documentation/tutorial

281 views
Skip to first unread message

marcus....@gmail.com

unread,
May 25, 2018, 11:05:38 AM5/25/18
to Open Ephys
Hi all,

we recently started on integrating OpenEphys with our existing stimulation hard- and software. Towards this end I would like to write a script in either Python or Matlab that receives Spikes and trial events to do some calculations etc. It seems that this is exactly what the event broadcaster was made for.

So far I have started with the minimal working example for a signal chain based on the file reader (data_stream_16ch_cortex) and the bandpass filter, spike sorter, splitter to spike viewer and event broadcaster. Spikes are detected and sorted when I start the acquisition. When I then try to run the provided example (event_listener.py) the prog gets stuck at "parts = sock.recv_multipart()" as if there is just no event broadcasted at all. The network_events_console.py works just as expected, so I assume it is not a general zmq problem.

Can anyone help here?

Best,

Marcus

Aarón Cuevas

unread,
May 31, 2018, 7:54:44 PM5/31/18
to Open Ephys
Hi Marcus,

The event broadcaster is an early proof-of-concept plugin that send the raw event structure via ZMQ. That structure was heavily modified a couple of versions ago but we have not been able to update the example scripts yet. So while the raw console works, the event listener script, which expects data conforming the old structure, fails to read the messages.

The reason it gets stuck at that specific line is because in lines 68-69 the script first sets up listeners for the 4 event types specified in lines 13-17, each of those listener filtering each message according to its first byte. The first byte of an event messages is not any of those any more, but 1 for normal events and 2 for spike events, with a second byte specifying the "subtype" (TTL/TEXT, etc... for events and SINGLE/STEREOTRODE/TETRODE for spikes).

The new structure is documented on Source/Processors/Events/Events.h line 34
On it the "EventType" field corresponds to the EventType enum in that file, SubType for events correspond to the enum in EventChannel::EventChannelTypes in Source/Processors/Channel/InfoObjects.h line 279 and ElectrodeType for spikes to the enum SpikeChannel::ElectrodeTypes in the InfoObjects.h file, line 13

I hope this can be of help.

Best,
Aarón

marcus....@gmail.com

unread,
Jul 4, 2018, 6:07:50 AM7/4/18
to Open Ephys
Hi Aaron,

thank you! This indeed put me into the right direction. I now managed to read the spike events (which is all I have in the test configuration) correctly. If this is of interested I am of course more than willing to share my modified event_listener script.

What is left from my point of view is to understand the timestamp of the spike. This does not seem to be in the same format as the timestamp of the event. E.g. I might get this spike event info (in Python):

print('%g: Spike: %s' % (timestamp_seconds, spike))
5.38823: Spike: OrderedDict([('EventType', 130), ('ElectrodeType', 1), ('SourceProcessorID', 104), ('SourceSubprocessorIdx', 0), ('SourceElectrodeIdx', 1), ('timestamp', 215529), ('sorted_id', 0), ('data', None)])

Looking through the OpenEphys source code I could not really find a good explanation. Is this the time since the last sync of hard and software? How do I interpret this timestamp?

Best,

Marcus

Aarón Cuevas

unread,
Jul 5, 2018, 11:58:21 PM7/5/18
to Open Ephys
Hi Marcus,

The timestamp field is the hardware timestamp, which is actually a sample count. In the spike case, it is the timestamp corresponding to the peak sample.
timestamp_seconds is just the timestamp divided by the sample rate of the signal, which in the case of the example signals is 40KHz

Is this what you're referring to?

Best,
Aarón

pierre-pascal lenck-santini

unread,
Mar 22, 2021, 6:58:11 AM3/22/21
to Open Ephys
Hello,
Aaron, would you happen to have a python code that reads the new version of the events?
I've been stuck for a week on this. I can't get anything from the sever (newest version as of tody on the last version of OEP).
thanks!

pierre-pascal lenck-santini

unread,
Mar 22, 2021, 2:57:14 PM3/22/21
to Open Ephys
For whom it may concern and benefit:
here is a way to read the sockets:
first  eventbroadcaster is in the SUB-PUB protocol
so when creating the socket:

     socket = context.socket(zmq.SUB)
#then make the connection:
    socket.connect("tcp://127.0.0.1:5558")
#this is the key: make sure you use the json option on the plugin
    socket.setsockopt(zmq.SUBSCRIBE, b'ttl')
    socket.setsockopt(zmq.SUBSCRIBE, b'spike')
voilà!

aaron.cue...@gmail.com

unread,
Mar 23, 2021, 9:19:28 AM3/23/21
to Open Ephys
Hello,
Glad you got it working. Unfortunately, I do not have any python scripts available, nor am I particularly familiar with ZMQ, so other users could help you better with that part.

All I can said is that, for text types ("header only" and "header and json") the first bytes are indeed these strings (also "text" for text messages and "binary" for binary events).
For RAW format, which could be needed for extracting spike waveforms, the binary block sent contains:
uint16 with "1" for TTL/text/binary messages and "2" for spikes
double (64bit float) with the timestamp in seconds (this is, the timestamp divided by the sampling rate)
and a data blob corresponding with the raw event structures described in the comments of the Events.h file in the GUI source.

Best,
Aarón

Reply all
Reply to author
Forward
0 new messages