Exemple #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
 def set_probe(self, probe, group_mode='by_probe', in_place=False):
     """
     Wrapper on top on set_probes when there one unique probe.
     """
     assert isinstance(probe, Probe), 'must give Probe'
     probegroup = ProbeGroup()
     probegroup.add_probe(probe)
     return self.set_probes(probegroup, group_mode=group_mode, in_place=in_place)
Exemple #3
0
def test_probegroup_3d():
    probegroup = ProbeGroup()

    for i in range(3):
        probe = generate_dummy_probe().to_3d()
        probe.move([i * 100, i * 80, i * 30])
        probegroup.add_probe(probe)

    assert probegroup.ndim == 3
Exemple #4
0
def test_plot_probe_group():
    probegroup = generate_dummy_probe_group()

    plot_probe_group(probegroup, same_axe=True, with_channel_index=True)
    plot_probe_group(probegroup, same_axe=False)

    # 3d
    probegroup_3d = ProbeGroup()
    for probe in probegroup.probes:
        probegroup_3d.add_probe(probe.to_3d())
    probegroup_3d.probes[-1].move([0, 150, -50])
    plot_probe_group(probegroup_3d, same_axe=True)
Exemple #5
0
def test_probegroup():
    probegroup = ProbeGroup()

    for i in range(3):
        probe = generate_dummy_probe()
        probe.move([i * 100, i * 80])
        probegroup.add_probe(probe)

    indices = probegroup.get_global_device_channel_indices()
    ids = probegroup.get_global_electrode_ids()

    df = probegroup.to_dataframe()
Exemple #6
0
    def set_probes(self,
                   probe_or_probegroup,
                   group_mode='by_probe',
                   in_place=False):
        """
        Attach a Probe to a recording.
        For this Probe.device_channel_indices is used to link contacts to recording channels.
        If some contacts of the Probe are not connected (device_channel_indices=-1)
        then the recording is "sliced" and only connected channel are kept.

        The probe order is not kept. Channel ids are re-ordered to match the channel_ids of the recording.


        Parameters
        ----------
        probe_or_probegroup: Probe, list of Probe, or ProbeGroup
            The probe(s) to be attached to the recording

        group_mode: str
            'by_probe' or 'by_shank'. Adds grouping property to the recording based on the probes ('by_probe')
            or  shanks ('by_shanks')

        in_place: bool
            False by default.
            Useful internally when extractor do self.set_probegroup(probe)

        Returns
        -------
        sub_recording: BaseRecording
            A view of the recording (ChannelSliceRecording or clone or itself)
        """
        from spikeinterface import ChannelSliceRecording

        assert group_mode in (
            'by_probe',
            'by_shank'), "'group_mode' can be 'by_probe' or 'by_shank'"

        # handle several input possibilities
        if isinstance(probe_or_probegroup, Probe):
            probegroup = ProbeGroup()
            probegroup.add_probe(probe_or_probegroup)
        elif isinstance(probe_or_probegroup, ProbeGroup):
            probegroup = probe_or_probegroup
        elif isinstance(probe_or_probegroup, list):
            assert all([isinstance(e, Probe) for e in probe_or_probegroup])
            probegroup = ProbeGroup()
            for probe in probe_or_probegroup:
                probegroup.add_probe(probe)
        else:
            raise ValueError('must give Probe or ProbeGroup or list of Probe')

        # handle not connected channels
        assert all(probe.device_channel_indices is not None for probe in probegroup.probes), \
            'Probe must have device_channel_indices'

        # this is a vector with complex fileds (dataframe like) that handle all contact attr
        arr = probegroup.to_numpy(complete=True)

        # keep only connected contact ( != -1)
        keep = arr['device_channel_indices'] >= 0
        if np.any(~keep):
            warn(
                'The given probes have unconnected contacts: they are removed')

        arr = arr[keep]
        inds = arr['device_channel_indices']
        order = np.argsort(inds)
        inds = inds[order]
        # check
        if np.max(inds) >= self.get_num_channels():
            raise ValueError(
                'The given Probe have "device_channel_indices" that do not match channel count'
            )
        new_channel_ids = self.get_channel_ids()[inds]
        arr = arr[order]

        # create recording : channel slice or clone or self
        if in_place:
            if not np.array_equal(new_channel_ids, self.get_channel_ids()):
                raise Exception(
                    'set_proce(inplace=True) must have all channel indices')
            sub_recording = self
        else:
            if np.array_equal(new_channel_ids, self.get_channel_ids()):
                sub_recording = self.clone()
            else:
                sub_recording = ChannelSliceRecording(self, new_channel_ids)

        # create a vector that handle all conatcts in property
        sub_recording.set_property('contact_vector', arr, ids=None)
        # planar_contour is saved in annotations
        for probe_index, probe in enumerate(probegroup.probes):
            contour = probe.probe_planar_contour
            if contour is not None:
                sub_recording.set_annotation(
                    f'probe_{probe_index}_planar_contour',
                    contour,
                    overwrite=True)

        # duplicate positions to "locations" property
        ndim = probegroup.ndim
        locations = np.zeros((arr.size, ndim), dtype='float64')
        for i, dim in enumerate(['x', 'y', 'z'][:ndim]):
            locations[:, i] = arr[dim]
        sub_recording.set_property('location', locations, ids=None)

        # handle groups
        groups = np.zeros(arr.size, dtype='int64')
        if group_mode == 'by_probe':
            for group, probe_index in enumerate(np.unique(arr['probe_index'])):
                mask = arr['probe_index'] == probe_index
                groups[mask] = group
        elif group_mode == 'by_shank':
            assert all(probe.shank_ids is not None for probe in probegroup.probes), \
                'shank_ids is None in probe, you cannot group by shank'
            for group, a in enumerate(
                    np.unique(arr[['probe_index', 'shank_ids']])):
                mask = (arr['probe_index'] == a['probe_index']) & (
                    arr['shank_ids'] == a['shank_ids'])
                groups[mask] = group
        sub_recording.set_property('group', groups, ids=None)

        return sub_recording
