def test_init(self): electrode_name = GetElectrode() vCS = VoltageClampSeries('test_vCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, timestamps=list()) self.assertEqual(vCS.name, 'test_vCS') self.assertEqual(vCS.unit, 'amperes') self.assertEqual(vCS.electrode, electrode_name) self.assertEqual(vCS.stimulus_description, "stimset") self.assertEqual(vCS.gain, 1.0) self.assertEqual(vCS.capacitance_fast, 2.0) self.assertEqual(vCS.capacitance_slow, 3.0) self.assertEqual(vCS.resistance_comp_bandwidth, 4.0) self.assertEqual(vCS.resistance_comp_correction, 5.0) self.assertEqual(vCS.resistance_comp_prediction, 6.0) self.assertEqual(vCS.whole_cell_capacitance_comp, 7.0) self.assertEqual(vCS.whole_cell_series_resistance_comp, 8.0)
def test_init(self): electrode_name = GetElectrode() vCS = VoltageClampSeries('test_vCS', 'a hypothetical source', list(), 'unit', electrode_name, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, timestamps=list()) self.assertEqual(vCS.name, 'test_vCS') self.assertEqual(vCS.source, 'a hypothetical source') self.assertEqual(vCS.unit, 'unit') self.assertEqual(vCS.electrode, electrode_name) self.assertEqual(vCS.gain, 1.0) self.assertEqual(vCS.capacitance_fast, 2.0) self.assertEqual(vCS.capacitance_slow, 3.0) self.assertEqual(vCS.resistance_comp_bandwidth, 4.0) self.assertEqual(vCS.resistance_comp_correction, 5.0) self.assertEqual(vCS.resistance_comp_prediction, 6.0) self.assertEqual(vCS.whole_cell_capacitance_comp, 7.0) self.assertEqual(vCS.whole_cell_series_resistance_comp, 8.0)
def setUpContainer(self): """ Return the test VoltageClampSeries to read/write """ self.setUpElectrode() return VoltageClampSeries(name="vcs", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=self.elec, gain=0.126, capacitance_fast=1.2, capacitance_slow=2.3, resistance_comp_bandwidth=3.45, resistance_comp_correction=4.5, resistance_comp_prediction=5.678, whole_cell_capacitance_comp=6.789, whole_cell_series_resistance_comp=0.7)
def create_icephys_stimulus_and_response(sweep_number, electrode, randomize_data): """ Internal helper function to construct a dummy stimulus and response pair representing an intracellular recording: :param sweep_number: Integer sweep number of the recording :type sweep_number: int :param electrode: Intracellular electrode used :type electrode: pynwb.icephys.IntracellularElectrode :param randomize_data: Randomize data values in the stimulus and response :type randomize_data: bool :returns: Tuple of VoltageClampStimulusSeries with the stimulus and VoltageClampSeries with the response. """ stimulus = VoltageClampStimulusSeries( name="ccss_" + str(sweep_number), data=[1, 2, 3, 4, 5] if not randomize_data else np.random.rand(10), starting_time=123.6 if not randomize_data else (np.random.rand() * 100), rate=10e3 if not randomize_data else int(np.random.rand() * 10) * 1000 + 1000., electrode=electrode, gain=0.1 if not randomize_data else np.random.rand(), sweep_number=sweep_number) # Create and ic-response response = VoltageClampSeries( name='vcs_' + str(sweep_number), data=[0.1, 0.2, 0.3, 0.4, 0.5] if not randomize_data else np.random.rand(10), conversion=1e-12, resolution=np.nan, starting_time=123.6 if not randomize_data else (np.random.rand() * 100), rate=20e3 if not randomize_data else int(np.random.rand() * 20) * 1000. + 1000., electrode=electrode, gain=0.02 if not randomize_data else np.random.rand(), capacitance_slow=100e-12, resistance_comp_correction=70.0 if not randomize_data else 70.0 + np.random.rand(), sweep_number=sweep_number) return stimulus, response
def test_unit_warning(self): electrode_name = GetElectrode() msg = "Unit for VoltageClampSeries 'test_vCS' is ignored and will be set to 'amperes' as per NWB 2.1.0." with self.assertWarnsWith(UserWarning, msg): vCS = VoltageClampSeries('test_vCS', list(), electrode_name, 1.0, "stimset", 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, timestamps=list(), unit='unit') self.assertEqual(vCS.unit, 'amperes')
ccss = CurrentClampStimulusSeries( name="ccss", source="command", data=[1, 2, 3, 4, 5], unit='A', starting_time=123.6, rate=10e3, electrode=elec, gain=0.02) nwbfile.add_stimulus(ccss) # Here, we will use :py:class:`~pynwb.icephys.VoltageClampSeries` to store voltage clamp # data and then add it to our NWBFile as acquired data using the :py:class:`~pynwb.file.NWBFile` method # :py:meth:`~pynwb.file.NWBFile.add_acquisition`. from pynwb.icephys import VoltageClampSeries vcs = VoltageClampSeries( name='vcs', source="command", data=[0.1, 0.2, 0.3, 0.4, 0.5], unit='A', conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=elec, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, capacitance_fast=np.nan, resistance_comp_bandwidth=np.nan, resistance_comp_prediction=np.nan, whole_cell_capacitance_comp=np.nan, whole_cell_series_resistance_comp=np.nan) nwbfile.add_acquisition(vcs) #################### # .. _icephys_writing: # # Once you have finished adding all of your data to the :py:class:`~pynwb.file.NWBFile`, # write the file with :py:class:`~pynwb.NWBHDF5IO`. from pynwb import NWBHDF5IO io = NWBHDF5IO('icephys_example.nwb', 'w') io.write(nwbfile)
def create_acquisition_series(self, electrode): series = [] for sweep_name in self.nwb_data.get_sweep_names(): sweep_number = self.nwb_data.get_sweep_number(sweep_name) acquisition = self.nwb_data.get_acquisition(sweep_number) stim_code = self.nwb_data.get_stim_code(sweep_number) stim_code_ext = self.get_stim_code_ext(stim_code, sweep_number) scale_factor = self.notebook.get_value("Scale Factor", sweep_number, None) clamp_mode = self.get_clamp_mode(sweep_number) if clamp_mode == self.V_CLAMP_MODE: acquisition_series = VoltageClampSeries( name=sweep_name, sweep_number=sweep_number, data=acquisition['data'], unit=acquisition['unit'], conversion=acquisition['conversion'], resolution=np.nan, starting_time=np.nan, rate=acquisition['rate'], electrode=electrode, gain=scale_factor, capacitance_slow=np.nan, resistance_comp_correction=np.nan, capacitance_fast=np.nan, resistance_comp_bandwidth=np.nan, resistance_comp_prediction=np.nan, comments=acquisition['comment'], whole_cell_capacitance_comp=np.nan, whole_cell_series_resistance_comp=np.nan, stimulus_description=stim_code_ext) elif clamp_mode == self.I_CLAMP_MODE: bridge_balance = self.notebook.get_value( "Bridge Bal Value", sweep_number, np.nan) bias_current = self.notebook.get_value("I-Clamp Holding Level", sweep_number, np.nan) acquisition_series = CurrentClampSeries( name=sweep_name, sweep_number=sweep_number, data=acquisition['data'], unit=acquisition['unit'], conversion=acquisition['conversion'], resolution=np.nan, starting_time=np.nan, rate=acquisition['rate'], comments=acquisition['comment'], electrode=electrode, gain=scale_factor, bias_current=bias_current, bridge_balance=bridge_balance, stimulus_description=stim_code_ext, capacitance_compensation=np.nan) series.append(acquisition_series) return series
nwbfile.add_stimulus(ccss) ####################### # Here, we will use :py:class:`~pynwb.icephys.VoltageClampSeries` to store voltage clamp # data and then add it to our NWBFile as acquired data using the :py:class:`~pynwb.file.NWBFile` method # :py:meth:`~pynwb.file.NWBFile.add_acquisition`. from pynwb.icephys import VoltageClampSeries vcs = VoltageClampSeries(name='vcs', data=[0.1, 0.2, 0.3, 0.4, 0.5], unit='A', conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=elec, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0, sweep_number=15) nwbfile.add_acquisition(vcs) #################### # If you are interested in all PatchClampSeries with a given sweep number, use get_series() # exposed via the :py:meth:`~pynwb.icephys.SweepTable.get_series` attribute. series = nwbfile.sweep_table.get_series(15) ####################
device=ex_device) # Create an ic-ephys stimulus ex_stimulus = VoltageClampStimulusSeries(name="stimulus", data=[1, 2, 3, 4, 5], starting_time=123.6, rate=10e3, electrode=ex_electrode, gain=0.02) # Create an ic-response ex_response = VoltageClampSeries(name='response', data=[0.1, 0.2, 0.3, 0.4, 0.5], conversion=1e-12, resolution=np.nan, starting_time=123.6, rate=20e3, electrode=ex_electrode, gain=0.02, capacitance_slow=100e-12, resistance_comp_correction=70.0) # (A) Add an intracellular recording to the file # NOTE: We can optionally define time-ranges for the stimulus/response via # the corresponding optional _start_index and _index_count parameters. # NOTE: It is allowed to add a recording with just a stimulus or a response # NOTE: We can add custom columns to any of our tables in steps (A)-(E) ex_ir_index = ex_nwbfile.add_intracellular_recording(electrode=ex_electrode, stimulus=ex_stimulus, response=ex_response) # (B) Add a list of sweeps to the simultaneous recordings table
def _addAcquisition(self): """ Adds an acquisition class as defined by PyNWB to the NWB File. Written for experiments conducted from a single channel. For multiple channels, refer to https://github.com/AllenInstitute/ipfx/blob/master/ipfx/x_to_nwb/ABFConverter.py """ for idx, abfFile in enumerate(self.abfFiles): if self.acquisitionChannelName is None: channelList = abfFile.adcNames channelIndices = range(len(channelList)) else: if self.acquisitionChannelName in abfFile.adcNames: channelList = abfFile.adcNames channelIndices = [channelList.index(self.acquisitionChannelName)] else: raise ValueError(f"Channel {self.acquisitionChannelName} could not be found.") for i in range(abfFile.sweepCount): for channelIndex in channelIndices: if self.debug: print(f"acquisition: abfFile={abfFile.abfFilePath}, sweep={i}, channelIndex={channelIndex}, channelName={channelList[channelIndex]}") # Collect data from pyABF abfFile.setSweep(i, channel=channelIndex) seriesName = f"Index_{idx}_{i}_{channelIndex}" responseGain = self.responseGain responseOffset = self.responseOffset data = abfFile.sweepY * responseGain + responseOffset conversion, unit = self._unitConversion(abfFile.sweepUnitsY) electrode = self.electrode resolution = np.nan starting_time = 0.0 rate = float(abfFile.dataRate) # Create a JSON file for the description field description = json.dumps({"file_name": os.path.basename(self.fileNames[idx]), "file_version": abfFile.abfVersionString, "sweep_number": i, "protocol": abfFile.protocol, "protocol_path": abfFile.protocolPath, "comments": self._getComments(abfFile)}, sort_keys=True, indent=4) # Create an acquisition class # Note: voltage input produces current output; current input produces voltage output data = createCompressedDataset(data) if self.clampMode == 1: acquisition = CurrentClampSeries(name=seriesName, data=data, sweep_number=i, electrode=electrode, gain=responseGain, resolution=resolution, conversion=conversion, starting_time=starting_time, rate=rate, unit=unit, description=description, bias_current=np.nan, bridge_balance=np.nan, capacitance_compensation=np.nan, ) elif self.clampMode == 0: acquisition = VoltageClampSeries(name=seriesName, data=data, sweep_number=i, electrode=electrode, gain=responseGain, resolution=resolution, conversion=conversion, starting_time=starting_time, rate=rate, unit=unit, description=description, capacitance_fast=np.nan, capacitance_slow=np.nan, resistance_comp_bandwidth=np.nan, resistance_comp_correction=np.nan, resistance_comp_prediction=np.nan, whole_cell_capacitance_comp=np.nan, whole_cell_series_resistance_comp=np.nan ) else: raise ValueError(f"Unsupported clamp mode {self.clampMode}") self.NWBFile.add_acquisition(acquisition)
def _addAcquisition(self): """ Adds an acquisition class as defined by PyNWB to the NWB File. Written for experiments conducted from a single channel. For multiple channels, refer to https://github.com/AllenInstitute/ipfx/blob/master/ipfx/x_to_nwb/ABFConverter.py """ sweepGlobal = 0 for idx, abfFile in enumerate(self.abfFiles): for i in range(abfFile.sweepCount): # Collect data from pyABF abfFile.setSweep(i) seriesName = "Index_" + str(i + sweepGlobal) data = abfFile.sweepY conversion, unit = self._unitConversion(abfFile.sweepUnitsY) electrode = self.electrode gain = 1.0 # hard coded for White Noise data resolution = np.nan starting_time = 0.0 rate = float(abfFile.dataRate) # Create a JSON file for the description field description = json.dumps( { "file_name": os.path.basename(self.fileNames[idx]), "file_version": abfFile.abfVersionString, "sweep_number": i, "protocol": abfFile.protocol, "protocol_path": abfFile.protocolPath, "comments": self._getComments(abfFile) }, sort_keys=True, indent=4) # Create an acquisition class # Note: voltage input produces current output; current input produces voltage output if self.clampMode == 0: acquisition = CurrentClampSeries( name=seriesName, data=data, sweep_number=i, unit=unit, electrode=electrode, gain=gain, resolution=resolution, conversion=conversion, starting_time=starting_time, rate=rate, description=description, bias_current=np.nan, bridge_balance=np.nan, capacitance_compensation=np.nan, ) elif self.clampMode == 1: acquisition = VoltageClampSeries( name=seriesName, data=data, sweep_number=i, unit=unit, electrode=electrode, gain=gain, resolution=resolution, conversion=conversion, starting_time=starting_time, rate=rate, description=description, capacitance_fast=np.nan, capacitance_slow=np.nan, resistance_comp_bandwidth=np.nan, resistance_comp_correction=np.nan, resistance_comp_prediction=np.nan, whole_cell_capacitance_comp=np.nan, whole_cell_series_resistance_comp=np.nan) self.NWBFile.add_acquisition(acquisition) sweepGlobal += abfFile.sweepCount return True