Skip to content

Commit

Permalink
Improve eseries api for unit, fix value to microvolts
Browse files Browse the repository at this point in the history
  • Loading branch information
rly committed Jul 12, 2024
1 parent 80dd349 commit b294ba2
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 16 deletions.
10 changes: 5 additions & 5 deletions spec/ndx-extracellular-channels.extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,11 @@ groups:
attributes:
- name: unit
dtype: text
value: volts
value: microvolts
doc: Base unit of measurement for working with the data. This value is fixed
to 'volts'. Actual stored values are not necessarily stored in these units.
To access the data in these units, multiply 'data' by 'conversion', followed
by 'channel_conversion' (if present), and then add 'offset'.
to 'microvolts'. Actual stored values are not necessarily stored in these
units. To access the data in these units, multiply 'data' by 'conversion',
followed by 'channel_conversion' (if present), and then add 'offset'.
- name: channels
neurodata_type_inc: DynamicTableRegion
doc: DynamicTableRegion pointer to rows in a ChannelsTable that represent the
Expand All @@ -328,7 +328,7 @@ groups:
doc: Channel-specific conversion factor. Multiply the data in the 'data' dataset
by these values along the channel axis (as indicated by axis attribute) AND
by the global conversion factor in the 'conversion' attribute of 'data' to get
the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion.
the data values in microvolts, i.e, data in microvolts = data * data.conversion * channel_conversion.
This approach allows for both global and per-channel data conversion factors
needed to support the storage of electrical recordings as native values generated
by data acquisition systems. If this dataset is not present, then there is no
Expand Down
22 changes: 19 additions & 3 deletions src/pynwb/ndx_extracellular_channels/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from pynwb import get_class, load_namespaces
from hdmf.utils import docval, get_docval

from pynwb import get_class, load_namespaces, register_class

try:
from importlib.resources import files
Expand All @@ -24,7 +26,21 @@
ProbeModel = get_class("ProbeModel", "ndx-extracellular-channels")
Probe = get_class("Probe", "ndx-extracellular-channels")
ChannelsTable = get_class("ChannelsTable", "ndx-extracellular-channels")
ExtracellularSeries = get_class("ExtracellularSeries", "ndx-extracellular-channels")
AutoExtracellularSeries = get_class("ExtracellularSeries", "ndx-extracellular-channels")

init_dv = [dv for dv in get_docval(AutoExtracellularSeries.__init__) if dv["name"] != "unit"]


@register_class("ExtracellularSeries", "ndx-extracellular-channels")
class ExtracellularSeries(AutoExtracellularSeries):

@docval(*init_dv)
def __init__(self, **kwargs):
# NOTE: "unit" is a required constructor argument in the auto-generated class
# but it's value is fixed to "microvolts"
kwargs["unit"] = "microvolts"
super().__init__(**kwargs)


from .io import from_probeinterface, to_probeinterface

Expand All @@ -40,4 +56,4 @@
)

# Remove these functions from the package
del load_namespaces, get_class
del load_namespaces, get_class, init_dv
4 changes: 1 addition & 3 deletions src/pynwb/tests/test_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,6 @@ def test_constructor(self):
channel_conversion=[1.1],
conversion=1e5,
offset=0.001,
unit="volts", # TODO should not have to specify this in init
)

assert es.name == "ExtracellularSeries"
Expand All @@ -649,7 +648,7 @@ def test_constructor(self):
assert es.conversion == 1e5
assert es.offset == 0.001
# NOTE: the TimeSeries mapper maps spec "ExtracellularSeries/data/unit" to "ExtracellularSeries.unit"
assert es.unit == "volts"
assert es.unit == "microvolts"
assert es.timestamps_unit == "seconds"


Expand Down Expand Up @@ -694,7 +693,6 @@ def addContainer(self):
channel_conversion=[1.0, 1.1, 1.2],
conversion=1e5,
offset=0.001,
unit="volts", # TODO should not have to specify this in init
)
self.nwbfile.add_acquisition(es)

Expand Down
3 changes: 1 addition & 2 deletions src/pynwb/tests/test_example_usage_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ def test_all_classes():
channel_conversion=[1.0, 1.1, 1.2],
conversion=1e5,
offset=0.001,
unit="volts", # TODO should not have to specify this in init
)

nwbfile.add_acquisition(es)
Expand All @@ -171,7 +170,7 @@ def test_all_classes():
np.testing.assert_array_equal(read_eseries.channel_conversion[:], [1.0, 1.1, 1.2])
assert read_eseries.conversion == 1e5
assert read_eseries.offset == 0.001
assert read_eseries.unit == "volts"
assert read_eseries.unit == "microvolts"

assert read_channels_table.name == "Neuropixels1ChannelsTable"
assert read_channels_table.description == "Test channels table"
Expand Down
6 changes: 3 additions & 3 deletions src/spec/create_extension_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,11 @@ def main():
name="unit",
doc=(
"Base unit of measurement for working with the data. This value is fixed to "
"'volts'. Actual stored values are not necessarily stored in these units. To "
"'microvolts'. Actual stored values are not necessarily stored in these units. To "
"access the data in these units, multiply 'data' by 'conversion', followed by "
"'channel_conversion' (if present), and then add 'offset'."
),
value="volts",
value="microvolts",
dtype="text",
)
],
Expand All @@ -491,7 +491,7 @@ def main():
"Channel-specific conversion factor. Multiply the data in the 'data' dataset by these "
"values along the channel axis (as indicated by axis attribute) AND by the global "
"conversion factor in the 'conversion' attribute of 'data' to get the data values in "
"Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This "
"microvolts, i.e, data in microvolts = data * data.conversion * channel_conversion. This "
"approach allows for both global and per-channel data conversion factors needed "
"to support the storage of electrical recordings as native values generated by data "
"acquisition systems. If this dataset is not present, then there is no channel-specific "
Expand Down

0 comments on commit b294ba2

Please sign in to comment.