from probeinterface.plotting import plot_probe_group
from probeinterface import generate_dummy_probe

##############################################################################
# Generate 2 dummy `Probe` objects with the utils function:
#

probe0 = generate_dummy_probe(elec_shapes='square')
probe1 = generate_dummy_probe(elec_shapes='circle')
probe1.move([250, -90])

##############################################################################
# Let's create a `ProbeGroup` and
# add the `Probe` objects into it:

probegroup = ProbeGroup()
probegroup.add_probe(probe0)
probegroup.add_probe(probe1)

print('probe0.get_electrode_count()', probe0.get_electrode_count())
print('probe1.get_electrode_count()', probe1.get_electrode_count())
print('probegroup.get_channel_count()', probegroup.get_channel_count())

##############################################################################
#  We can now plot all probes in the same axis:

plot_probe_group(probegroup, same_axe=True)

##############################################################################
#  or in separate axes:
##############################################################################
# Import

import numpy as np
import matplotlib.pyplot as plt

from probeinterface import Probe, ProbeGroup
from probeinterface.plotting import plot_probe, plot_probe_group

##############################################################################
# Generate 4 tetrodes:
# 

from probeinterface import generate_tetrode

probegroup = ProbeGroup()
for i in range(4):
    tetrode = generate_tetrode()
    tetrode.move([i * 50, 0])
    probegroup.add_probe(tetrode)
probegroup.set_global_device_channel_indices(np.arange(16))

df = probegroup.to_dataframe()
df

plot_probe_group(probegroup, with_channel_index=True, same_axes=True)

##############################################################################
# Generate a linear probe:
# 
Exemple #9
0
plot_probe(probe, with_channel_index=True)

##############################################################################
# Very often we have several probes on the device and this can lead to even
# more complex channel indices.
# `ProbeGroup.get_global_device_channel_indices()` gives an overview of the device wiring.

probe0 = generate_multi_columns_probe(num_columns=3,
                                      num_elec_per_column=[5, 6, 5],
                                      xpitch=75, ypitch=75, y_shift_per_column=[0, -37.5, 0],
                                      electrode_shapes='circle', electrode_shape_params={'radius': 12})
