Use ProbeGroup object instead of contact_vector property#4465
Use ProbeGroup object instead of contact_vector property#4465alejoe91 wants to merge 28 commits into
ProbeGroup object instead of contact_vector property#4465Conversation
Co-authored-by: Alessio Buccino <alejoe9187@gmail.com>
| ) | ||
| # check that multiple probes are non-overlapping | ||
| all_probes = recording.get_probegroup().probes | ||
| check_probe_do_not_overlap(all_probes) |
There was a problem hiding this comment.
This is removed because when we split_by and aggregate probes might overlap
|
I would like to take a look to this. I can do it this week. |
|
I guess that @zm711 and @h-mayorquin are now dancing on their seat just reading this PR. Let me read it slowly. |
h-mayorquin
left a comment
There was a problem hiding this comment.
As we discussed previously I think this is a step in the direction direction.
Is _build_probegroup_from_properties only for backwwards compatbility?
I think we can segregate the backward-compatibility serialization logic (_build_probegroup_from_properties) from the main class methods by moving it into the deserialization hooks. _extra_metadata_from_dict already runs after properties are set (base.py:1202), so it can check for "probegroup" first and fall back to reconstructing from contact_vector. For the folder path, load_metadata_from_folder (base.py:639) needs to swap lines 643 and 646 so .npy properties load before _extra_metadata_from_folder runs, giving the hook access to legacy contact_vector when there is no probe.json. This has the side effect of a cleaner design where has_probe() becomes return self._probegroup is not None with no mutation at check time.
Let's check also how zarr does it. If we don't have a separate function for zarr, we can also add it to |
| if self.has_probe(): | ||
| probegroup = self.get_probegroup() | ||
| write_probeinterface(folder / "probe.json", probegroup) |
There was a problem hiding this comment.
this is not needed, handled by the save_to_folder
@h-mayorquin actually both the |
|
Depends on SpikeInterface/probeinterface#420 |
|
@h-mayorquin @samuelgarcia this is ready to review. See updated PR description |
|
|
||
| import numpy as np | ||
|
|
||
| from probeinterface import read_probeinterface |
| return self.select_channels_with_probegroup(probegroup, group_mode=group_mode) | ||
|
|
||
| # Handle several input possibilities: Probe or dict | ||
| if isinstance(probegroup, dict): |
There was a problem hiding this comment.
I think this should be handled in _extra_metadata_from_dict instead of here. This will avoid the polymorphism of the type in the signature and it will corral the serialization machinery to the serialization path and simplify the function that people are more likely to see.
There was a problem hiding this comment.
There is also a strange behavior here when you pass a dict with with in_place=False which would be solve by this.
|
I am OK with all of this but there are a couple of features here:
The three look good to me but we can also make them as separate PRs if we don't feel OK about the whole bundle. Most of the diff churn comes from 2 I think. Some comments:
|
|
I agree @h-mayorquin Let me split this into 2 PRs: That will make it easier to review. We can also postpone 2, since it might need some more discussion |
Updated
After SpikeInterface/probeinterface#446, we can go all in on the use of
ProbeGroupinstead ofcontact_vector, since the use case with interleaved contacts after device channel indices slicing is handled gracefully by the new_global_contact_orderarray, stored in the probegroup dictionary.Now the
recordinghas a_probegroupattribute, which is propagated as metadata.Now real issue with bakward compatibility, since the saving to folder/zarr kept the
device_channel_indices.The
probegroup.get_slicetakes care of all metadata propagation.Note that this implementation is alternative to what is proposed in #4553 and implemented in #4548 : here we keep a
ProbeGroupobject attached to the recording, after sorting it bydevice_channel_indices, instead of adding awiringproperty. You lose the original probe contact order, but we argue that the contacts in a probegroup do not really have a "default" order, but are rather a set of contacts that become ordered when wired (see #3498).Some additional points:
set_probe/probegroupversusselect_channels_with_probe/probegroupThis PR further refactors the set_probe function to address several issues:
set_probe/probegroup: now are only in place (the not in place is deprecated, but will be removed in 0.106.0): these functions now require that the connected contacts have the same length as the number of channels.select_channels_with_probe/probegroupto handle the slicing of recordings with probes.Tests for aggregation/slicing
Added more tests for aggregation/slicing behavior and metadata propagation
Fixes #4545 #4546 #4547 #4549 #4553
Tests for backward compatibility
Added a test for bakward compatibility, which saves a recording to binary/zarr with v0.104.* and reloads it with the current version to check that the probegroup is reloaded correctly.