Skip to content

Commit a0a5ef5

Browse files
authored
Merge branch 'main' into prepare_release
2 parents c76b240 + b22fc37 commit a0a5ef5

9 files changed

Lines changed: 18 additions & 201 deletions

File tree

src/spikeinterface/core/sortingfolder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def __init__(self, folder_path):
3737

3838
BaseSorting.__init__(self, sampling_frequency, unit_ids)
3939

40-
self.spikes = np.load(folder_path / "spikes.npy", mmap_mode="r")
40+
self.spikes = np.load(folder_path / "spikes.npy")
4141

4242
for segment_index in range(num_segments):
4343
self.add_sorting_segment(SpikeVectorSortingSegment(self.spikes, segment_index, unit_ids))

src/spikeinterface/core/template.py

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
from dataclasses import dataclass, field, astuple, replace
66
from probeinterface import Probe
77
from pathlib import Path
8-
from multiprocessing.shared_memory import SharedMemory
98

109
from .sparsity import ChannelSparsity
11-
from .core_tools import make_shared_array
1210

1311

1412
@dataclass
@@ -457,88 +455,3 @@ def get_channel_locations(self) -> np.ndarray:
457455
assert self.probe is not None, "Templates.get_channel_locations() needs a probe to be set"
458456
channel_locations = self.probe.contact_positions
459457
return channel_locations
460-
461-
462-
class SharedMemoryTemplates(Templates):
463-
464-
def __init__(
465-
self,
466-
shm_name,
467-
shape,
468-
dtype,
469-
sampling_frequency,
470-
nbefore,
471-
sparsity_mask,
472-
channel_ids,
473-
unit_ids,
474-
probe,
475-
is_scaled,
476-
main_shm_owner=True,
477-
):
478-
479-
assert len(shape) == 3
480-
assert shape[0] > 0, "SharedMemoryTemplates only supported with no empty templates"
481-
482-
self.shm = SharedMemory(shm_name, create=False)
483-
templates_array = np.ndarray(shape=shape, dtype=dtype, buffer=self.shm.buf)
484-
485-
Templates.__init__(
486-
self,
487-
templates_array=templates_array,
488-
sampling_frequency=sampling_frequency,
489-
nbefore=nbefore,
490-
sparsity_mask=sparsity_mask,
491-
channel_ids=channel_ids,
492-
unit_ids=unit_ids,
493-
probe=probe,
494-
is_scaled=is_scaled,
495-
)
496-
497-
# self._serializability["memory"] = True
498-
# self._serializability["json"] = False
499-
# self._serializability["pickle"] = False
500-
501-
# this is very important for the shm.unlink()
502-
# only the main instance need to call it
503-
# all other instances that are loaded from dict are not the main owner
504-
self.main_shm_owner = main_shm_owner
505-
506-
self._kwargs = dict(
507-
shm_name=shm_name,
508-
shape=shape,
509-
sampling_frequency=sampling_frequency,
510-
nbefore=self.nbefore,
511-
sparsity_mask=self.sparsity_mask,
512-
channel_ids=self.channel_ids,
513-
unit_ids=self.unit_ids,
514-
probe=self.probe,
515-
is_scaled=self.is_scaled,
516-
# this ensure that all dump/load will not be main shm owner
517-
main_shm_owner=False,
518-
)
519-
520-
def __del__(self):
521-
self.shm.close()
522-
if self.main_shm_owner:
523-
self.shm.unlink()
524-
525-
@staticmethod
526-
def from_templates(templates):
527-
data = templates.get_dense_templates()
528-
shm_templates, shm = make_shared_array(data.shape, data.dtype)
529-
shm_templates[:] = data
530-
shared_templates = SharedMemoryTemplates(
531-
shm.name,
532-
data.shape,
533-
data.dtype,
534-
templates.sampling_frequency,
535-
templates.nbefore,
536-
templates.sparsity_mask,
537-
templates.channel_ids,
538-
templates.unit_ids,
539-
templates.probe,
540-
templates.is_scaled,
541-
main_shm_owner=True,
542-
)
543-
shm.close()
544-
return shared_templates

src/spikeinterface/core/tests/test_template_class.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
import numpy as np
33
import pickle
4-
from spikeinterface.core.template import Templates, SharedMemoryTemplates
4+
from spikeinterface.core.template import Templates
55
from spikeinterface.core.sparsity import ChannelSparsity
66

77
from probeinterface import generate_multi_columns_probe
@@ -171,21 +171,6 @@ def test_select_channels(template_type, is_scaled):
171171
assert np.array_equal(selected_template.sparsity_mask, template.sparsity_mask[:, selected_channel_ids_indices])
172172

