From ad04661992a20eaa046681603e4be3a2ff03ce89 Mon Sep 17 00:00:00 2001 From: Steph Prince <40640337+stephprince@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:18:20 -0800 Subject: [PATCH] make PatchClampSeries gain optional to match the schema (#1975) Co-authored-by: Ryan Ly --- CHANGELOG.md | 3 ++- src/pynwb/icephys.py | 33 +++++++++++++------------- tests/integration/hdf5/test_icephys.py | 21 ++++++++++++++++ tests/unit/test_icephys.py | 7 ++++++ 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 971c9d799..d0989e10e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ - Fixed bug in how `ElectrodeGroup.__init__` validates its `position` argument. @oruebel [#1770](https://github.com/NeurodataWithoutBorders/pynwb/pull/1770) - Changed `SpatialSeries.reference_frame` from required to optional as specified in the schema. @rly [#1986](https://github.com/NeurodataWithoutBorders/pynwb/pull/1986) -### Enhancements and minor changes` +### Enhancements and minor changes +- Made gain an optional argument for PatchClampSeries to match the schema. @stephprince [#1975](https://github.com/NeurodataWithoutBorders/pynwb/pull/1975) - Added warning when writing files with `NWBHDF5IO` without the `.nwb` extension. @stephprince [#1978](https://github.com/NeurodataWithoutBorders/pynwb/pull/1978) ## PyNWB 2.8.2 (September 9, 2024) diff --git a/src/pynwb/icephys.py b/src/pynwb/icephys.py index 3101649fd..ec44a2bd8 100644 --- a/src/pynwb/icephys.py +++ b/src/pynwb/icephys.py @@ -109,7 +109,8 @@ class PatchClampSeries(TimeSeries): 'name': 'gain', 'type': float, 'doc': 'Units: Volt/Amp (v-clamp) or Volt/Volt (c-clamp)', - }, # required + 'default': None, + }, { 'name': 'stimulus_description', 'type': str, @@ -164,7 +165,7 @@ class CurrentClampSeries(PatchClampSeries): 'capacitance_compensation') @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required - {'name': 'gain', 'type': float, 'doc': 'Units - Volt/Volt'}, + {'name': 'gain', 'type': float, 'doc': 'Units - Volt/Volt', 'default': None}, *get_docval(PatchClampSeries.__init__, 'stimulus_description'), {'name': 'bias_current', 'type': float, 'doc': 'Unit - Amp', 'default': None}, {'name': 'bridge_balance', 'type': float, 'doc': 'Unit - Ohm', 'default': None}, @@ -196,7 +197,7 @@ class IZeroClampSeries(CurrentClampSeries): __nwbfields__ = () @docval(*get_docval(CurrentClampSeries.__init__, 'name', 'data', 'electrode'), # required - {'name': 'gain', 'type': float, 'doc': 'Units: Volt/Volt'}, # required + {'name': 'gain', 'type': float, 'doc': 'Units: Volt/Volt', 'default': None}, {'name': 'stimulus_description', 'type': str, 'doc': ('The stimulus name/protocol. Setting this to a value other than "N/A" is deprecated as of ' 'NWB 2.3.0.'), @@ -238,16 +239,16 @@ class CurrentClampStimulusSeries(PatchClampSeries): __nwbfields__ = () - @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode', 'gain'), # required - *get_docval(PatchClampSeries.__init__, 'stimulus_description', 'resolution', 'conversion', 'timestamps', - 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', - 'sweep_number', 'offset'), + @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required + *get_docval(PatchClampSeries.__init__, 'gain', 'stimulus_description', 'resolution', 'conversion', + 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', + 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'amperes')", 'default': 'amperes'}) def __init__(self, **kwargs): - name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) + name, data, unit, electrode = popargs('name', 'data', 'unit', 'electrode', kwargs) unit = ensure_unit(self, name, unit, 'amperes', '2.1.0') - super().__init__(name, data, unit, electrode, gain, **kwargs) + super().__init__(name, data, unit, electrode, **kwargs) @register_class('VoltageClampSeries', CORE_NAMESPACE) @@ -267,7 +268,7 @@ class VoltageClampSeries(PatchClampSeries): 'whole_cell_series_resistance_comp') @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required - {'name': 'gain', 'type': float, 'doc': 'Units - Volt/Amp'}, # required + {'name': 'gain', 'type': float, 'doc': 'Units - Volt/Amp', 'default': None}, *get_docval(PatchClampSeries.__init__, 'stimulus_description'), {'name': 'capacitance_fast', 'type': float, 'doc': 'Unit - Farad', 'default': None}, {'name': 'capacitance_slow', 'type': float, 'doc': 'Unit - Farad', 'default': None}, @@ -307,16 +308,16 @@ class VoltageClampStimulusSeries(PatchClampSeries): __nwbfields__ = () - @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode', 'gain'), # required - *get_docval(PatchClampSeries.__init__, 'stimulus_description', 'resolution', 'conversion', 'timestamps', - 'starting_time', 'rate', 'comments', 'description', 'control', 'control_description', - 'sweep_number', 'offset'), + @docval(*get_docval(PatchClampSeries.__init__, 'name', 'data', 'electrode'), # required + *get_docval(PatchClampSeries.__init__, 'gain', 'stimulus_description', 'resolution', 'conversion', + 'timestamps', 'starting_time', 'rate', 'comments', 'description', 'control', + 'control_description', 'sweep_number', 'offset'), {'name': 'unit', 'type': str, 'doc': "The base unit of measurement (must be 'volts')", 'default': 'volts'}) def __init__(self, **kwargs): - name, data, unit, electrode, gain = popargs('name', 'data', 'unit', 'electrode', 'gain', kwargs) + name, data, unit, electrode = popargs('name', 'data', 'unit', 'electrode', kwargs) unit = ensure_unit(self, name, unit, 'volts', '2.1.0') - super().__init__(name, data, unit, electrode, gain, **kwargs) + super().__init__(name, data, unit, electrode, **kwargs) @register_class('SweepTable', CORE_NAMESPACE) diff --git a/tests/integration/hdf5/test_icephys.py b/tests/integration/hdf5/test_icephys.py index 4fba6d28f..b50e5d9f5 100644 --- a/tests/integration/hdf5/test_icephys.py +++ b/tests/integration/hdf5/test_icephys.py @@ -66,6 +66,27 @@ def addContainer(self, nwbfile): nwbfile.add_device(self.device) super().addContainer(nwbfile) +class TestPatchClampSeriesMin(AcquisitionH5IOMixin, TestCase): + """ Test a PatchClampSeries with minimum required args to read/write """ + + def setUpElectrode(self): + """ Set up the test IntracellularElectrode """ + self.device = Device(name='device_name') + self.elec = IntracellularElectrode(name="elec0", description='a fake electrode object', + device=self.device) + + def setUpContainer(self): + self.setUpElectrode() + return PatchClampSeries(name="pcs", data=[1, 2, 3, 4, 5], unit='A', + starting_time=123.6, rate=10e3, electrode=self.elec) + + def addContainer(self, nwbfile): + """ + Add the test PatchClampSeries as an acquisition and IntracellularElectrode and Device to the given NWBFile + """ + nwbfile.add_icephys_electrode(self.elec) + nwbfile.add_device(self.device) + super().addContainer(nwbfile) class TestCurrentClampStimulusSeries(TestPatchClampSeries): diff --git a/tests/unit/test_icephys.py b/tests/unit/test_icephys.py index e0e8332f9..5ada7ec12 100644 --- a/tests/unit/test_icephys.py +++ b/tests/unit/test_icephys.py @@ -154,6 +154,13 @@ def test_default(self): self.assertEqual(pCS.electrode, electrode_name) self.assertEqual(pCS.gain, 1.0) + def test_gain_optional(self): + electrode_name = GetElectrode() + + pCS = PatchClampSeries('test_pCS', list(), 'unit', + electrode_name, timestamps=list()) + self.assertIsNone(pCS.gain) + def test_sweepNumber_valid(self): electrode_name = GetElectrode()