Skip to content

Commit f65f2ce

Browse files
committed
Merge branch 'load_analyzer_from_nwb' of github.com:alejoe91/spikeinterface into load_analyzer_from_nwb
2 parents b72a39d + e0a551a commit f65f2ce

File tree

4 files changed

+84
-29
lines changed

4 files changed

+84
-29
lines changed

src/spikeinterface/core/baserecordingsnippets.py

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,17 @@ def is_filtered(self):
6161
# the is_filtered is handle with annotation
6262
return self._annotations.get("is_filtered", False)
6363

64-
def set_probe(self, probe, group_mode="by_probe", in_place=False):
64+
def set_probe(self, probe, group_mode="auto", in_place=False):
6565
"""
6666
Attach a list of Probe object to a recording.
6767
6868
Parameters
6969
----------
7070
probe_or_probegroup: Probe, list of Probe, or ProbeGroup
7171
The probe(s) to be attached to the recording
72-
group_mode: "by_probe" | "by_shank", default: "by_probe
73-
"by_probe" or "by_shank". Adds grouping property to the recording based on the probes ("by_probe")
74-
or shanks ("by_shanks")
72+
group_mode: "auto" | "by_probe" | "by_shank" | "by_side", default: "auto"
73+
How to add the "group" property.
74+
"auto" is the best splitting possible that can be all at once when multiple probes, multiple shanks and two sides are present.
7575
in_place: bool
7676
False by default.
7777
Useful internally when extractor do self.set_probegroup(probe)
@@ -86,10 +86,10 @@ def set_probe(self, probe, group_mode="by_probe", in_place=False):
8686
probegroup.add_probe(probe)
8787
return self._set_probes(probegroup, group_mode=group_mode, in_place=in_place)
8888

89-
def set_probegroup(self, probegroup, group_mode="by_probe", in_place=False):
89+
def set_probegroup(self, probegroup, group_mode="auto", in_place=False):
9090
return self._set_probes(probegroup, group_mode=group_mode, in_place=in_place)
9191

92-
def _set_probes(self, probe_or_probegroup, group_mode="by_probe", in_place=False):
92+
def _set_probes(self, probe_or_probegroup, group_mode="auto", in_place=False):
9393
"""
9494
Attach a list of Probe objects to a recording.
9595
For this Probe.device_channel_indices is used to link contacts to recording channels.
@@ -103,9 +103,9 @@ def _set_probes(self, probe_or_probegroup, group_mode="by_probe", in_place=False
103103
----------
104104
probe_or_probegroup: Probe, list of Probe, or ProbeGroup
105105
The probe(s) to be attached to the recording
106-
group_mode: "by_probe" | "by_shank", default: "by_probe"
107-
"by_probe" or "by_shank". Adds grouping property to the recording based on the probes ("by_probe")
108-
or shanks ("by_shank")
106+
group_mode: "auto" | "by_probe" | "by_shank" | "by_side", default: "auto"
107+
How to add the "group" property.
108+
"auto" is the best splitting possible that can be all at once when multiple probes, multiple shanks and two sides are present.
109109
in_place: bool
110110
False by default.
111111
Useful internally when extractor do self.set_probegroup(probe)
@@ -115,7 +115,12 @@ def _set_probes(self, probe_or_probegroup, group_mode="by_probe", in_place=False
115115
sub_recording: BaseRecording
116116
A view of the recording (ChannelSlice or clone or itself)
117117
"""
118-
assert group_mode in ("by_probe", "by_shank"), "'group_mode' can be 'by_probe' or 'by_shank'"
118+
assert group_mode in (
119+
"auto",
120+
"by_probe",
121+
"by_shank",
122+
"by_side",
123+
), "'group_mode' can be 'auto' 'by_probe' 'by_shank' or 'by_side'"
119124

120125
# handle several input possibilities
121126
if isinstance(probe_or_probegroup, Probe):
@@ -150,6 +155,7 @@ def _set_probes(self, probe_or_probegroup, group_mode="by_probe", in_place=False
150155
warn("The given probes have unconnected contacts: they are removed")
151156

152157
probe_as_numpy_array = probe_as_numpy_array[keep]
158+
153159
device_channel_indices = probe_as_numpy_array["device_channel_indices"]
154160
order = np.argsort(device_channel_indices)
155161
device_channel_indices = device_channel_indices[order]
@@ -199,20 +205,32 @@ def _set_probes(self, probe_or_probegroup, group_mode="by_probe", in_place=False
199205
sub_recording.set_property("location", locations, ids=None)
200206

201207
# handle groups
202-
groups = np.zeros(probe_as_numpy_array.size, dtype="int64")
203-
if group_mode == "by_probe":
204-
for group, probe_index in enumerate(np.unique(probe_as_numpy_array["probe_index"])):
205-
mask = probe_as_numpy_array["probe_index"] == probe_index
206-
groups[mask] = group
208+
has_shank_id = "shank_ids" in probe_as_numpy_array.dtype.fields
209+
has_contact_side = "contact_sides" in probe_as_numpy_array.dtype.fields
210+
if group_mode == "auto":
211+
group_keys = ["probe_index"]
212+
if has_shank_id:
213+
group_keys += ["shank_ids"]
214+
if has_contact_side:
215+
group_keys += ["contact_sides"]
216+
elif group_mode == "by_probe":
217+
group_keys = ["probe_index"]
207218
elif group_mode == "by_shank":
208-
assert all(
209-
probe.shank_ids is not None for probe in probegroup.probes
210-
), "shank_ids is None in probe, you cannot group by shank"
211-
for group, a in enumerate(np.unique(probe_as_numpy_array[["probe_index", "shank_ids"]])):
212-
mask = (probe_as_numpy_array["probe_index"] == a["probe_index"]) & (
213-
probe_as_numpy_array["shank_ids"] == a["shank_ids"]
214-
)
215-
groups[mask] = group
219+
assert has_shank_id, "shank_ids is None in probe, you cannot group by shank"
220+
group_keys = ["probe_index", "shank_ids"]
221+
elif group_mode == "by_side":
222+
assert has_contact_side, "contact_sides is None in probe, you cannot group by side"
223+
if has_shank_id:
224+
group_keys = ["probe_index", "shank_ids", "contact_sides"]
225+
else:
226+
group_keys = ["probe_index", "contact_sides"]
227+
groups = np.zeros(probe_as_numpy_array.size, dtype="int64")
228+
unique_keys = np.unique(probe_as_numpy_array[group_keys])
229+
for group, a in enumerate(unique_keys):
230+
mask = np.ones(probe_as_numpy_array.size, dtype=bool)
231+
for k in group_keys:
232+
mask &= probe_as_numpy_array[k] == a[k]
233+
groups[mask] = group
216234
sub_recording.set_property("group", groups, ids=None)
217235

218236
# add probe annotations to recording

src/spikeinterface/core/tests/test_baserecording.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,23 @@ def test_BaseRecording(create_cache_folder):
179179

180180
# set/get Probe only 2 channels
181181
probe = Probe(ndim=2)
182-
positions = [[0.0, 0.0], [0.0, 15.0], [0, 30.0]]
183-
probe.set_contacts(positions=positions, shapes="circle", shape_params={"radius": 5})
184-
probe.set_device_channel_indices([2, -1, 0])
182+
positions = [
183+
[0.0, 0.0],
184+
[0.0, 15.0],
185+
[0, 30.0],
186+
[100.0, 0.0],
187+
[100.0, 15.0],
188+
[100.0, 30.0],
189+
]
190+
probe.set_contacts(
191+
positions=positions, shapes="circle", shape_params={"radius": 5}, shank_ids=["a"] * 3 + ["b"] * 3
192+
)
193+
probe.set_device_channel_indices(
194+
[2, -1, 0, -1, -1, -1],
195+
)
185196
probe.create_auto_shape()
186197

198+
rec_p = rec.set_probe(probe, group_mode="auto")
187199
rec_p = rec.set_probe(probe, group_mode="by_shank")
188200
rec_p = rec.set_probe(probe, group_mode="by_probe")
189201
positions2 = rec_p.get_channel_locations()
@@ -213,10 +225,35 @@ def test_BaseRecording(create_cache_folder):
213225
# plot_probe(probe2)
214226
# plt.show()
215227

228+
# test different group mode
229+
probe = Probe(ndim=2)
230+
positions_two_side = positions + positions
231+
shank_ids = ["a", "a", "a", "b", "b", "b"] * 2
232+
contact_sides = ["front"] * 6 + ["back"] * 6
233+
probe.set_contacts(
234+
positions=positions_two_side,
235+
shapes="circle",
236+
shape_params={"radius": 5},
237+
shank_ids=shank_ids,
238+
contact_sides=contact_sides,
239+
)
240+
probe.set_device_channel_indices(np.arange(12))
241+
probe.create_auto_shape()
242+
traces = np.zeros((1000, 12), dtype="int16")
243+
rec = NumpyRecording([traces], 30000.0)
244+
rec1 = rec.set_probe(probe, group_mode="auto")
245+
assert np.unique(rec1.get_property("group")).size == 4
246+
rec2 = rec.set_probe(probe, group_mode="by_probe")
247+
assert np.unique(rec2.get_property("group")).size == 1
248+
rec3 = rec.set_probe(probe, group_mode="by_shank")
249+
assert np.unique(rec3.get_property("group")).size == 2
250+
rec4 = rec.set_probe(probe, group_mode="by_side")
251+
assert np.unique(rec4.get_property("group")).size == 4
252+
216253
# set unconnected probe
217254
probe = Probe(ndim=2)
218255
positions = [[0.0, 0.0], [0.0, 15.0], [0, 30.0]]
219-
probe.set_contacts(positions=positions, shapes="circle", shape_params={"radius": 5})
256+
probe.set_contacts(positions=positions, shapes="circle", shape_params={"radius": 5}, shank_ids=["a", "a", "a"])
220257
probe.set_device_channel_indices([-1, -1, -1])
221258
probe.create_auto_shape()
222259

src/spikeinterface/core/tests/test_basesnippets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def test_BaseSnippets(create_cache_folder):
142142
probe.set_device_channel_indices([2, -1, 0])
143143
probe.create_auto_shape()
144144

145-
snippets_p = snippets.set_probe(probe, group_mode="by_shank")
145+
snippets_p = snippets.set_probe(probe, group_mode="auto")
146146
snippets_p = snippets.set_probe(probe, group_mode="by_probe")
147147
positions2 = snippets_p.get_channel_locations()
148148
assert np.array_equal(positions2, [[0, 30.0], [0.0, 0.0]])

src/spikeinterface/sorters/tests/test_runsorter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_run_sorter_dict(generate_recording, create_cache_folder):
5656
recording.set_property(key="split_property", values=[4, 4, "g", "g", 4, 4, 4, "g"])
5757
dict_of_recordings = recording.split_by("split_property")
5858

59-
sorter_params = {"detection": {"detect_threshold": 4.9}}
59+
sorter_params = {"detect_threshold": 4.9}
6060

6161
folder = cache_folder / "sorting_tdc_local_dict"
6262

0 commit comments

Comments
 (0)