Skip to content

Commit 9d95496

Browse files
committed
Deal with censor_ms in soft merge
1 parent edbd531 commit 9d95496

2 files changed

Lines changed: 68 additions & 27 deletions

File tree

src/spikeinterface/postprocessing/correlograms.py

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,45 +103,68 @@ def _merge_extension_data(
103103
Here, we apply this formula to quickly compute correlograms for merged units.
104104
"""
105105

106-
need_to_append = False
107-
delete_from = 1
106+
can_apply_soft_method = True
107+
if censor_ms is not None:
108+
# if censor_ms has no effect, can apply "soft" method. Check if any spikes have been removed
109+
for new_unit_id, merge_unit_group in zip(new_unit_ids, merge_unit_groups):
108110

109-
correlograms, new_bins = deepcopy(self.get_data())
111+
merged_spike_train_length = len(new_sorting_analyzer.sorting.get_unit_spike_train(new_unit_id))
110112

111-
for new_unit_id, merge_unit_group in zip(new_unit_ids, merge_unit_groups):
113+
old_spike_train_lengths = len(
114+
np.concatenate(
115+
[self.sorting_analyzer.sorting.get_unit_spike_train(unit_id) for unit_id in merge_unit_group]
116+
)
117+
)
118+
119+
if merged_spike_train_length != old_spike_train_lengths:
120+
can_apply_soft_method = False
121+
break
122+
123+
if can_apply_soft_method is False:
124+
new_ccgs, new_bins = _compute_correlograms_on_sorting(new_sorting_analyzer.sorting, **self.params)
125+
new_data = dict(ccgs=new_ccgs, bins=new_bins)
126+
else:
127+
128+
need_to_append = False
129+
delete_from = 1
130+
131+
correlograms, new_bins = deepcopy(self.get_data())
132+
133+
for new_unit_id, merge_unit_group in zip(new_unit_ids, merge_unit_groups):
134+
135+
merge_unit_group_indices = self.sorting_analyzer.sorting.ids_to_indices(merge_unit_group)
112136

113-
merge_unit_group_indices = self.sorting_analyzer.sorting.ids_to_indices(merge_unit_group)
137+
new_col = np.sum(correlograms[merge_unit_group_indices, :, :], axis=0)
114138

115-
new_col = np.sum(correlograms[merge_unit_group_indices, :, :], axis=0)
116-
correlograms[merge_unit_group_indices[0], :, :] = new_col
117-
correlograms[merge_unit_group_indices[1:], :, :] = 0
139+
correlograms[merge_unit_group_indices[0], :, :] = new_col
140+
correlograms[merge_unit_group_indices[1:], :, :] = 0
118141

119-
new_row = np.sum(correlograms[:, merge_unit_group_indices, :], axis=1)
120-
correlograms[:, merge_unit_group_indices[0], :] = new_row
121-
correlograms[:, merge_unit_group_indices[1:], :] = 0
142+
new_row = np.sum(correlograms[:, merge_unit_group_indices, :], axis=1)
143+
correlograms[:, merge_unit_group_indices[0], :] = new_row
144+
correlograms[:, merge_unit_group_indices[1:], :] = 0
122145

123-
if new_unit_id not in merge_unit_group:
124-
need_to_append = True
125-
delete_from = 0
146+
if new_unit_id not in merge_unit_group:
147+
need_to_append = True
148+
delete_from = 0
126149

127-
if need_to_append is True:
128-
old_num_units = np.shape(correlograms)[0]
129-
correlograms = np.pad(correlograms, ((0, len(new_unit_ids)), (0, len(new_unit_ids)), (0, 0)))
130-
for a, (new_unit_id, merge_unit_group) in enumerate(zip(new_unit_ids, merge_unit_groups)):
150+
if need_to_append is True:
151+
old_num_units = np.shape(correlograms)[0]
152+
correlograms = np.pad(correlograms, ((0, len(new_unit_ids)), (0, len(new_unit_ids)), (0, 0)))
153+
for a, (new_unit_id, merge_unit_group) in enumerate(zip(new_unit_ids, merge_unit_groups)):
131154

132-
old_loc = self.sorting_analyzer.sorting.ids_to_indices([merge_unit_group[0]])[0]
133-
new_loc = old_num_units + a
155+
old_loc = self.sorting_analyzer.sorting.ids_to_indices([merge_unit_group[0]])[0]
156+
new_loc = old_num_units + a
134157

135-
correlograms[:, [old_loc, new_loc], :] = correlograms[:, [new_loc, old_loc], :]
136-
correlograms[[old_loc, new_loc], :, :] = correlograms[[new_loc, old_loc], :, :]
158+
correlograms[:, [old_loc, new_loc], :] = correlograms[:, [new_loc, old_loc], :]
159+
correlograms[[old_loc, new_loc], :, :] = correlograms[[new_loc, old_loc], :, :]
137160

138-
units_to_delete = np.concatenate([merge_unit_group[delete_from:] for merge_unit_group in merge_unit_groups])
139-
indices_to_delete = self.sorting_analyzer.sorting.ids_to_indices(units_to_delete)
161+
units_to_delete = np.concatenate([merge_unit_group[delete_from:] for merge_unit_group in merge_unit_groups])
162+
indices_to_delete = self.sorting_analyzer.sorting.ids_to_indices(units_to_delete)
140163

141-
correlograms = np.delete(correlograms, indices_to_delete, axis=0)
142-
correlograms = np.delete(correlograms, indices_to_delete, axis=1)
164+
correlograms = np.delete(correlograms, indices_to_delete, axis=0)
165+
correlograms = np.delete(correlograms, indices_to_delete, axis=1)
143166

144-
new_data = dict(ccgs=correlograms, bins=new_bins)
167+
new_data = dict(ccgs=correlograms, bins=new_bins)
145168
return new_data
146169

147170
def _run(self, verbose=False):

src/spikeinterface/postprocessing/tests/test_extension_merges.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,21 @@ def test_correlograms_merge():
3434
# Then re-compute, and compare
3535
recomputed_correlograms = merged_sorting_analyzer.compute("correlograms").get_data()
3636
assert np.all(computed_correlograms[0] == recomputed_correlograms[0])
37+
38+
# test when `censor_ms` is not None. This merge does remove some spikes.
39+
merged_sorting_analyzer_censored = sorting_analyzer.merge_units(
40+
merge_unit_groups=trial_merges[2], new_id_strategy="take_first", censor_ms=5
41+
)
42+
computed_ccgs_censored = merged_sorting_analyzer_censored.get_extension("correlograms").get_data()
43+
44+
recomputed_ccgs_censored = merged_sorting_analyzer_censored.compute("correlograms").get_data()
45+
assert np.all(computed_ccgs_censored[0] == recomputed_ccgs_censored[0])
46+
47+
# This `censor_ms` does not remove spikes, so can use the soft method
48+
merged_sorting_analyzer_not_censored = sorting_analyzer.merge_units(
49+
merge_unit_groups=trial_merges[0], new_id_strategy="take_first", censor_ms=0
50+
)
51+
computed_ccgs_not_censored = merged_sorting_analyzer_not_censored.get_extension("correlograms").get_data()
52+
53+
recomputed_ccgs_not_censored = merged_sorting_analyzer_not_censored.compute("correlograms").get_data()
54+
assert np.all(computed_ccgs_not_censored[0] == recomputed_ccgs_not_censored[0])

0 commit comments

Comments
 (0)