Skip to content

Commit

Permalink
Rearrange spec, update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
rly committed Jun 30, 2024
1 parent 1868478 commit d0d3ecc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 92 deletions.
93 changes: 54 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,14 @@ classDiagram
direction LR
class ExtracellularSeries {
<<ElectricalSeries>>
<<TimeSeries>>
data : numeric
--> unit : str = "microvolts"
channels : DynamicTableRegion
--> target : ChannelsTable
channel_conversion : List[float], optional
--> axis : int = 1
}
class ChannelsTable{
Expand All @@ -94,38 +98,46 @@ classDiagram
description : str
probe : ProbeModel
probe_insertion : ProbeInsertion, optional
contacts : DynamicTableRegion, optional?
--> target : ContactsTable
reference_contact : DynamicTableRegion, optional
--> target : ContactsTable
reference_mode : Literal["external wire", ...], optional
position_reference : str, optional
reference_mode : str, optional
position_confirmation_method : str, optional
--------------------------------------
columns
--------------------------------------
id : int
filter : VectorData, optional
---> Values strings such as "Bandpass 0-300 Hz".
contact_position [x, y, z] : VectorData, optional
---> Each value is length 3 tuple of floats.
brain_area : VectorData, optional
--> data : str
----> Plays the role of the old 'location'.
... Any other custom columns, such analong frontend e.g. ADC information
id : VectorData[int]
contact : DynamicTableRegion, optional
--> 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 : Tuple[float, float, float], optional
----> Stereotactic coordinates on surface.
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
insertion_angle : Tuple[float, float, float], optional
----> The pitch/roll/yaw relative to the position on the surface.
}
namespace ProbeInterface{
namespace ProbeInterface {
class Probe {
<<Device>>
Expand All @@ -135,16 +147,17 @@ classDiagram
}
class ProbeModel {
<<Not sure what type>>
<<Device>>
name : str
manufacturer : str
model : str
contour : List[Tuple[float, float], Tuple[float, float, float]]
contact_table : ContactsTable
ndim : int, optional
planar_contour_in_um : List[Tuple[float, float], Tuple[float, float, float]], optional
contacts_table : ContactsTable
}
class ContactTable {
class ContactsTable {
<<DynamicTable>>
--------------------------------------
Expand All @@ -156,23 +169,25 @@ classDiagram
--------------------------------------
columns
--------------------------------------
id : int
shape : str, optional
size : str, optional
shank_id : str, optional
relative_position : List[Tuple[float, float], Tuple[float, float, float]], optional
id : VectorData[int]
relative_position_in_mm : List[Tuple[float, float], Tuple[float, float, float]]
--> reference : str, optional
contact_id : VectorData[str], optional
device_channel : VectorData[int], 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
}
}
ExtracellularSeries ..> ChannelsTable : links with channels
ProbeModel *--> ContactTable : contains
Probe *..> ProbeModel : links with probe_model
ChannelsTable *..> Probe : links with probe
ChannelsTable ..> ContactTable : links with contacts
Probe *..> ProbeModel : links to probe_model
ProbeModel *--> ContactsTable : contains
ExtracellularSeries ..> ChannelsTable : links to channels
ChannelsTable *..> Probe : links to probe
ChannelsTable ..> ContactTable : links to contacts
ChannelsTable *--> ProbeInsertion: might contain ProbeInsertion
note for ChannelsTable "ChannelsTable is no longer global"
```
Expand Down
44 changes: 22 additions & 22 deletions spec/ndx-extracellular-channels.extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,21 @@ groups:
(first element), which direction is positive in the y direction (second element),
etc.
required: false
- name: shape
neurodata_type_inc: VectorData
dtype: text
doc: Shape of the contact; e.g. 'circle'
- name: contact_id
neurodata_type_inc: VectorData
dtype: text
doc: Unique ID of the contact
quantity: '?'
- name: device_channel
neurodata_type_inc: VectorData
dtype: int
doc: 'Index of the channel connected to the contact on the device. Probes can
have a complex contact indexing system due to the probe layout. When they are
plugged into a recording device like an Open Ephys with an Intan headstage,
the channel order can be mixed again. So the physical contact channel index
is rarely the channel index on the device. See the probeinterface tutorial on
automatic wiring for an example: https://probeinterface.readthedocs.io/en/main/examples/ex_11_automatic_wiring.html#sphx-glr-examples-ex-11-automatic-wiring-py'
quantity: '?'
- name: shank_id
neurodata_type_inc: VectorData
dtype: text
Expand All @@ -61,6 +67,10 @@ groups:
doc: The axes defining the contact plane. See 'contact_plane_axes' in https://probeinterface.readthedocs.io/en/main/format_spec.html
for more details.
quantity: '?'
- name: shape
neurodata_type_inc: VectorData
dtype: text
doc: Shape of the contact; e.g. 'circle'
- name: radius_in_um
neurodata_type_inc: VectorData
dtype: float
Expand All @@ -76,16 +86,6 @@ groups:
dtype: float
doc: Height of a rectangular contact, in micrometers.
quantity: '?'
- name: device_channel
neurodata_type_inc: VectorData
dtype: int
doc: 'Index of the channel connected to the contact on the device. Probes can
have a complex contact indexing system due to the probe layout. When they are
plugged into a recording device like an Open Ephys with an Intan headstage,
the channel order can be mixed again. So the physical contact channel index
is rarely the channel index on the device. See the probeinterface tutorial on
automatic wiring for an example: https://probeinterface.readthedocs.io/en/main/examples/ex_11_automatic_wiring.html#sphx-glr-examples-ex-11-automatic-wiring-py'
quantity: '?'
- neurodata_type_def: ProbeModel
neurodata_type_inc: Device
doc: Neural probe object, compatible with the ProbeInterface specification. The
Expand Down Expand Up @@ -157,6 +157,14 @@ groups:
in millimeters. + is up. Coordinate is relative to the zero-point described
in `position_reference`.
required: false
- name: depth_in_mm
dtype: float
doc: Depth that the probe was driven along `insertion_angle` starting from `insertion_position_ap_in_mm`
and `insertion_position_ml_in_mm`, in millimeters. This is an alternate method
of providing the dorsal-ventral coordinate of the probe insertion site. If both
`insertion_position_dv_in_mm` and `depth_in_mm` are provided, the values should
be consistent.
required: false
- name: position_reference
dtype: text
doc: Location of the origin (0, 0, 0) for `insertion_position_{X}_in_mm` coordinates,
Expand Down Expand Up @@ -190,14 +198,6 @@ groups:
side downward). Zero is defined as the probe being parallel to a coronal slice
of the brain. '
required: false
- name: depth_in_mm
dtype: float
doc: Depth that the probe was driven along `insertion_angle` starting from `insertion_position_ap_in_mm`
and `insertion_position_ml_in_mm`, in millimeters. This is an alternate method
of providing the dorsal-ventral coordinate of the probe insertion site. If both
`insertion_position_dv_in_mm` and `depth_in_mm` are provided, the values should
be consistent.
required: false
- neurodata_type_def: ChannelsTable
neurodata_type_inc: DynamicTable
default_name: ChannelsTable
Expand Down
62 changes: 31 additions & 31 deletions src/spec/create_extension_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,24 @@ def main():
],
),
NWBDatasetSpec(
name="shape",
name="contact_id", # id is already used by DynamicTable
neurodata_type_inc="VectorData",
doc="Shape of the contact; e.g. 'circle'",
doc="Unique ID of the contact",
dtype="text",
quantity="?",
),
NWBDatasetSpec(
name="contact_id", # id is already used by DynamicTable
# NOTE: cannot end this name with "_index" because it conflicts with ragged arrays
name="device_channel",
neurodata_type_inc="VectorData",
doc="Unique ID of the contact",
dtype="text",
doc=("Index of the channel connected to the contact on the device. "
"Probes can have a complex contact indexing system due to the probe layout. "
"When they are plugged into a recording device like an Open Ephys with an Intan headstage, "
"the channel order can be mixed again. So the physical contact channel index "
"is rarely the channel index on the device. See the probeinterface tutorial on automatic "
"wiring for an example: "
"https://probeinterface.readthedocs.io/en/main/examples/ex_11_automatic_wiring.html#sphx-glr-examples-ex-11-automatic-wiring-py"),
dtype="int",
quantity="?",
),
NWBDatasetSpec(
Expand All @@ -100,6 +108,12 @@ def main():
shape=[[None, 2, 2], [None, 2, 3]],
quantity="?",
),
NWBDatasetSpec(
name="shape",
neurodata_type_inc="VectorData",
doc="Shape of the contact; e.g. 'circle'",
dtype="text",
),
NWBDatasetSpec(
name="radius_in_um",
neurodata_type_inc="VectorData",
Expand All @@ -121,20 +135,6 @@ def main():
dtype="float",
quantity="?",
),
NWBDatasetSpec(
# NOTE: cannot end this name with "_index" because it conflicts with ragged arrays
name="device_channel",
neurodata_type_inc="VectorData",
doc=("Index of the channel connected to the contact on the device. "
"Probes can have a complex contact indexing system due to the probe layout. "
"When they are plugged into a recording device like an Open Ephys with an Intan headstage, "
"the channel order can be mixed again. So the physical contact channel index "
"is rarely the channel index on the device. See the probeinterface tutorial on automatic "
"wiring for an example: "
"https://probeinterface.readthedocs.io/en/main/examples/ex_11_automatic_wiring.html#sphx-glr-examples-ex-11-automatic-wiring-py"),
dtype="int",
quantity="?",
),
],
)

Expand Down Expand Up @@ -234,6 +234,18 @@ def main():
dtype="float",
required=False,
),
NWBAttributeSpec(
name="depth_in_mm",
doc=(
"Depth that the probe was driven along `insertion_angle` starting from "
"`insertion_position_ap_in_mm` and `insertion_position_ml_in_mm`, in millimeters. This is an "
"alternate method of providing the dorsal-ventral coordinate of the probe insertion site. If "
"both `insertion_position_dv_in_mm` and `depth_in_mm` are provided, the values should be "
"consistent."
),
dtype="float",
required=False,
),
NWBAttributeSpec(
name="position_reference",
doc=(
Expand Down Expand Up @@ -286,18 +298,6 @@ def main():
dtype="float",
required=False,
),
NWBAttributeSpec(
name="depth_in_mm",
doc=(
"Depth that the probe was driven along `insertion_angle` starting from "
"`insertion_position_ap_in_mm` and `insertion_position_ml_in_mm`, in millimeters. This is an "
"alternate method of providing the dorsal-ventral coordinate of the probe insertion site. If "
"both `insertion_position_dv_in_mm` and `depth_in_mm` are provided, the values should be "
"consistent."
),
dtype="float",
required=False,
),
],
)

Expand Down

0 comments on commit d0d3ecc

Please sign in to comment.