Esempio n. 1
0
 def get_probegroup(self):
     arr = self.get_property('contact_vector')
     if arr is None:
         positions = self.get_property('location')
         if positions is None:
             raise ValueError(
                 'There is not Probe attached to recording. use set_probe(...)'
             )
         else:
             warn(
                 'There is no Probe attached to this recording. Creating a dummy one with contact positions'
             )
             ndim = positions.shape[1]
             probe = Probe(ndim=ndim)
             probe.set_contacts(positions=positions,
                                shapes='circle',
                                shape_params={'radius': 5})
             probe.set_device_channel_indices(
                 np.arange(self.get_num_channels(), dtype='int64'))
             #  probe.create_auto_shape()
             probegroup = ProbeGroup()
             probegroup.add_probe(probe)
     else:
         probegroup = ProbeGroup.from_numpy(arr)
         for probe_index, probe in enumerate(probegroup.probes):
             contour = self.get_annotation(
                 f'probe_{probe_index}_planar_contour')
             if contour is not None:
                 probe.set_planar_contour(contour)
     return probegroup
Esempio n. 2
0
 def set_dummy_probe_from_locations(self,
                                    locations,
                                    shape="circle",
                                    shape_params={"radius": 1}):
     probe = Probe()
     probe.set_contacts(locations, shapes=shape, shape_params=shape_params)
     probe.set_device_channel_indices(np.arange(self.get_num_channels()))
     self.set_probe(probe, in_place=True)
    x = i // 8
    y = i % 8
    positions[i] = x, y
positions *= 20
positions[8:16, 1] -= 10

##############################################################################
# Now we can create a `Probe` object
#  and set the position and shape of each contact
#  
# The `ndim` argument indicates that the contact is 2d, so the positions have a (n_elec, 2) shape.
#  We can also define 3d probe with `ndim=3` and positions will have a (n_elec, 3) shape.
#  
# Note: `shapes` and `shape_params` could be arrays as well, indicating the shape for each contact separately.

probe = Probe(ndim=2, si_units='um')
probe.set_contacts(positions=positions, shapes='circle', shape_params={'radius': 5})

##############################################################################
#  `Probe` objects have fancy prints!

print(probe)

##############################################################################
# In addition to contacts, we can crate the planar contour (polygon) of the probe

polygon = [(-20, -30), (20, -110), (60, -30), (60, 190), (-20, 190)]
probe.set_planar_contour(polygon)

