Multiporbe recording
Closed this issue · 10 comments
Hello,
I've been experimenting recording with two probes simultaneously and was wondering what could be the best option to deal with the channel layouts. Would it make sense to create a single probe object with 6 shanks (3 per probe) and sort the data by shank? At first glance this seems like a viable option.
It would be nice if someone could share their experiences with such layouts :)
Cheers,
Marcelo
Hi @mfvd
You can also create 2 probes in probeinterface, then make a probegroup
and add them as separate spikeinterface groups with:
recording = recording.set_probe(probegroup, group_mode='by_probe')
This will load the two probes and assign different channel groups. Then you can use the spikeinterface.sorters.run_sorter_by_property()
function to spike sort separate groups individually.
Hi @alejoe91
Thanks for tour quick reply!
Just to make sure I understood correctly:
Would it still be possible to run the sorter by shank or would the group property now be the probe?
This group_mode
have a role on how to set the group property.
By probe:
recording = recording.set_probe(probegroup, group_mode='by_probe')
print(recording.get_property('group')) # show 2 groups
By shank:
recording = recording.set_probe(probegroup, group_mode='by_shank')
print(recording.get_property('group')) # show 6 groups
Then internally, spikeinterface.sorters.run_sorter_by_property
use the recording.split_by(self, property='group')
Note that you can use any property also for the splitting.
I've tried Samuel's apporach and got the following error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [7], in <cell line: 31>()
29 probegroup = pi.ProbeGroup()
30 probegroup.add_probe(probe)
---> 31 probegroup.add_probe(probe2)
33 # set recording channels to new probe>RHD map.
34 # by shank to perform sorting by shank
35 rec_probe = rec.set_probe(probegroup,
36 group_mode='by_shank')
File /opt/anaconda3/envs/si_openephys/lib/python3.8/site-packages/probeinterface/probegroup.py:22, in ProbeGroup.add_probe(self, probe)
18 """
19
20 """
21 if len(self.probes) > 0:
---> 22 self._check_compatible(probe)
24 self.probes.append(probe)
25 probe._probe_group = self
File /opt/anaconda3/envs/si_openephys/lib/python3.8/site-packages/probeinterface/probegroup.py:36, in ProbeGroup._check_compatible(self, probe)
34 # check global channel maps
35 self.probes.append(probe)
---> 36 self.check_global_device_wiring_and_ids()
37 self.probes = self.probes[:-1]
File /opt/anaconda3/envs/si_openephys/lib/python3.8/site-packages/probeinterface/probegroup.py:188, in ProbeGroup.check_global_device_wiring_and_ids(self)
185 valid_chans = chans[keep]['device_channel_indices']
187 if valid_chans.size != np.unique(valid_chans).size:
--> 188 raise ValueError('channel device index are not unique across probes')
190 # check unique ids for != ''
191 all_ids = self.get_global_contact_ids()
ValueError: channel device index are not unique across probes
I set the device channel indices manually for each probe. Any idea of what error I've made?
manufacturer = 'cambridgeneurotech'
probe_name = 'ASSY-37-Fb'
probe = pi.get_probe(manufacturer, probe_name)
# Match to device (RHD headstage) map. In this case it was corrected because probeinterface was wrong.
device_channel_indices = [
29, 19, 10, 18, 28, 30, 20, 17, 21, 31, 22, 16, 23, 27, 26, 25, 24, 7, 6, 5,
4, 8, 9, 3, 11, 2, 12, 1, 13, 0, 14, 15]
# set channel ids based on probe map from cambridge site and RHD map.
probe.set_device_channel_indices(device_channel_indices)
### set info for PROBE_2 ###
probe2 = pi.get_probe(manufacturer, probe_name)
device_channel_indices_2 = [
17, 20, 16, 21, 31, 23, 30, 24, 28, 19, 26, 8, 27, 10, 28, 11, 29, 12, 22, 7,
25, 0, 4, 15, 5, 14, 9, 13, 6, 1, 3, 2]
device_channel_indices_2 = [element + 32 for element in device_channel_indices_2]
# set channel ids based on probe map from cambridge site and RHD map.
probe2.set_device_channel_indices(device_channel_indices_2)
# create and populate probegroup
probegroup = pi.ProbeGroup()
probegroup.add_probe(probe)
probegroup.add_probe(probe2)
rec_probe = rec.set_probe(probegroup,
group_mode='by_shank')
As the error suggests, the device channel indices are not unique. You need to shift the second set by the number of channels in the first probe ;)
Stupid error on my part...
I was certain device_channel_indices_2 = [element + 32 for element in device_channel_indices_2]
was doing just that and did not spot a duplicate value in my list
thanks for the help @alejoe91
I'm now having the following error:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Input In [16], in <cell line: 41>()
37 probegroup.add_probe(probe2)
39 # set recording channels to new probe>RHD map.
40 # by shank to perform sorting by shank
---> 41 rec_probe = rec.set_probe(probe=probegroup,
42 group_mode='by_shank')
File /opt/anaconda3/envs/si_openephys/lib/python3.8/site-packages/spikeinterface/core/baserecording.py:325, in BaseRecording.set_probe(self, probe, group_mode, in_place)
321 def set_probe(self, probe, group_mode='by_probe', in_place=False):
322 """
323 Wrapper on top on set_probes when there one unique probe.
324 """
--> 325 assert isinstance(probe, Probe), 'must give Probe'
326 probegroup = ProbeGroup()
327 probegroup.add_probe(probe)
AssertionError: must give Probe
I set the probe indices and channel ids for the second probe and the values seem to be correct. Not sure what to do next.
### set info for PROBE_2 ###
probe2 = pi.get_probe(manufacturer, probe_name)
# Match to device (RHD headstage) map. In this case it was corrected because probeinterface was wrong.
device_channel_indices_2 = [
17, 20, 16, 21, 31, 23, 30, 24, 18, 19, 26, 8, 27, 10, 28, 11, 29, 12, 22, 7,
25, 0, 4, 15, 5, 14, 9, 13, 6, 1, 3, 2]
device_channel_indices_2_64 = [element + 32 for element in device_channel_indices_2]
probe2.set_device_channel_indices(device_channel_indices_2_64)
# set contact ids
contact_ids_2 = np.arange(33, 65, 1)
# set contact ids to account for second probe
probe2.set_contact_ids(contact_ids_2)
# create and populate probegroup
probegroup = pi.ProbeGroup()
probegroup.add_probe(probe)
probegroup.add_probe(probe2)
rec_probe = rec.set_probe(probegroup,
group_mode='by_shank')
You need to do
rec_probe = rec.set_probegroup(probegroup,
group_mode='by_shank')
@samuelgarcia
Thanks!