def _read_eventarray(self, node, parent): attributes = self._get_standard_attributes(node) times = self._get_quantity(node["times"]) labels = node["labels"].value event = Event(times=times, labels=labels, **attributes) event.segment = parent return event
def _read_eventarray(self, node, parent): attributes = self._get_standard_attributes(node) times = self._get_quantity(node["times"]) labels = node["labels"].value.astype('U') event = Event(times=times, labels=labels, **attributes) event.segment = parent return event
def create_event(self, parent=None, name='Event'): event = Event([1.0, 2.3, 4.1] * pq.s, np.array([chr(0) + 'trig1', chr(0) + 'trig2', chr(0) + 'trig3'])); event.segment = parent self._assign_basic_attributes(event, name=name) return event
def _read_eventarray(self, node, parent): attributes = self._get_standard_attributes(node) times = self._get_quantity(node["times"]) if self._lazy: labels = np.array((), dtype=node["labels"].dtype) else: labels = node["labels"].value event = Event(times=times, labels=labels, **attributes) event.segment = parent if self._lazy: event.lazy_shape = node["times"].shape return event
def _new_event(cls, signal, times=None, labels=None, units=None, name=None, file_origin=None, description=None, annotations=None, segment=None): ''' A function to map Event.__new__ to function that does not do the unit checking. This is needed for pickle to work. ''' e = Event(signal=signal, times=times, labels=labels, units=units, name=name, file_origin=file_origin, description=description, **annotations) e.segment = segment return e
def test__issue_285(self): # Spiketrain train = SpikeTrain([3, 4, 5] * pq.s, t_stop=10.0) unit = Unit() train.unit = unit unit.spiketrains.append(train) epoch = Epoch(np.array([0, 10, 20]), np.array([2, 2, 2]), np.array(["a", "b", "c"]), units="ms") blk = Block() seg = Segment() seg.spiketrains.append(train) seg.epochs.append(epoch) epoch.segment = seg blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.spiketrains[0].unit, Unit) self.assertIsInstance(r_seg.epochs[0], Epoch) os.remove('blk.pkl') # Epoch epoch = Epoch(times=np.arange(0, 30, 10) * pq.s, durations=[10, 5, 7] * pq.ms, labels=np.array(['btn0', 'btn1', 'btn2'], dtype='U')) epoch.segment = Segment() blk = Block() seg = Segment() seg.epochs.append(epoch) blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.epochs[0].segment, Segment) os.remove('blk.pkl') # Event event = Event(np.arange(0, 30, 10) * pq.s, labels=np.array(['trig0', 'trig1', 'trig2'], dtype='U')) event.segment = Segment() blk = Block() seg = Segment() seg.events.append(event) blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.events[0].segment, Segment) os.remove('blk.pkl') # IrregularlySampledSignal signal = IrregularlySampledSignal([0.0, 1.23, 6.78], [1, 2, 3], units='mV', time_units='ms') signal.segment = Segment() blk = Block() seg = Segment() seg.irregularlysampledsignals.append(signal) blk.segments.append(seg) blk.segments[0].block = blk reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.irregularlysampledsignals[0].segment, Segment) os.remove('blk.pkl')
def test_roundtrip(self): annotations = {"session_start_time": datetime.now()} # Define Neo blocks bl0 = Block(name='First block', **annotations) bl1 = Block(name='Second block', **annotations) bl2 = Block(name='Third block', **annotations) original_blocks = [bl0, bl1, bl2] num_seg = 4 # number of segments num_chan = 3 # number of channels for blk in original_blocks: for ind in range(num_seg): # number of Segments seg = Segment(index=ind) seg.block = blk blk.segments.append(seg) for seg in blk.segments: # AnalogSignal objects # 3 Neo AnalogSignals a = AnalogSignal(np.random.randn(44, num_chan) * pq.nA, sampling_rate=10 * pq.kHz, t_start=50 * pq.ms) b = AnalogSignal(np.random.randn(64, num_chan) * pq.mV, sampling_rate=8 * pq.kHz, t_start=40 * pq.ms) c = AnalogSignal(np.random.randn(33, num_chan) * pq.uA, sampling_rate=10 * pq.kHz, t_start=120 * pq.ms) # 2 Neo IrregularlySampledSignals d = IrregularlySampledSignal( np.arange(7.0) * pq.ms, np.random.randn(7, num_chan) * pq.mV) # 2 Neo SpikeTrains train = SpikeTrain(times=[1, 2, 3] * pq.s, t_start=1.0, t_stop=10.0) train2 = SpikeTrain(times=[4, 5, 6] * pq.s, t_stop=10.0) # todo: add waveforms # 1 Neo Event evt = Event(times=np.arange(0, 30, 10) * pq.ms, labels=np.array(['ev0', 'ev1', 'ev2'])) # 2 Neo Epochs epc = Epoch(times=np.arange(0, 30, 10) * pq.s, durations=[10, 5, 7] * pq.ms, labels=np.array(['btn0', 'btn1', 'btn2'])) epc2 = Epoch(times=np.arange(10, 40, 10) * pq.s, durations=[9, 3, 8] * pq.ms, labels=np.array(['btn3', 'btn4', 'btn5'])) seg.spiketrains.append(train) seg.spiketrains.append(train2) seg.epochs.append(epc) seg.epochs.append(epc2) seg.analogsignals.append(a) seg.analogsignals.append(b) seg.analogsignals.append(c) seg.irregularlysampledsignals.append(d) seg.events.append(evt) a.segment = seg b.segment = seg c.segment = seg d.segment = seg evt.segment = seg train.segment = seg train2.segment = seg epc.segment = seg epc2.segment = seg # write to file test_file_name = "test_round_trip.nwb" iow = NWBIO(filename=test_file_name, mode='w') iow.write_all_blocks(original_blocks) ior = NWBIO(filename=test_file_name, mode='r') retrieved_blocks = ior.read_all_blocks() self.assertEqual(len(retrieved_blocks), 3) self.assertEqual(len(retrieved_blocks[2].segments), num_seg) original_signal_22b = original_blocks[2].segments[2].analogsignals[1] retrieved_signal_22b = retrieved_blocks[2].segments[2].analogsignals[1] for attr_name in ("name", "units", "sampling_rate", "t_start"): retrieved_attribute = getattr(retrieved_signal_22b, attr_name) original_attribute = getattr(original_signal_22b, attr_name) self.assertEqual(retrieved_attribute, original_attribute) assert_array_equal(retrieved_signal_22b.magnitude, original_signal_22b.magnitude) original_issignal_22d = original_blocks[2].segments[ 2].irregularlysampledsignals[0] retrieved_issignal_22d = retrieved_blocks[2].segments[ 2].irregularlysampledsignals[0] for attr_name in ("name", "units", "t_start"): retrieved_attribute = getattr(retrieved_issignal_22d, attr_name) original_attribute = getattr(original_issignal_22d, attr_name) self.assertEqual(retrieved_attribute, original_attribute) assert_array_equal( retrieved_issignal_22d.times.rescale('ms').magnitude, original_issignal_22d.times.rescale('ms').magnitude) assert_array_equal(retrieved_issignal_22d.magnitude, original_issignal_22d.magnitude) original_event_11 = original_blocks[1].segments[1].events[0] retrieved_event_11 = retrieved_blocks[1].segments[1].events[0] for attr_name in ("name", ): retrieved_attribute = getattr(retrieved_event_11, attr_name) original_attribute = getattr(original_event_11, attr_name) self.assertEqual(retrieved_attribute, original_attribute) assert_array_equal( retrieved_event_11.rescale('ms').magnitude, original_event_11.rescale('ms').magnitude) assert_array_equal(retrieved_event_11.labels, original_event_11.labels) original_spiketrain_131 = original_blocks[1].segments[1].spiketrains[1] retrieved_spiketrain_131 = retrieved_blocks[1].segments[1].spiketrains[ 1] for attr_name in ("name", "t_start", "t_stop"): retrieved_attribute = getattr(retrieved_spiketrain_131, attr_name) original_attribute = getattr(original_spiketrain_131, attr_name) self.assertEqual(retrieved_attribute, original_attribute) assert_array_equal( retrieved_spiketrain_131.times.rescale('ms').magnitude, original_spiketrain_131.times.rescale('ms').magnitude) original_epoch_11 = original_blocks[1].segments[1].epochs[0] retrieved_epoch_11 = retrieved_blocks[1].segments[1].epochs[0] for attr_name in ("name", ): retrieved_attribute = getattr(retrieved_epoch_11, attr_name) original_attribute = getattr(original_epoch_11, attr_name) self.assertEqual(retrieved_attribute, original_attribute) assert_array_equal( retrieved_epoch_11.rescale('ms').magnitude, original_epoch_11.rescale('ms').magnitude) assert_allclose( retrieved_epoch_11.durations.rescale('ms').magnitude, original_epoch_11.durations.rescale('ms').magnitude) assert_array_equal(retrieved_epoch_11.labels, original_epoch_11.labels) os.remove(test_file_name)
def test__issue_285(self): # Spiketrain train = SpikeTrain([3, 4, 5] * pq.s, t_stop=10.0) unit = Unit() train.unit = unit unit.spiketrains.append(train) epoch = Epoch(np.array([0, 10, 20]), np.array([2, 2, 2]), np.array(["a", "b", "c"]), units="ms") blk = Block() seg = Segment() seg.spiketrains.append(train) seg.epochs.append(epoch) epoch.segment = seg blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.spiketrains[0].unit, Unit) self.assertIsInstance(r_seg.epochs[0], Epoch) os.remove('blk.pkl') # Epoch epoch = Epoch(times=np.arange(0, 30, 10) * pq.s, durations=[10, 5, 7] * pq.ms, labels=np.array(['btn0', 'btn1', 'btn2'], dtype='S')) epoch.segment = Segment() blk = Block() seg = Segment() seg.epochs.append(epoch) blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.epochs[0].segment, Segment) os.remove('blk.pkl') # Event event = Event(np.arange(0, 30, 10) * pq.s, labels=np.array(['trig0', 'trig1', 'trig2'], dtype='S')) event.segment = Segment() blk = Block() seg = Segment() seg.events.append(event) blk.segments.append(seg) reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.events[0].segment, Segment) os.remove('blk.pkl') # IrregularlySampledSignal signal = IrregularlySampledSignal( [0.0, 1.23, 6.78], [1, 2, 3], units='mV', time_units='ms') signal.segment = Segment() blk = Block() seg = Segment() seg.irregularlysampledsignals.append(signal) blk.segments.append(seg) blk.segments[0].block = blk reader = PickleIO(filename="blk.pkl") reader.write(blk) reader = PickleIO(filename="blk.pkl") r_blk = reader.read_block() r_seg = r_blk.segments[0] self.assertIsInstance(r_seg.irregularlysampledsignals[0].segment, Segment) os.remove('blk.pkl')
def read_segment(self, block_index=0, seg_index=0, lazy=False, signal_group_mode=None, load_waveforms=False, time_slice=None): """ :param block_index: int default 0. In case of several block block_index can be specified. :param seg_index: int default 0. Index of segment. :param lazy: False by default. :param signal_group_mode: 'split-all' or 'group-by-same-units' (default depend IO): This control behavior for grouping channels in AnalogSignal. * 'split-all': each channel will give an AnalogSignal * 'group-by-same-units' all channel sharing the same quantity units ar grouped in a 2D AnalogSignal :param load_waveforms: False by default. Control SpikeTrains.waveforms is None or not. :param time_slice: None by default means no limit. A time slice is (t_start, t_stop) both are quantities. All object AnalogSignal, SpikeTrain, Event, Epoch will load only in the slice. """ if signal_group_mode is None: signal_group_mode = self._prefered_signal_group_mode # annotations seg_annotations = dict( self.raw_annotations['blocks'][block_index]['segments'][seg_index]) for k in ('signals', 'units', 'events'): seg_annotations.pop(k) seg_annotations = check_annotations(seg_annotations) seg = Segment(index=seg_index, **seg_annotations) seg_t_start = self.segment_t_start(block_index, seg_index) * pq.s seg_t_stop = self.segment_t_stop(block_index, seg_index) * pq.s # get only a slice of objects limited by t_start and t_stop time_slice = (t_start, t_stop) if time_slice is None: t_start, t_stop = None, None t_start_, t_stop_ = None, None else: assert not lazy, 'time slice only work when not lazy' t_start, t_stop = time_slice t_start = ensure_second(t_start) t_stop = ensure_second(t_stop) # checks limits if t_start < seg_t_start: t_start = seg_t_start if t_stop > seg_t_stop: t_stop = seg_t_stop # in float format in second (for rawio clip) t_start_, t_stop_ = float(t_start.magnitude), float( t_stop.magnitude) # new spiketrain limits seg_t_start = t_start seg_t_stop = t_stop # AnalogSignal signal_channels = self.header['signal_channels'] if signal_channels.size > 0: channel_indexes_list = self.get_group_channel_indexes() for channel_indexes in channel_indexes_list: sr = self.get_signal_sampling_rate(channel_indexes) * pq.Hz sig_t_start = self.get_signal_t_start(block_index, seg_index, channel_indexes) * pq.s sig_size = self.get_signal_size( block_index=block_index, seg_index=seg_index, channel_indexes=channel_indexes) if not lazy: # in case of time_slice get: get i_start, i_stop, new sig_t_start if t_stop is not None: i_stop = int( (t_stop - sig_t_start).magnitude * sr.magnitude) if i_stop > sig_size: i_stop = sig_size else: i_stop = None if t_start is not None: i_start = int( (t_start - sig_t_start).magnitude * sr.magnitude) if i_start < 0: i_start = 0 sig_t_start += (i_start / sr).rescale('s') else: i_start = None raw_signal = self.get_analogsignal_chunk( block_index=block_index, seg_index=seg_index, i_start=i_start, i_stop=i_stop, channel_indexes=channel_indexes) float_signal = self.rescale_signal_raw_to_float( raw_signal, dtype='float32', channel_indexes=channel_indexes) for i, (ind_within, ind_abs) in self._make_signal_channel_subgroups( channel_indexes, signal_group_mode=signal_group_mode).items(): units = np.unique(signal_channels[ind_abs]['units']) assert len(units) == 1 units = ensure_signal_units(units[0]) if signal_group_mode == 'split-all': # in that case annotations by channel is OK chan_index = ind_abs[0] d = self.raw_annotations['blocks'][block_index][ 'segments'][seg_index]['signals'][chan_index] annotations = dict(d) if 'name' not in annotations: annotations['name'] = signal_channels['name'][ chan_index] else: # when channel are grouped by same unit # annotations are empty... annotations = {} annotations['name'] = 'Channel bundle ({}) '.format( ','.join(signal_channels[ind_abs]['name'])) annotations = check_annotations(annotations) if lazy: anasig = AnalogSignal(np.array([]), units=units, copy=False, sampling_rate=sr, t_start=sig_t_start, **annotations) anasig.lazy_shape = (sig_size, len(ind_within)) else: anasig = AnalogSignal(float_signal[:, ind_within], units=units, copy=False, sampling_rate=sr, t_start=sig_t_start, **annotations) seg.analogsignals.append(anasig) # SpikeTrain and waveforms (optional) unit_channels = self.header['unit_channels'] for unit_index in range(len(unit_channels)): if not lazy and load_waveforms: raw_waveforms = self.get_spike_raw_waveforms( block_index=block_index, seg_index=seg_index, unit_index=unit_index, t_start=t_start_, t_stop=t_stop_) float_waveforms = self.rescale_waveforms_to_float( raw_waveforms, dtype='float32', unit_index=unit_index) wf_units = ensure_signal_units( unit_channels['wf_units'][unit_index]) waveforms = pq.Quantity(float_waveforms, units=wf_units, dtype='float32', copy=False) wf_sampling_rate = unit_channels['wf_sampling_rate'][ unit_index] wf_left_sweep = unit_channels['wf_left_sweep'][unit_index] if wf_left_sweep > 0: wf_left_sweep = float( wf_left_sweep) / wf_sampling_rate * pq.s else: wf_left_sweep = None wf_sampling_rate = wf_sampling_rate * pq.Hz else: waveforms = None wf_left_sweep = None wf_sampling_rate = None d = self.raw_annotations['blocks'][block_index]['segments'][ seg_index]['units'][unit_index] annotations = dict(d) if 'name' not in annotations: annotations['name'] = unit_channels['name'][c] annotations = check_annotations(annotations) if not lazy: spike_timestamp = self.get_spike_timestamps( block_index=block_index, seg_index=seg_index, unit_index=unit_index, t_start=t_start_, t_stop=t_stop_) spike_times = self.rescale_spike_timestamp( spike_timestamp, 'float64') sptr = SpikeTrain(spike_times, units='s', copy=False, t_start=seg_t_start, t_stop=seg_t_stop, waveforms=waveforms, left_sweep=wf_left_sweep, sampling_rate=wf_sampling_rate, **annotations) else: nb = self.spike_count(block_index=block_index, seg_index=seg_index, unit_index=unit_index) sptr = SpikeTrain(np.array([]), units='s', copy=False, t_start=seg_t_start, t_stop=seg_t_stop, **annotations) sptr.lazy_shape = (nb, ) seg.spiketrains.append(sptr) # Events/Epoch event_channels = self.header['event_channels'] for chan_ind in range(len(event_channels)): if not lazy: ev_timestamp, ev_raw_durations, ev_labels = self.get_event_timestamps( block_index=block_index, seg_index=seg_index, event_channel_index=chan_ind, t_start=t_start_, t_stop=t_stop_) ev_times = self.rescale_event_timestamp( ev_timestamp, 'float64') * pq.s if ev_raw_durations is None: ev_durations = None else: ev_durations = self.rescale_epoch_duration( ev_raw_durations, 'float64') * pq.s ev_labels = ev_labels.astype('S') else: nb = self.event_count(block_index=block_index, seg_index=seg_index, event_channel_index=chan_ind) lazy_shape = (nb, ) ev_times = np.array([]) * pq.s ev_labels = np.array([], dtype='S') ev_durations = np.array([]) * pq.s d = self.raw_annotations['blocks'][block_index]['segments'][ seg_index]['events'][chan_ind] annotations = dict(d) if 'name' not in annotations: annotations['name'] = event_channels['name'][chan_ind] annotations = check_annotations(annotations) if event_channels['type'][chan_ind] == b'event': e = Event(times=ev_times, labels=ev_labels, units='s', copy=False, **annotations) e.segment = seg seg.events.append(e) elif event_channels['type'][chan_ind] == b'epoch': e = Epoch(times=ev_times, durations=ev_durations, labels=ev_labels, units='s', copy=False, **annotations) e.segment = seg seg.epochs.append(e) if lazy: e.lazy_shape = lazy_shape seg.create_many_to_one_relationship() return seg
def read_segment(self, block_index=0, seg_index=0, lazy=False, signal_group_mode=None, load_waveforms=False, time_slice=None): """ :param block_index: int default 0. In case of several block block_index can be specified. :param seg_index: int default 0. Index of segment. :param lazy: False by default. :param signal_group_mode: 'split-all' or 'group-by-same-units' (default depend IO): This control behavior for grouping channels in AnalogSignal. * 'split-all': each channel will give an AnalogSignal * 'group-by-same-units' all channel sharing the same quantity units ar grouped in a 2D AnalogSignal :param load_waveforms: False by default. Control SpikeTrains.waveforms is None or not. :param time_slice: None by default means no limit. A time slice is (t_start, t_stop) both are quantities. All object AnalogSignal, SpikeTrain, Event, Epoch will load only in the slice. """ if lazy: warnings.warn( "Lazy is deprecated and will be replaced by ProxyObject functionality.", DeprecationWarning) if signal_group_mode is None: signal_group_mode = self._prefered_signal_group_mode # annotations seg_annotations = dict(self.raw_annotations['blocks'][block_index]['segments'][seg_index]) for k in ('signals', 'units', 'events'): seg_annotations.pop(k) seg_annotations = check_annotations(seg_annotations) seg = Segment(index=seg_index, **seg_annotations) seg_t_start = self.segment_t_start(block_index, seg_index) * pq.s seg_t_stop = self.segment_t_stop(block_index, seg_index) * pq.s # get only a slice of objects limited by t_start and t_stop time_slice = (t_start, t_stop) if time_slice is None: t_start, t_stop = None, None t_start_, t_stop_ = None, None else: assert not lazy, 'time slice only work when not lazy' t_start, t_stop = time_slice t_start = ensure_second(t_start) t_stop = ensure_second(t_stop) # checks limits if t_start < seg_t_start: t_start = seg_t_start if t_stop > seg_t_stop: t_stop = seg_t_stop # in float format in second (for rawio clip) t_start_, t_stop_ = float(t_start.magnitude), float(t_stop.magnitude) # new spiketrain limits seg_t_start = t_start seg_t_stop = t_stop # AnalogSignal signal_channels = self.header['signal_channels'] if signal_channels.size > 0: channel_indexes_list = self.get_group_channel_indexes() for channel_indexes in channel_indexes_list: sr = self.get_signal_sampling_rate(channel_indexes) * pq.Hz sig_t_start = self.get_signal_t_start( block_index, seg_index, channel_indexes) * pq.s sig_size = self.get_signal_size(block_index=block_index, seg_index=seg_index, channel_indexes=channel_indexes) if not lazy: # in case of time_slice get: get i_start, i_stop, new sig_t_start if t_stop is not None: i_stop = int((t_stop - sig_t_start).magnitude * sr.magnitude) if i_stop > sig_size: i_stop = sig_size else: i_stop = None if t_start is not None: i_start = int((t_start - sig_t_start).magnitude * sr.magnitude) if i_start < 0: i_start = 0 sig_t_start += (i_start / sr).rescale('s') else: i_start = None raw_signal = self.get_analogsignal_chunk(block_index=block_index, seg_index=seg_index, i_start=i_start, i_stop=i_stop, channel_indexes=channel_indexes) float_signal = self.rescale_signal_raw_to_float( raw_signal, dtype='float32', channel_indexes=channel_indexes) for i, (ind_within, ind_abs) in self._make_signal_channel_subgroups( channel_indexes, signal_group_mode=signal_group_mode).items(): units = np.unique(signal_channels[ind_abs]['units']) assert len(units) == 1 units = ensure_signal_units(units[0]) if signal_group_mode == 'split-all': # in that case annotations by channel is OK chan_index = ind_abs[0] d = self.raw_annotations['blocks'][block_index]['segments'][seg_index][ 'signals'][chan_index] annotations = dict(d) if 'name' not in annotations: annotations['name'] = signal_channels['name'][chan_index] else: # when channel are grouped by same unit # annotations have channel_names and channel_ids array # this will be moved in array annotations soon annotations = {} annotations['name'] = 'Channel bundle ({}) '.format( ','.join(signal_channels[ind_abs]['name'])) annotations['channel_names'] = signal_channels[ind_abs]['name'] annotations['channel_ids'] = signal_channels[ind_abs]['id'] annotations = check_annotations(annotations) if lazy: anasig = AnalogSignal(np.array([]), units=units, copy=False, sampling_rate=sr, t_start=sig_t_start, **annotations) anasig.lazy_shape = (sig_size, len(ind_within)) else: anasig = AnalogSignal(float_signal[:, ind_within], units=units, copy=False, sampling_rate=sr, t_start=sig_t_start, **annotations) seg.analogsignals.append(anasig) # SpikeTrain and waveforms (optional) unit_channels = self.header['unit_channels'] for unit_index in range(len(unit_channels)): if not lazy and load_waveforms: raw_waveforms = self.get_spike_raw_waveforms(block_index=block_index, seg_index=seg_index, unit_index=unit_index, t_start=t_start_, t_stop=t_stop_) float_waveforms = self.rescale_waveforms_to_float(raw_waveforms, dtype='float32', unit_index=unit_index) wf_units = ensure_signal_units(unit_channels['wf_units'][unit_index]) waveforms = pq.Quantity(float_waveforms, units=wf_units, dtype='float32', copy=False) wf_sampling_rate = unit_channels['wf_sampling_rate'][unit_index] wf_left_sweep = unit_channels['wf_left_sweep'][unit_index] if wf_left_sweep > 0: wf_left_sweep = float(wf_left_sweep) / wf_sampling_rate * pq.s else: wf_left_sweep = None wf_sampling_rate = wf_sampling_rate * pq.Hz else: waveforms = None wf_left_sweep = None wf_sampling_rate = None d = self.raw_annotations['blocks'][block_index]['segments'][seg_index]['units'][ unit_index] annotations = dict(d) if 'name' not in annotations: annotations['name'] = unit_channels['name'][c] annotations = check_annotations(annotations) if not lazy: spike_timestamp = self.get_spike_timestamps(block_index=block_index, seg_index=seg_index, unit_index=unit_index, t_start=t_start_, t_stop=t_stop_) spike_times = self.rescale_spike_timestamp(spike_timestamp, 'float64') sptr = SpikeTrain(spike_times, units='s', copy=False, t_start=seg_t_start, t_stop=seg_t_stop, waveforms=waveforms, left_sweep=wf_left_sweep, sampling_rate=wf_sampling_rate, **annotations) else: nb = self.spike_count(block_index=block_index, seg_index=seg_index, unit_index=unit_index) sptr = SpikeTrain(np.array([]), units='s', copy=False, t_start=seg_t_start, t_stop=seg_t_stop, **annotations) sptr.lazy_shape = (nb,) seg.spiketrains.append(sptr) # Events/Epoch event_channels = self.header['event_channels'] for chan_ind in range(len(event_channels)): if not lazy: ev_timestamp, ev_raw_durations, ev_labels = self.get_event_timestamps( block_index=block_index, seg_index=seg_index, event_channel_index=chan_ind, t_start=t_start_, t_stop=t_stop_) ev_times = self.rescale_event_timestamp(ev_timestamp, 'float64') * pq.s if ev_raw_durations is None: ev_durations = None else: ev_durations = self.rescale_epoch_duration(ev_raw_durations, 'float64') * pq.s ev_labels = ev_labels.astype('S') else: nb = self.event_count(block_index=block_index, seg_index=seg_index, event_channel_index=chan_ind) lazy_shape = (nb,) ev_times = np.array([]) * pq.s ev_labels = np.array([], dtype='S') ev_durations = np.array([]) * pq.s d = self.raw_annotations['blocks'][block_index]['segments'][seg_index]['events'][ chan_ind] annotations = dict(d) if 'name' not in annotations: annotations['name'] = event_channels['name'][chan_ind] annotations = check_annotations(annotations) if event_channels['type'][chan_ind] == b'event': e = Event(times=ev_times, labels=ev_labels, units='s', copy=False, **annotations) e.segment = seg seg.events.append(e) elif event_channels['type'][chan_ind] == b'epoch': e = Epoch(times=ev_times, durations=ev_durations, labels=ev_labels, units='s', copy=False, **annotations) e.segment = seg seg.epochs.append(e) if lazy: e.lazy_shape = lazy_shape seg.create_many_to_one_relationship() return seg