##############################################################################
#  If `pandas` is installed, the `Probe` object can be exported as a dataframe for a simpler view:
Esempio n. 4
0
def test_BaseRecording():
    num_seg = 2
    num_chan = 3
    num_samples = 30
    sampling_frequency = 10000
    dtype = 'int16'

    files_path = [f'test_base_recording_{i}.raw' for i in range(num_seg)]
    for i in range(num_seg):
        a = np.memmap(files_path[i],
                      dtype=dtype,
                      mode='w+',
                      shape=(num_samples, num_chan))
        a[:] = np.random.randn(*a.shape).astype(dtype)

    rec = BinaryRecordingExtractor(files_path, sampling_frequency, num_chan,
                                   dtype)
    print(rec)

    assert rec.get_num_segments() == 2
    assert rec.get_num_channels() == 3

    assert np.all(rec.ids_to_indices([0, 1, 2]) == [0, 1, 2])
    assert np.all(
        rec.ids_to_indices([0, 1, 2], prefer_slice=True) == slice(0, 3, None))

    # annotations / properties
    rec.annotate(yep='yop')
    assert rec.get_annotation('yep') == 'yop'

    rec.set_property('quality', [1., 3.3, np.nan])
    values = rec.get_property('quality')
    assert np.all(values[:2] == [
        1.,
        3.3,
    ])

    # dump/load dict
    d = rec.to_dict()
    rec2 = BaseExtractor.from_dict(d)
    rec3 = load_extractor(d)

    # dump/load json
    rec.dump_to_json('test_BaseRecording.json')
    rec2 = BaseExtractor.load('test_BaseRecording.json')
    rec3 = load_extractor('test_BaseRecording.json')

    # dump/load pickle
    rec.dump_to_pickle('test_BaseRecording.pkl')
    rec2 = BaseExtractor.load('test_BaseRecording.pkl')
    rec3 = load_extractor('test_BaseRecording.pkl')

    # cache to binary
    cache_folder = Path('./my_cache_folder')
    folder = cache_folder / 'simple_recording'
    rec.save(format='binary', folder=folder)
    rec2 = BaseExtractor.load_from_folder(folder)
    assert 'quality' in rec2.get_property_keys()
    # but also possible
    rec3 = BaseExtractor.load('./my_cache_folder/simple_recording')

    # cache to memory
    rec4 = rec3.save(format='memory')

    traces4 = rec4.get_traces(segment_index=0)
    traces = rec.get_traces(segment_index=0)
    assert np.array_equal(traces4, traces)

    # cache joblib several jobs
    rec.save(name='simple_recording_2', chunk_size=10, n_jobs=4)

    # set/get Probe only 2 channels
    probe = Probe(ndim=2)
    positions = [[0., 0.], [0., 15.], [0, 30.]]
    probe.set_contacts(positions=positions,
                       shapes='circle',
                       shape_params={'radius': 5})
    probe.set_device_channel_indices([2, -1, 0])
    probe.create_auto_shape()

    rec2 = rec.set_probe(probe, group_mode='by_shank')
    rec2 = rec.set_probe(probe, group_mode='by_probe')
    positions2 = rec2.get_channel_locations()
    assert np.array_equal(positions2, [[0, 30.], [0., 0.]])

    probe2 = rec2.get_probe()
    positions3 = probe2.contact_positions
    assert np.array_equal(positions2, positions3)

    # from probeinterface.plotting import plot_probe_group, plot_probe
    # import matplotlib.pyplot as plt
    # plot_probe(probe)
    # plot_probe(probe2)
    # plt.show()

    # test return_scale
    sampling_frequency = 30000
    traces = np.zeros((1000, 5), dtype='int16')
    rec_int16 = NumpyRecording([traces], sampling_frequency)
    assert rec_int16.get_dtype() == 'int16'
    print(rec_int16)
    traces_int16 = rec_int16.get_traces()
    assert traces_int16.dtype == 'int16'
    # return_scaled raise error when no gain_to_uV/offset_to_uV properties
    with pytest.raises(ValueError):
        traces_float32 = rec_int16.get_traces(return_scaled=True)
    rec_int16.set_property('gain_to_uV', [.195] * 5)
    rec_int16.set_property('offset_to_uV', [0.] * 5)
    traces_float32 = rec_int16.get_traces(return_scaled=True)
    assert traces_float32.dtype == 'float32'
Esempio n. 5
0
def toy_example(duration=10,
                num_channels=4,
                num_units=10,
                sampling_frequency=30000.0,
                num_segments=2,
                average_peak_amplitude=-100,
                upsample_factor=13,
                dumpable=False,
                dump_folder=None,
                seed=None):
    '''
    Creates toy recording and sorting extractors.

    Parameters
    ----------
    duration: float (or list if multi segment)
        Duration in s (default 10)
    num_channels: int
        Number of channels (default 4)
    num_units: int
        Number of units (default 10)
    sampling_frequency: float
        Sampling frequency (default 30000)
    num_segments: int default 2
        Number of segments.
    dumpable: bool
        If True, objects are dumped to file and become 'dumpable'
    dump_folder: str or Path
        Path to dump folder (if None, 'test' is used
    seed: int
        Seed for random initialization

    Returns
    -------
    recording: RecordingExtractor
        The output recording extractor. If dumpable is False it's a NumpyRecordingExtractor, otherwise it's an
        MdaRecordingExtractor
    sorting: SortingExtractor
        The output sorting extractor. If dumpable is False it's a NumpyRecordingExtractor, otherwise it's an
        NpzSortingExtractor
    '''

    if isinstance(duration, int):
        duration = float(duration)

    if isinstance(duration, float):
        durations = [duration] * num_segments
    else:
        durations = duration
        assert isinstance(duration, list)
        assert len(durations) == num_segments
        assert all(isinstance(d, float) for d in durations)

    assert num_channels > 0
    assert num_units > 0

    waveforms, geometry = synthesize_random_waveforms(
        num_units=num_units,
        num_channels=num_channels,
        average_peak_amplitude=average_peak_amplitude,
        upsample_factor=upsample_factor,
        seed=seed)

    unit_ids = np.arange(num_units, dtype='int64')

    traces_list = []
    times_list = []
    labels_list = []
    for segment_index in range(num_segments):
        times, labels = synthesize_random_firings(
            num_units=num_units,
            duration=durations[segment_index],
            sampling_frequency=sampling_frequency,
            seed=seed)
        times_list.append(times)
        labels_list.append(labels)

        traces = synthesize_timeseries(
            times,
            labels,
            unit_ids,
            waveforms,
            sampling_frequency,
            durations[segment_index],
            noise_level=10,
            waveform_upsample_factor=upsample_factor,
            seed=seed)
        traces_list.append(traces)

    sorting = NumpySorting.from_times_labels(times_list, labels_list,
                                             sampling_frequency)

    recording = NumpyRecording(traces_list, sampling_frequency)
    recording.annotate(is_filtered=True)

    probe = Probe(ndim=2)
    probe.set_contacts(positions=geometry,
                       shapes='circle',
                       shape_params={'radius': 5})
    probe.create_auto_shape(probe_type='rect', margin=20)
    probe.set_device_channel_indices(np.arange(num_channels, dtype='int64'))
    recording = recording.set_probe(probe)

    return recording, sorting