173173

174-
@pytest.mark.parametrize("is_scaled", [True, False])
175-
@pytest.mark.parametrize("template_type", ["dense"])
176-
def test_shm_templates(template_type, is_scaled):
177-
template = generate_test_template(template_type, is_scaled)
178-
shm_templates = SharedMemoryTemplates.from_templates(template)
179-
180-
# Verify that the channel ids match
181-
assert np.array_equal(shm_templates.channel_ids, template.channel_ids)
182-
# Verify that the templates data matches
183-
assert np.array_equal(shm_templates.templates_array, template.templates_array)
184-
185-
if template.sparsity_mask is not None:
186-
assert np.array_equal(shm_templates.sparsity_mask, template.sparsity_mask)
187-
188-
189174
if __name__ == "__main__":
190175
# test_json_serialization("sparse")
191176
test_json_serialization("dense")

src/spikeinterface/generation/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
move_dense_templates,
33
interpolate_templates,
44
DriftingTemplates,
5-
SharedMemoryDriftingTemplates,
65
InjectDriftingTemplatesRecording,
76
make_linear_displacement,
87
)

src/spikeinterface/generation/drift_tools.py

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
from numpy.typing import ArrayLike
88
from probeinterface import Probe
99
from spikeinterface.core import BaseRecording, BaseRecordingSegment, BaseSorting, Templates
10-
from multiprocessing.shared_memory import SharedMemory
11-
from spikeinterface.core.core_tools import make_shared_array
1210

1311

1412
def interpolate_templates(templates_array, source_locations, dest_locations, interpolation_method="cubic"):
@@ -260,85 +258,6 @@ def precompute_displacements(self, displacements, **interpolation_kwargs):
260258
self.displacements = displacements
261259

262260

