diff --git a/source/User-Manual/Plugins/Onix-Source.rst b/source/User-Manual/Plugins/Onix-Source.rst index 838b6edd..22650c2e 100644 --- a/source/User-Manual/Plugins/Onix-Source.rst +++ b/source/User-Manual/Plugins/Onix-Source.rst @@ -68,11 +68,11 @@ Plugin Configuration please consider adding them to the `GitHub repo `__. .. note:: - The ONIX Source plugin requires the ONIX PCIe Host Firmware to be version 2.0 or higher. If you have an - older version of the firmware, you will need to upgrade it to use this plugin. Please follow the - `Updating Firmware in Windows - `__ - portion of the hardware documentation to update your PCIe controller firmware. + The ONIX Source plugin requires the ONIX PCIe Host Gateware to be version 2.0 or higher. If you have an + older version of the gateware, you will need to upgrade it to use this plugin. Please follow the + `Updating Gateware in Windows + `__ + portion of the hardware documentation to update your PCIe controller gateware. The ONIX Source plugin allows you to stream data from the ONIX acquisition system. This plugin assumes that you have an ONIX Breakout Board connected and powered on before adding the plugin to @@ -206,11 +206,15 @@ CPU usage but may increase latency. A smaller block read size can provide lower cause the memory monitor to fill up. The default value is 4096 samples, but this can be adjusted based on your experimental needs. -The block read size can be set to any integer value, but this value must be greater than the size of -the largest frame received from the connected headstage. If the block read size is set to a value -smaller than the size of the largest frame, an error message will be displayed in a pop-up window -with the smallest value possible for the block read size. The plugin will not allow you to connect -to the ONIX system until the block read size is set to a valid value. +The block read size must be greater than the size of the largest frame received from the connected +headstage. If the block read size is set to a value smaller than the size of the largest frame, an +error message will be displayed in a pop-up window with the smallest value possible for the block +read size. The plugin will not allow you to connect to the ONIX system until the block read size is +set to a valid value. + +.. note:: + The block read size must be aligned to a 32-bit word boundary. If a value is not aligned, it will + be rounded up to the next 32-bit aligned value. :code:`liboni` Version ######################### @@ -307,6 +311,39 @@ file, press the "Load from JSON" button. This will open a file dialog that allow JSON file to load. The loaded JSON file will be used to configure the probe settings, such as the selected electrodes. +Automatically saved ProbeInterface JSON Files +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: Requires >= v0.3.0 of the plugin, and >= v1.0.2 of the GUI. + +Every data stream that contains ProbeInterface metadata will write that metadata to a JSON file +every time a recording is started. The files will be saved in the folder path set by the recording +options interface at the top of the GUI's main window. This may be a different folder +location than the Record Nodes, as those can be modified to save in a folder that is different from +the main GUI. If there is a Record Node using the default folder path, then the folder structure +will look something like this: + +.. code-block:: + + / + ├── ONIX Source 100/ + │ ├── experiment1/ + │ │ └── .json + │ ├── experiment2/ + │ │ └── .json + │ └── experiment3/ + │ └── .json + └── Record Node 102/ + ├── experiment1/ + ├── experiment2/ + ├── experiment3/ + ├── settings.xml + ├── settings_2.xml + └── settings_3.xml + +Note that there may be multiple JSON files per folder in the ONIX Source 100 folder, or the ONIX +Source 100 folder may not exist if no streams are being recorded that contain a ProbeInterface file. + Transfer electrode configurations from external sources ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -330,6 +367,8 @@ to this plugin. .. image:: ../../_static/images/plugins/onixsource/probe-interface-neuropixels-pxi-to-onix-source.gif :alt: GIF showing how to export JSON file from Neuropixels PXI plugin and import to ONIX Source plugin +| + Breakout Board Configuration ############################### @@ -401,7 +440,7 @@ include a probe viewer, allowing you to visualize the probe layout and select th stream. Depending on the probe type, the following options, and a button to view the selected option in the probe viewer, may be available: -- *Electrodes*: Enabled selected electrodes, or view currently enabled electrodes. +- *Electrodes*: Enable selected electrodes, or view currently enabled electrodes. - *Electrode Preset*: Select an electrode preset for the probe. - *Reference*: The reference channel for the probe. - *AP Gain*: The gain for the AP channels (Neuropixels 1.0 only). @@ -469,6 +508,10 @@ This plugin can stream data from the following Neuropixels probe types: "**Probe**", "**Channels**", "**Plugin Version**" "Neuropixels 1.0", "384 AP, 384 LFP", "≥0.1.0" "Neuropixels 2.0 (quad-shank)", "384 wideband", "≥0.1.0" + "Neuropixels 2.0 (single-shank)", "384 wideband", "≥0.3.0" + +.. note:: + For versions >= 0.3.0, if a probe is not compatible a pop-up window will explain that it cannot be configured. Neuropixels data streams --------------------------- @@ -532,7 +575,7 @@ folders/files for Neuropixel probes. :width: 500 :align: center -If the checkbox is checked, it will disable to ability to manually choose calibration files, but the +If the checkbox is checked, it will disable the ability to manually choose calibration files, but the selected file will still be displayed in the same location as if you had chosen the file manually. To choose the file manually, uncheck the checkbox and follow the instructions `above <#calibration-files>`_. @@ -591,4 +634,197 @@ channels: The quaternion data can be used to drive the commutator in the GUI, allowing for real-time commutation of the headstage. See :ref:`commutatorcontrol` for more information on how to use the commutator with the BNO055 IMU data. -| +Loading Data +============ + +There are two major platforms that can be used to load and process data recorded by the Open Ephys +GUI and the ONIX Source plugin. First is the `open-ephys-python-tools +`__ which is maintained by the Open Ephys GUI +team. The second is `SpikeInterface `__, which is oriented +towards Neuropixels recording/analysis but can be used for ephys from any source. + +.. note:: + For the following scripts, it is assumed that the :code:`DigitalIO` device is enabled. + +open-ephys-python-tools +######################### + +The Python tools can be installed by running the following line inside a Python virtual environment: + +.. code-block:: + + pip install open-ephys-python-tools + +The following script prints information about all the data streams recorded by the first record node +in your signal chain during a single acquisition session: + +.. code-block:: python + + from open_ephys.analysis.session import Session + + # Point to the top-level data directory (the parent folder containing the Record Node folder(s)) + session = Session('./path/to/data') + + if session.recordnodes is None: + raise ValueError("No valid Record Nodes found.") + + # List all record nodes + for node in session.recordnodes: + print(node) + + # Iterate through each experiment (recording) in the first record node + node = session.recordnodes[0] + for recording in node.recordings: + print(f"\nExperiment {recording.experiment_index}") + + if recording.continuous is None: + print("No continuous channels found.") + continue + + for stream in recording.continuous: + print(f" Stream: {stream.metadata.stream_name}") + print(f" Sample rate: {stream.metadata.sample_rate} Hz") + print(f" Channels: {stream.samples.shape[1]}") + +To load samples from a stream, call :code:`samples[]` on the stream variable. Similarly, the +timestamps can be loaded by calling :code:`timestamps[]` on the stream. + +.. code-block:: python + + from open_ephys.analysis.session import Session + + session = Session('./path/to/data') + node = session.recordnodes[0] + recording = node.recordings[0] + stream = recording.continuous[0] # There must be at least one continuous stream to load from index 0 + + samples = stream.samples[:,0] # Get all samples from the first channel + timestamps = stream.timestamps # Get all timestamps + +The following script shows how to extract event markers from event channels and overlay them on top +of continuous traces. In this example, the DigitalIO continuous and event streams are assumed to be +recorded. Any time-synchronized channel recorded by the ONIX Source plugin will have the same +timestamps and can be overlaid. + +.. code-block:: python + + from open_ephys.analysis.session import Session + import matplotlib.pyplot as plt + + session = Session('/path/to/data') + node = session.recordnodes[0] + recording = node.recordings[0] + digital_io = recording.continuous["BreakoutBoard-DigitalIO"] + + plt.figure() + + stream_name = 'BreakoutBoard-DigitalIO' + + plt.plot(digital_io.timestamps, digital_io.samples[:,7]) # Channel 8 [index 7] assumed to be the channel with incoming changes + + plt.title(f"{digital_io.name.split('.')[1][:-1]}") + + for i, event in recording.events.iterrows(): # type: ignore + if event['stream_name'] == stream_name: + if event['state'] == 1: + start = event['timestamp'] + plt.axvline(x=start, color='r') + + elif event['state'] == 0: + end = event['timestamp'] + plt.axvline(x=end, color='g') + + plt.show() + +SpikeInterface +######################### + +SpikeInterface is a Python package specialized for loading and analyzing Neuropixels data, as well +as other forms of ephys data. SpikeInterface v0.103.1+ and ProbeInterface V0.3.1+ support reading +data from the ONIX Source plugin. + +.. note:: + ONIX Source plugin v0.3.0+ is required to correctly integrate Neuropixels metadata; recordings + saved prior to v0.3.0 will not correctly load certain metadata, such as the Neuropixels sample + shifts. + +SpikeInterface can be installed by running the following line inside a Python virtual environment: + +.. code-block:: + + pip install spikeinterface + +The following script shows how to list all available streams in a Record Node folder. + +.. code-block:: python + + import spikeinterface.extractors as se + + folder_path = '/path/to/data' + + # List all available streams without loading any data + stream_names, stream_ids = se.OpenEphysBinaryRecordingExtractor.get_streams(folder_path) + print("Available streams:") + for i, name in enumerate(stream_names): + print(f" {i}: {name}") + +Once the stream ID or stream name is known, the following script can be used to load the chosen +stream. It is assumed that the Record Node directory is the same as the GUI data directory. If the +Record Node directory was modified separately from the GUI directory, the metadata file will not be +automatically discovered. + +.. code-block:: python + + import spikeinterface.extractors as se + + folder_path = '/path/to/data' + + # Load a specific stream by ID (replace with your actual stream ID from the list above) + recording = se.read_openephys(folder_path, stream_id='0') + + print(f"\nChannels: {recording.get_num_channels()}") + print(f"Sampling rate: {recording.get_sampling_frequency()} Hz") + print(f"Duration: {recording.get_total_duration():.2f} s") + +For recordings with multiple experiments, use the :code:`block_index` parameter to select which +experiment to load: + +.. code-block:: python + + import spikeinterface.extractors as se + + folder_path = '/path/to/data' + + # Determine how many experiments were recorded + n_blocks = se.OpenEphysBinaryRecordingExtractor.get_num_blocks(folder_path) + print(f"Number of experiments: {n_blocks}") + + for block_index in range(n_blocks): + recording = se.read_openephys( + folder_path, + stream_id='2', + block_index=block_index + ) + print(f"Experiment {block_index}: {recording.get_total_duration():.2f} s") + +Additional Plugin Integration +=============================== + +Neuropixels-CAR +################## + +Neuropixels probe streams are automatically detected by the :ref:`neuropixelscar` plugin, which uses +a Common Average Reference across the specific groups of channels belonging to the same ADC. + +.. note:: Requires Onix Source plugin v0.3.0+. + +LFP Viewer +################## + +Neuropixels probe streams in the :ref:`lfpviewer` can be sorted by depth, according to the electrode +metadata defined by the ProbeInterface specification above. Additionally, the channels can be +colored by shank, to visually indicate when a channel belongs to a different shank than its +neighbor. + +.. note:: Requires Onix Source plugin v0.3.0+. + diff --git a/source/User-Manual/Plugins/XDAQ-OE.rst b/source/User-Manual/Plugins/XDAQ-OE.rst index e441efd2..2e41e388 100644 --- a/source/User-Manual/Plugins/XDAQ-OE.rst +++ b/source/User-Manual/Plugins/XDAQ-OE.rst @@ -19,7 +19,7 @@ XDAQ "*Source Code*", "https://github.com/open-ephys-plugins/XDAQ-OE" -.. tip:: For more in-depth documentation on the XDAQ, please refer to the `XDAQ help site `__. +.. tip:: For more in-depth documentation on the XDAQ, please refer to the `XDAQ help site `__. Plugin configuration ==================== diff --git a/source/conf.py b/source/conf.py index 5891fc5d..4d06bfca 100644 --- a/source/conf.py +++ b/source/conf.py @@ -238,7 +238,8 @@ 'https://labstreaminglayer.org/#/', 'https://discord.gg/jmnneS85CY', 'https://store-usa.arduino.cc/*', - 'https://openbci.com/*' + 'https://openbci.com/*', + 'https://ftdichip.com/drivers/d3xx-drivers/' ] linkcheck_allowed_redirects = {