Esempio n. 6
0
shapes = np.array(['circle', 'square'] * 12)
shape_params = np.array([{'radius': 8}, {'width': 12}] * 12)

##############################################################################
#  The `plane_axes` argument handles the axis for each contact.
#  It can be used for contact-wise rotations.
#  `plane_axes` has a shape of (num_elec, 2, ndim)

plane_axes = [[[1 / np.sqrt(2), 1 / np.sqrt(2)],
               [-1 / np.sqrt(2), 1 / np.sqrt(2)]]] * n
plane_axes = np.array(plane_axes)

##############################################################################
#  Create the probe

probe = Probe(ndim=2, si_units='um')
probe.set_contacts(positions=positions,
                   plane_axes=plane_axes,
                   shapes=shapes,
                   shape_params=shape_params)
probe.create_auto_shape()

##############################################################################

plot_probe(probe)

##############################################################################
#  We can also use the `rotate_contacts` to make contact-wise rotations:

from probeinterface import generate_multi_columns_probe
from probeinterface import Probe
from probeinterface.plotting import plot_probe

##############################################################################
# First, let's create one 2d probe with 32 contacts:

n = 24
positions = np.zeros((n, 2))
for i in range(n):
    x = i // 8
    y = i % 8
    positions[i] = x, y
positions *= 20
positions[8:16, 1] -= 10

probe_2d = Probe(ndim=2, si_units='um')
probe_2d.set_contacts(positions=positions,
                      shapes='circle',
                      shape_params={'radius': 5})
probe_2d.create_auto_shape(probe_type='tip')

##############################################################################
# Let's transform it into a 3d probe.
#
# Here the axes are 'xz' so y will be 0 for all contacts.
# The shape of probe_3d.contact_positions is now (n_elec, 3)

probe_3d = probe_2d.to_3d(axes='xz')
print(probe_2d.contact_positions.shape)
print(probe_3d.contact_positions.shape)
probe2.rotate(theta=-35)
probe2.move([400, 0])
n = probe2.get_electrode_count()
rand_colors = np.random.rand(n, 3)
plot_probe(probe2,
           ax=ax,
           electrode_colors=rand_colors,
           probe_shape_kwargs={
               'facecolor': 'purple',
               'edgecolor': 'k',
               'lw': 0.5,
               'alpha': 0.2
           })

