https://github.com/catalystneuro/ndx-extracellular-channels
Science Score: 13.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (8.7%) to scientific vocabulary
Repository
Basic Info
- Host: GitHub
- Owner: catalystneuro
- License: bsd-3-clause
- Language: Python
- Default Branch: main
- Size: 20.5 KB
Statistics
- Stars: 0
- Watchers: 4
- Forks: 0
- Open Issues: 2
- Releases: 0
Metadata Files
README.md
ndx-extracellular-channels Extension for NWB
ndx-extracellular-channels is an extension of the NWB format to formally define information about neural probes as data types in NWB files. It comes with helper functions to easily construct ndx_extracellular_channels.Probe from probeinterface.Probe and vice versa.
It provides a new version of ElectricalSeries called ExtracellularSeries. Each ExtracellularSeries is associated with its own ChannelsTable that contains information about the channels and probe used to record the data. Each channel is mapped to contacts on the probe.
Use cases supported: - Storing the manufacturer, model, and serial number of the probe - Storing the size, shape, shank ID, and relative position of the contacts - Associating a channel with a contact on a probe - Storing multiple data streams (channels) from the same contacts on a probe, e.g., AP and LF bands from a Neuropixels probe - Storing a selection of channels from a probe, e.g., the probe model has 960 contacts and only 384 are used - Bipolar reference schemes, e.g., channel 1 is defined as the signal from contact 2 referenced to contact 1 - Storing precise information about the probe insertion position and orientation, separate from the targeted position and reconstructed position - Storing separate channel tables for different data streams instead of a global channel table, which avoids creating columns that apply only to some streams - Multiple instances of the same probe in the same file, e.g., a Neuropixels probe in the left and right hemispheres
It encompasses SpikeInterface's ndx-probeinterface extension and started originally as @D1o0g9s's ndx-probe-interface extension.
Installation
(TODO publish to PyPI)
python
pip install ndx_extracellular_channels
Usage
Going from a probeinterface.Probe/ProbeGroup object to a ndx_extracellular_channels.Probe object
```python import ndxextracellularchannels
piprobe = probeinterface.Probe(...) piprobegroup = probeinterface.ProbeGroup()
fromprobeinterface always returns a list of ndxextracellular_channels.Probe devices
ndxprobes1 = ndxextracellularchannels.fromprobeinterface(piprobe) ndxprobes2 = ndxextracellularchannels.fromprobeinterface(piprobegroup)
ndxprobes = ndxprobes1.extend(ndx_probes2)
nwbfile = pynwb.NWBFile(...)
add Probe as NWB Devices
for ndxprobe in ndxprobes: nwbfile.adddevice(ndxprobe) ```
Going from a ndx_extracellular_channels.Probe object to a probeinterface.Probe object
```python import ndxextracellularchannels
load ndxextracellularchannels.Probe objects from NWB file
io = pynwb.NWBH5IO(file_path, "r") nwbfile = io.read()
ndxprobes = [] for device in nwbfile: if isinstance(device, ndxextracellularchannels.Probe): ndxprobes.append(device)
convert to probeinterface.Probe objects
piprobes = [] for ndxprobe in ndxprobes: piprobe = ndxextracellularchannels.toprobeinterface(ndxprobe) piprobes.append(piprobe) ```
See src/pynwb/tests/test_example_usage_probeinterface.py for a full example.
Diagram
```mermaid %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%
classDiagram direction LR
class ExtracellularSeries {
<<TimeSeries>>
data : numeric
--> unit : str = "microvolts"
channels : DynamicTableRegion
--> target : ChannelsTable
channel_conversion : List[float], optional
--> axis : int = 1
}
class ChannelsTable {
<<DynamicTable>>
--------------------------------------
attributes
--------------------------------------
name : str
description : str
probe : Probe
position_reference : str, optional
electrical_reference_description : str, optional
ground : str, optional
position_confirmation_method : str, optional
--------------------------------------
columns
--------------------------------------
id : VectorData[int]
contact : DynamicTableRegion
--> target : ContactsTable
reference_contact : DynamicTableRegion, optional
--> target : ContactsTable
filter : VectorData[str], optional
---> Strings such as "Bandpass 0-300 Hz".
estimated_position_ap_in_mm : VectorData[float], optional
estimated_position_ml_in_mm : VectorData[float], optional
estimated_position_dv_in_mm : VectorData[float], optional
estimated_brain_area : VectorData[str], optional
confirmed_position_ap_in_mm : VectorData[float], optional
confirmed_position_ml_in_mm : VectorData[float], optional
confirmed_position_dv_in_mm : VectorData[float], optional
confirmed_brain_area : VectorData[str], optional
... Any other custom columns, e.g., ADC information
}
class ProbeInsertion {
<<Container>>
insertion_position_ap_in_mm : float, optional
insertion_position_ml_in_mm : float, optional
insertion_position_dv_in_mm : float, optional
position_reference : str, optional
hemisphere : Literal["left", "right"], optional
insertion_angle_pitch_in_deg : float, optional
insertion_angle_roll_in_deg : float, optional
insertion_angle_yaw_in_deg : float, optional
depth_in_um : float, optional
}
namespace ProbeInterface {
class Probe {
<<Device>>
identifier : str
--> Usually the serial number
probe_model : ProbeModel
probe_insertion : ProbeInsertion, optional
}
class ProbeModel {
<<Device>>
name : str
manufacturer : str
model : str
ndim : int, optional
planar_contour_in_um : List[Tuple[float, float], Tuple[float, float, float]], optional
contacts_table : ContactsTable
}
class ContactsTable {
<<DynamicTable>>
--------------------------------------
attributes
--------------------------------------
name : str
description : str
--------------------------------------
columns
--------------------------------------
id : VectorData[int]
relative_position_in_um : List[Tuple[float, float], Tuple[float, float, float]]
contact_id : VectorData[str], optional
shank_id : VectorData[str], optional
plane_axes : List[Tuple[int, int], Tuple[int, int, int]], optional
shape : VectorData[str], optional
radius_in_um : VectorData[float], optional
width_in_um : VectorData[float], optional
height_in_um : VectorData[float], optional
}
}
Probe *..> ProbeModel : links to probe_model
Probe *--> ProbeInsertion: might contain ProbeInsertion
ProbeModel *--> ContactsTable : contains
ExtracellularSeries ..> ChannelsTable : links to channels
ChannelsTable *..> Probe : links to probe
ChannelsTable ..> ContactsTable : row reference to contact
note for ChannelsTable "ChannelsTable is no longer global"
```
Ongoing work
- Publish on PyPI
- Incorporate this NDX into the core NWB schema via NWBEP002
Future plans
- Add information about the headstage used for data acquisition
This extension was created using ndx-template.
Owner
- Name: CatalystNeuro
- Login: catalystneuro
- Kind: organization
- Email: hello@catalystneuro.com
- Website: catalystneuro.com
- Twitter: catalystneuro
- Repositories: 87
- Profile: https://github.com/catalystneuro
GitHub Events
Total
- Issues event: 1
- Issue comment event: 1
Last Year
- Issues event: 1
- Issue comment event: 1