probe1 = probe0.copy()

probe1.move([350, 200])
probegroup = ProbeGroup()
probegroup.add_probe(probe0)
probegroup.add_probe(probe1)

# wire probe0 0 to 31 and shuffle
channel_indices0 = np.arange(16)
np.random.shuffle(channel_indices0)
probe0.set_device_channel_indices(channel_indices0)

# wire probe0 32 to 63 and shuffle
channel_indices1 = np.arange(16, 32)
np.random.shuffle(channel_indices1)
probe1.set_device_channel_indices(channel_indices1)

print(probegroup.get_global_device_channel_indices())
Exemple #10
0
from probeinterface import Probe, ProbeGroup
from probeinterface.plotting import plot_probe, plot_probe_group
from probeinterface import generate_dummy_probe
from probeinterface import write_probeinterface, read_probeinterface
from probeinterface import write_prb, read_prb

##############################################################################
# Let's first generate 2 dummy probes and combine them
# into a ProbeGroup

probe0 = generate_dummy_probe(elec_shapes='square')
probe1 = generate_dummy_probe(elec_shapes='circle')
probe1.move([250, -90])

probegroup = ProbeGroup()
probegroup.add_probe(probe0)
probegroup.add_probe(probe1)

##############################################################################
# With the `write_probeinterface` and `read_probeinterface` functions we can
# write to and read from the json-based probeinterface format:

write_probeinterface('my_two_probe_setup.json', probegroup)

probegroup2 = read_probeinterface('my_two_probe_setup.json')
plot_probe_group(probegroup2)

##############################################################################
# The format looks like this:
Exemple #11
0
def test_probegroup():
    probegroup = ProbeGroup()

    nchan = 0
    for i in range(3):
        probe = generate_dummy_probe()
        probe.move([i * 100, i * 80])
        n = probe.get_contact_count()
        probe.set_device_channel_indices(np.arange(n)[::-1] + nchan)
        shank_ids = np.ones(n)
        shank_ids[:n // 2] *= i * 2
        shank_ids[n // 2:] *= i * 2 + 1
        probe.set_shank_ids(shank_ids)
        probegroup.add_probe(probe)

        nchan += n

    indices = probegroup.get_global_device_channel_indices()

    ids = probegroup.get_global_contact_ids()

    df = probegroup.to_dataframe()
    #~ print(df['global_contact_ids'])

    arr = probegroup.to_numpy(complete=False)
    other = ProbeGroup.from_numpy(arr)
    arr = probegroup.to_numpy(complete=True)
    other = ProbeGroup.from_numpy(arr)

    d = probegroup.to_dict()
    other = ProbeGroup.from_dict(d)

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

    # checking automatic generation of ids with new dummy probes
    probegroup.probes = []
    for i in range(3):
        probegroup.add_probe(generate_dummy_probe())
    probegroup.auto_generate_contact_ids()
    probegroup.auto_generate_probe_ids()

    for p in probegroup.probes:
        assert p.contact_ids is not None
        assert 'probe_id' in p.annotations
                                         num_channels=16)
# make dumpable
recording = recording.save()

##############################################################################
# Initially all channel are in the same group.

print(recording.get_channel_groups())

##############################################################################
# Lets now change the probe mapping and assign a 4 tetrodes to this recording.
# for this we will use the `probeinterface` module and create a `ProbeGroup` containing for dummy tetrode.

from probeinterface import generate_tetrode, ProbeGroup

probegroup = ProbeGroup()
for i in range(4):
    tetrode = generate_tetrode()
    tetrode.set_device_channel_indices(np.arange(4) + i * 4)
    probegroup.add_probe(tetrode)

##############################################################################
#  now our new recording contain 4 groups

recording_4_tetrodes = recording.set_probegroup(probegroup,
                                                group_mode='by_probe')

# get group
print(recording_4_tetrodes.get_channel_groups())
# similar to this
print(recording_4_tetrodes.get_property('group'))