263-
class SharedMemoryDriftingTemplates(DriftingTemplates):
264-
265-
def __init__(
266-
self,
267-
shm_name,
268-
shape,
269-
dtype,
270-
templates_array_moved=None,
271-
displacements=None,
272-
main_shm_owner=True,
273-
**static_kwargs,
274-
):
275-
276-
assert len(shape) == 4
277-
assert shape[0] > 0, "SharedMemoryTemplates only supported with no empty templates"
278-
279-
self.shm = SharedMemory(shm_name, create=False)
280-
templates_array_moved = np.ndarray(shape=shape, dtype=dtype, buffer=self.shm.buf)
281-
self.static_kwargs = static_kwargs
282-
DriftingTemplates.__init__(
283-
self, templates_array_moved=templates_array_moved, displacements=displacements, **self.static_kwargs
284-
)
285-
286-
# this is very important for the shm.unlink()
287-
# only the main instance need to call it
288-
# all other instances that are loaded from dict are not the main owner
289-
self.main_shm_owner = main_shm_owner
290-
291-
self._kwargs = dict(
292-
shm_name=shm_name,
293-
shape=shape,
294-
displacements=self.displacements,
295-
static_kwargs=self.static_kwargs,
296-
channel_ids=self.channel_ids,
297-
# this ensure that all dump/load will not be main shm owner
298-
main_shm_owner=False,
299-
)
300-
301-
def __del__(self):
302-
self.shm.close()
303-
if self.main_shm_owner:
304-
self.shm.unlink()
305-
306-
@staticmethod
307-
def from_drifting_templates(drifting_templates):
308-
assert (
309-
drifting_templates.templates_array_moved is not None
310-
), "drifting_templates must have precomputed displacements"
311-
data = drifting_templates.templates_array_moved
312-
shm_templates, shm = make_shared_array(data.shape, data.dtype)
313-
shm_templates[:] = data
314-
static_kwargs = drifting_templates.to_dict()
315-
init_kwargs = {
316-
"templates_array": np.asarray(static_kwargs["templates_array"]),
317-
"sparsity_mask": (
318-
None if static_kwargs["sparsity_mask"] is None else np.asarray(static_kwargs["sparsity_mask"])
319-
),
320-
"channel_ids": np.asarray(static_kwargs["channel_ids"]),
321-
"unit_ids": np.asarray(static_kwargs["unit_ids"]),
322-
"sampling_frequency": static_kwargs["sampling_frequency"],
323-
"nbefore": static_kwargs["nbefore"],
324-
"is_scaled": static_kwargs["is_scaled"],
325-
"probe": (
326-
static_kwargs["probe"] if static_kwargs["probe"] is None else Probe.from_dict(static_kwargs["probe"])
327-
),
328-
}
329-
shared_drifting_templates = SharedMemoryDriftingTemplates(
330-
shm.name,
331-
data.shape,
332-
data.dtype,
333-
shm_templates,
334-
drifting_templates.displacements,
335-
main_shm_owner=True,
336-
**init_kwargs,
337-
)
338-
shm.close()
339-
return shared_drifting_templates
340-
341-
342261
def make_linear_displacement(start, stop, num_step=10):
343262
"""
344263
Generates 2D linear displacements between `start` and `stop` positions (included in returned displacements).

src/spikeinterface/generation/tests/test_drift_tools.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
move_dense_templates,
77
make_linear_displacement,
88
DriftingTemplates,
9-
SharedMemoryDriftingTemplates,
109
InjectDriftingTemplatesRecording,
1110
)
1211
from spikeinterface.core.generate import generate_templates, generate_sorting, NoiseGeneratorRecording
@@ -134,25 +133,13 @@ def test_DriftingTemplates():
134133
assert np.array_equal(drifting_templates_from_precomputed.displacements, drifting_templates.displacements)
135134

136135

137-
def test_SharedMemoryDriftingTemplates():
138-
static_templates = make_some_templates()
139-
drifting_templates = DriftingTemplates.from_static_templates(static_templates)
140-
displacement = np.array([[5.0, 10.0]])
141-
drifting_templates.precompute_displacements(displacement)
142-
shm_drifting_templates = SharedMemoryDriftingTemplates.from_drifting_templates(drifting_templates)
143-
144-
assert np.array_equal(shm_drifting_templates.templates_array_moved, drifting_templates.templates_array_moved)
145-
assert np.array_equal(shm_drifting_templates.displacements, drifting_templates.displacements)
146-
147-
148136
def test_InjectDriftingTemplatesRecording(create_cache_folder):
149137
cache_folder = create_cache_folder
150138
templates = make_some_templates()
151139
probe = templates.probe
152140

153141
# drifting templates
154142
drifting_templates = DriftingTemplates.from_static_templates(templates)
155-
channel_locations = probe.contact_positions
156143

157144
num_units = templates.unit_ids.size
158145
sampling_frequency = templates.sampling_frequency

src/spikeinterface/postprocessing/principal_component.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,11 @@ def get_some_projections(self, channel_ids=None, unit_ids=None):
260260
spike_unit_indices = some_spikes["unit_index"][selected_inds]
261261

262262
if sparsity is None:
263-
some_projections = all_projections[selected_inds, :, :][:, :, channel_indices]
263+
if self.params["mode"] == "concatenated":
264+
some_projections = all_projections[selected_inds, :]
265+
else:
266+
some_projections = all_projections[selected_inds, :, :][:, :, channel_indices]
267+
264268
else:
265269
# need re-alignement
266270
some_projections = np.zeros((selected_inds.size, num_components, channel_indices.size), dtype=dtype)

src/spikeinterface/postprocessing/tests/test_principal_component.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ def test_mode_concatenated(self):
5050
assert pca.ndim == 2
5151
assert pca.shape[1] == n_components
5252

53+
ext_rand = sorting_analyzer.get_extension("random_spikes")
54+
num_rand_spikes = len(ext_rand.get_data())
55+
56+
some_projections = ext.get_some_projections()
57+
assert some_projections[0].shape[0] == num_rand_spikes
58+
assert some_projections[0].shape[1] == n_components
59+
5360
@pytest.mark.parametrize("sparse", [True, False])
5461
def test_get_projections(self, sparse):
5562
"""

src/spikeinterface/qualitymetrics/pca_metrics.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,10 @@ def compute_pc_metrics(
157157
neighbor_channel_indices = sorting_analyzer.channel_ids_to_indices(neighbor_channel_ids)
158158

159159
labels = all_labels[np.isin(all_labels, neighbor_unit_ids)]
160-
pcs = dense_projections[np.isin(all_labels, neighbor_unit_ids)][:, :, neighbor_channel_indices]
160+
if pca_ext.params["mode"] == "concatenated":
161+
pcs = dense_projections[np.isin(all_labels, neighbor_unit_ids)]
162+
else:
163+
pcs = dense_projections[np.isin(all_labels, neighbor_unit_ids)][:, :, neighbor_channel_indices]
161164
pcs_flat = pcs.reshape(pcs.shape[0], -1)
162165

163166
func_args = (pcs_flat, labels, non_nn_metrics, unit_id, unit_ids, metric_params, max_threads_per_worker)

0 commit comments

Comments
 (0)