# and make some alien probes
probe3 = Probe()
positions = [[0, 0], [0, 50], [25, 77], [45, 27]]
shapes = ['circle', 'square', 'rect', 'circle']
params = [{
    'radius': 10
}, {
    'width': 30
}, {
    'width': 20,
    'height': 12
}, {
    'radius': 13
}]
probe3.set_electrodes(positions=positions, shapes=shapes, shape_params=params)
probe3.create_auto_shape(probe_type='rect')
probe3.rotate(theta=25)
def test_BaseRecording():
    num_seg = 2
    num_chan = 3
    num_samples = 30
    sampling_frequency = 10000
    dtype = 'int16'

    file_paths = [f'test_base_recording_{i}.raw' for i in range(num_seg)]
    for i in range(num_seg):
        a = np.memmap(file_paths[i],
                      dtype=dtype,
                      mode='w+',
                      shape=(num_samples, num_chan))
        a[:] = np.random.randn(*a.shape).astype(dtype)
    rec = BinaryRecordingExtractor(file_paths, sampling_frequency, num_chan,
                                   dtype)

    assert rec.get_num_segments() == 2
    assert rec.get_num_channels() == 3

    assert np.all(rec.ids_to_indices([0, 1, 2]) == [0, 1, 2])
    assert np.all(
        rec.ids_to_indices([0, 1, 2], prefer_slice=True) == slice(0, 3, None))

    # annotations / properties
    rec.annotate(yep='yop')
    assert rec.get_annotation('yep') == 'yop'

    rec.set_channel_groups([0, 0, 1])

    rec.set_property('quality', [1., 3.3, np.nan])
    values = rec.get_property('quality')
    assert np.all(values[:2] == [
        1.,
        3.3,
    ])

    # missing property
    rec.set_property('string_property', ["ciao", "bello"], ids=[0, 1])
    values = rec.get_property('string_property')
    assert values[2] == ""

    # setting an different type raises an error
    assert_raises(Exception,
                  rec.set_property,
                  key='string_property_nan',
                  values=["ciao", "bello"],
                  ids=[0, 1],
                  missing_value=np.nan)

    # int properties without missing values raise an error
    assert_raises(Exception,
                  rec.set_property,
                  key='int_property',
                  values=[5, 6],
                  ids=[1, 2])

    rec.set_property('int_property', [5, 6], ids=[1, 2], missing_value=200)
    values = rec.get_property('int_property')
    assert values.dtype.kind == "i"

    times0 = rec.get_times(segment_index=0)

    # dump/load dict
    d = rec.to_dict()
    rec2 = BaseExtractor.from_dict(d)
    rec3 = load_extractor(d)

    # dump/load json
    rec.dump_to_json('test_BaseRecording.json')
    rec2 = BaseExtractor.load('test_BaseRecording.json')
    rec3 = load_extractor('test_BaseRecording.json')

    # dump/load pickle
    rec.dump_to_pickle('test_BaseRecording.pkl')
    rec2 = BaseExtractor.load('test_BaseRecording.pkl')
    rec3 = load_extractor('test_BaseRecording.pkl')

    # dump/load dict - relative
    d = rec.to_dict(relative_to=".")
    rec2 = BaseExtractor.from_dict(d, base_folder=".")
    rec3 = load_extractor(d, base_folder=".")

    # dump/load json
    rec.dump_to_json('test_BaseRecording_rel.json', relative_to=".")
    rec2 = BaseExtractor.load('test_BaseRecording_rel.json', base_folder=".")
    rec3 = load_extractor('test_BaseRecording_rel.json', base_folder=".")

    # cache to binary
    cache_folder = Path('./my_cache_folder')
    folder = cache_folder / 'simple_recording'
    rec.save(format='binary', folder=folder)
    rec2 = BaseExtractor.load_from_folder(folder)
    assert 'quality' in rec2.get_property_keys()
    values = rec2.get_property('quality')
    assert values[0] == 1.
    assert values[1] == 3.3
    assert np.isnan(values[2])

    groups = rec2.get_channel_groups()
    assert np.array_equal(groups, [0, 0, 1])

    # but also possible
    rec3 = BaseExtractor.load('./my_cache_folder/simple_recording')

    # cache to memory
    rec4 = rec3.save(format='memory')

    traces4 = rec4.get_traces(segment_index=0)
    traces = rec.get_traces(segment_index=0)
    assert np.array_equal(traces4, traces)

    # cache joblib several jobs
    folder = cache_folder / 'simple_recording2'
    rec2 = rec.save(folder=folder, chunk_size=10, n_jobs=4)
    traces2 = rec2.get_traces(segment_index=0)

    # set/get Probe only 2 channels
    probe = Probe(ndim=2)
    positions = [[0., 0.], [0., 15.], [0, 30.]]
    probe.set_contacts(positions=positions,
                       shapes='circle',
                       shape_params={'radius': 5})
    probe.set_device_channel_indices([2, -1, 0])
    probe.create_auto_shape()

    rec_p = rec.set_probe(probe, group_mode='by_shank')
    rec_p = rec.set_probe(probe, group_mode='by_probe')
    positions2 = rec_p.get_channel_locations()
    assert np.array_equal(positions2, [[0, 30.], [0., 0.]])

    probe2 = rec_p.get_probe()
    positions3 = probe2.contact_positions
    assert np.array_equal(positions2, positions3)

    assert np.array_equal(probe2.device_channel_indices, [0, 1])

    # test save with probe
    folder = cache_folder / 'simple_recording3'
    rec2 = rec_p.save(folder=folder, chunk_size=10, n_jobs=2)
    rec2 = load_extractor(folder)
    probe2 = rec2.get_probe()
    assert np.array_equal(probe2.contact_positions, [[0, 30.], [0., 0.]])
    positions2 = rec_p.get_channel_locations()
    assert np.array_equal(positions2, [[0, 30.], [0., 0.]])
    traces2 = rec2.get_traces(segment_index=0)
    assert np.array_equal(traces2, rec_p.get_traces(segment_index=0))

    # from probeinterface.plotting import plot_probe_group, plot_probe
    # import matplotlib.pyplot as plt
    # plot_probe(probe)
    # plot_probe(probe2)
    # plt.show()

    # test return_scale
    sampling_frequency = 30000
    traces = np.zeros((1000, 5), dtype='int16')
    rec_int16 = NumpyRecording([traces], sampling_frequency)
    assert rec_int16.get_dtype() == 'int16'

    traces_int16 = rec_int16.get_traces()
    assert traces_int16.dtype == 'int16'
    # return_scaled raise error when no gain_to_uV/offset_to_uV properties
    with pytest.raises(ValueError):
        traces_float32 = rec_int16.get_traces(return_scaled=True)
    rec_int16.set_property('gain_to_uV', [.195] * 5)
    rec_int16.set_property('offset_to_uV', [0.] * 5)
    traces_float32 = rec_int16.get_traces(return_scaled=True)
    assert traces_float32.dtype == 'float32'

    # test with t_start
    rec = BinaryRecordingExtractor(file_paths,
                                   sampling_frequency,
                                   num_chan,
                                   dtype,
                                   t_starts=np.arange(num_seg) * 10.)
    times1 = rec.get_times(1)
    folder = cache_folder / 'recording_with_t_start'
    rec2 = rec.save(folder=folder)
    assert np.allclose(times1, rec2.get_times(1))

    # test with time_vector
    rec = BinaryRecordingExtractor(file_paths, sampling_frequency, num_chan,
                                   dtype)
    rec.set_times(np.arange(num_samples) / sampling_frequency + 30.,
                  segment_index=0)
    rec.set_times(np.arange(num_samples) / sampling_frequency + 40.,
                  segment_index=1)
    times1 = rec.get_times(1)
    folder = cache_folder / 'recording_with_times'
    rec2 = rec.save(folder=folder)
    assert np.allclose(times1, rec2.get_times(1))
    rec3 = load_extractor(folder)
    assert np.allclose(times1, rec3.get_times(1))
