Skip to content

Fix soft vs hard merge issue in analyzer #4025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/spikeinterface/core/sortinganalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,20 +960,22 @@ def _save_or_select_or_merge(
mergeable, masks = self.are_units_mergeable(
merge_unit_groups,
sparsity_overlap=sparsity_overlap,
merging_mode=merging_mode,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zm711 this should fix it. The implementation of this function is as follows:

  • if "soft": return intersection of sparsity and check mergeability
  • if "hard": return union and set mergeable to True

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn’t sure if in hard mode we wanted to test to see if soft was possible and switch to soft if possible and then only do hard if required.

return_masks=True,
)

for unit_index, unit_id in enumerate(all_unit_ids):
if unit_id in new_unit_ids:
merge_unit_group = tuple(merge_unit_groups[new_unit_ids.index(unit_id)])
if not mergeable[merge_unit_group]:
# unit groups can be not mergeable only in "soft" mode
# see are_units_mergeable() function
raise Exception(
f"The sparsity of {merge_unit_group} do not overlap enough for a soft merge using "
f"a sparsity threshold of {sparsity_overlap}. You can either lower the threshold or use "
"a hard merge."
f"a sparsity threshold of {sparsity_overlap}. You can either lower the threshold "
"or use a hard merge."
)
else:
sparsity_mask[unit_index] = masks[merge_unit_group]
sparsity_mask[unit_index] = masks[merge_unit_group]
else:
# This means that the unit is already in the previous sorting
index = self.sorting.id_to_index(unit_id)
Expand Down