v0.6.0
Binary release July 22, 2022
Release Notes
Overview
Version 0.6.0 includes a large number of updates intended to improve the experience of both users and developers of the Open Ephys GUI. Many of the changes were prompted by the need to provide more robust support for data sources that send multiple asynchronous streams (such as Neuropixels). Perhaps the most important update is the introduction of the DataStream
class, which represents a group of channels that are guaranteed to generate the same number of samples on each processing block. Every continuous channel, event channel, and spike channel must be associated with one and only one DataStream
object, in order to ensure that its timestamps can be assigned accurately. Users will notice that the old "Channel Selector" on the right-hand side of each plugin editor has been replaced with a "Stream Selector," which allows you to view information about the various streams that are passing through a plugin. Plugin parameters are now typically applied on a per-stream basis, and any channel-specific parameters are configured via a popup window that's much easier to navigate than the previous Channel Selector UI.
These updates would not have been possible without introducing breaking changes to the Open Ephys Plugin API (now at version 8). Any existing plugins will need to be refactored and recompiled in order to be loaded by the host application. We worked hard to make the API simpler and more consistent, and many convenience functions were added to simplify plugin development. Most importantly, we overhauled the Parameter
class, in order to make it possible to generate user interfaces for new plugins with only a few lines of code. For example, see the FilterEditor.cpp
file before and after implementing these changes. The Parameter
class also keeps track of settings across data streams, and automatically handles saving and loading.
Almost every source code file has been cleaned up, with docstrings added to most header files and unused functions removed. We also streamlined the user interface, removing unnecessary buttons and menu items. We reduced the default plugins down to the essentials, and moved other plugins to their own repositories. This will allow users to upgrade these plugins independently from the main GUI, making it easier to roll out new features in the future.
Core GUI enhancements
Data streams as first-class citizens: Previously, sources that emitted data as multiple, asynchronous streams (such as Neuropixels) were represented as "subprocessors" with zero-based indexing. However, the channels associated with a given subprocessor were not readily visible to the user. Now, the subprocessor concept has been replaced by "Data Streams" that represent a block of continuous channels that are guaranteed to generate the same number of samples on each processing callback. When using data sources that only generate one stream (such as the File Reader), the behavior of the GUI will be largely unchanged. But when multiple streams are present (such as the AP band and LFP band of Neuropixels probes), independent settings can be applied to each stream. For example, it's now straightforward to have unique Bandpass Filter settings for different streams, or even to have the Bandpass Filter plugin bypass a given stream entirely to conserve CPU. Grouping channels by streams also prevents the user from, e.g., creating electrode groups for spike detection that span multiple streams, which would generate invalid spikes. Information about individual streams is now visible in the redesigned "Graph" tab, as well as the Stream Selector interface for each plugin (viewed by clicking the vertical lines on the right of the plugin editor). The visible settings for a given plugin will reflect the stream that's currently active in the Stream Selector. In addition, the Stream Selector displays the amount of time it takes for data to pass through a plugin (helpful for determining which plugins are introducing unwanted processing latency), as well as the state of the first 10 TTL lines for a given stream.
Overhauled Parameter
class: The GUI previously had a class to represent different types of plugin parameters, but this was not being used by most plugins. We have now revived this class, and made it a central part of all of the built-in plugins. The Parameter
class now serves three main functions: auto-generating user interfaces, keeping track of parameter values across data streams, and automatically saving and loading settings for each plugin. There are 7 types of Parameters
(boolean, categorical, string, float, integer, selected channels, and mask channels) and 5 types of Parameter Editors (text box, check box, combo box, slider, selected channels, and mask channels). Parameters
can be applied to plugins (global scope), data streams (stream scope), or individual channels (event channel scope, continuous channel scope, and spike channel scope). Parameters
must be declared in the plugin's GenericProcessor
constructor, and any ParameterEditors
must be declared in the plugin's GenericEditor
constructor. Parameter
names must avoid spaces in order to allow saving/loading via XML. See the FilterNode for an example of how to use the Parameter
class in practice.
Broadcast messages: Plugins can now communicate with one another via broadcast messages. A broadcast message sent while acquisition is active will be distributed to all other plugins in the signal chain via the MessageCenter
. This allows messages to be passed "backwards" through the signal chain, for example to trigger the digital outputs of the Open Ephys acquisition board. To send a broadcast message, simply call GenericProcessor::broadcastMessage()
while acquisition is active. To respond to broadcast messages, plugins should implement the GenericProcessor::handleBroadcastMessage()
method. Broadcast messages are currently used by the Acquisition Board plugin (formerly Rhythm FPGA) to trigger digital outputs and the Audio Monitor plugin to select channels to listen to. Additional functionality based on broadcast messages will be added in the future.
Built-in HTTP server: The GUI no longer requires the Network Events plugin to be controlled remotely; instead, it now launches an HTTP server based on a class originally implemented by Paul Botros from the Carmena Lab at Berkeley. The HTTP server makes it possible to start/stop acquisition, configure plugins parameters, transmit broadcast messages through the signal chain, and even close the GUI remotely. When the GUI is open, browsing to http://localhost:37497/api/processors will display the current signal chain in JSON format. Changes to the GUI's status are done via HTTP "PUT" requests, and can be accomplished with a single line of code using Python's requests library.
Streamlined settings files: The XML files used for saving and loading signal chains are much more compact and easier to interpret. However, we still do not recommend attempting to manually edit settings files, as this can invalidate them.
Redesigned "Info" tab: The GUI's info tab now displays links to the documentation, citation information, a list of contributors, and the GPL 3.0 license.
Audio Monitor: The "Audio" interface has been removed from individual plugins. Instead, Audio Monitors can be dropped into the signal chain as a separate plugin. Users can select up to 4 continuous channels to listen to, or select an incoming Spike Channel to monitor. The Audio Monitor includes a built-in high-pass filter so it can output decent-sounding signals at almost any point in the signal chain.
Default configurations: When the GUI is launched for the first time, the user is prompted to select one of 3 default configurations: Acquisition Board, File Reader, or Neuropixels (Windows only). If a plugin required for one of these configurations is not available, it will be installed automatically (this only works in "Release" mode). On subsequent runs, the default configuration interface can be accessed via the File menu.
Recording: Added the ability to customize the name of recording directory via the control panel (i.e., you don't need to use the auto-generated date string if you don't want to).
Logging: Replaced all calls to std::cout
with LOGA
, LOGB
, LOGC
, etc. syntax. This makes it easier to track different kinds of messages and have more refined control over what gets printed to the console. All logging output is printed to a text file, which is copied and timestamped in the case of a crash.
Updated JUCE backend: The GUI now uses a more recent version of the JUCE library (v6).
Updates to Individual Plugins
File Reader: The File Reader can now read in both continuous channels and events from three different formats: Binary, Open Ephys, and NWB 2.0. For files longer than 30 seconds, it includes a "scrubbing" interface that can be used to quickly scroll to different points in the file.
Rhythm FPGA: The Rhythm FPGA plugin has been split into two separate plugins, "Acquisition Board" and "Intan RHD USB", which now live in their own repository. This makes it possible to upgrade these plugins independently from the main GUI. We have also improved the impedance measurement functionality, which includes a progress bar and the ability to save impedance values to an XML file directly from the UI.
Neuropixels: A more efficient start-up sequence leads to faster loading times. The HTTP server can be used to select different subsets of electrodes via a Python or Matlab script. IMPORTANT: We added automatic offset subtraction to the Neuropixels-PXI data stream, so signals are centered around 0 after about 5 seconds of acquisition. This makes it possible to perform spike detection on AP band channels without filtering.
Spike Detector: The Spike Detector includes a new configuration table that makes it much easier to view and modify settings across electrodes. There are now three different options for setting the spike detection threshold, two of which will compute the threshold automatically.