@@ -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
0 commit comments