Esempio n. 10
0
def test_probe():
    positions = _dummy_posistion()

    probe = Probe(ndim=2, si_units='um')
    probe.set_electrodes(positions=positions,
                         shapes='circle',
                         shape_params={'radius': 5})
    probe.set_electrodes(positions=positions,
                         shapes='square',
                         shape_params={'width': 5})
    probe.set_electrodes(positions=positions,
                         shapes='rect',
                         shape_params={
                             'width': 8,
                             'height': 5
                         })

    assert probe.get_electrode_count() == 24

    # shape of the probe
    vertices = [(-20, -30), (20, -110), (60, -30), (60, 190), (-20, 190)]
    probe.set_planar_contour(vertices)

    # auto shape
    probe.create_auto_shape()

    # device channel
    chans = np.arange(0, 24, dtype='int')
    np.random.shuffle(chans)
    probe.set_device_channel_indices(chans)

    # electrode_ids int or str
    elec_ids = np.arange(24)
    probe.set_electrode_ids(elec_ids)
    elec_ids = [f'elec #{e}' for e in range(24)]
    probe.set_electrode_ids(elec_ids)

    # copy
    probe2 = probe.copy()

    # move rotate
    probe.move([20, 50])
    probe.rotate(theta=40, center=[0, 0], axis=None)

    # make annimage
    values = np.random.randn(24)
    image, xlims, ylims = probe.to_image(values, method='cubic')

    image2, xlims, ylims = probe.to_image(values, method='cubic', num_pixel=16)

    #~ from probeinterface.plotting import plot_probe_group, plot_probe
    #~ import matplotlib.pyplot as plt
    #~ fig, ax = plt.subplots()
    #~ plot_probe(probe, ax=ax)
    #~ ax.imshow(image, extent=xlims+ylims, origin='lower')
    #~ ax.imshow(image2, extent=xlims+ylims, origin='lower')
    #~ plt.show()

    # 3d
    probe_3d = probe.to_3d()
    probe_3d.rotate(theta=60, center=[0, 0, 0], axis=[0, 1, 0])

    #~ from probeinterface.plotting import plot_probe_group, plot_probe
    #~ import matplotlib.pyplot as plt
    #~ plot_probe(probe_3d)
    #~ plt.show()

    # get shanks
    for shank in probe.get_shanks():
        print(shank)
        print(shank.electrode_positions)

    # get dict and df
    d = probe.to_dict()
    #~ print(d)
    df = probe.to_dataframe()
    print(df)