Skip to content

Commit 50eadce

Browse files
authored
Merge pull request #3433 from alejoe91/postprocessing-tmp-recording
Fix compute analyzer pipeline with tmp recording
2 parents a874f2a + a071605 commit 50eadce

2 files changed

Lines changed: 22 additions & 19 deletions

File tree

src/spikeinterface/core/sortinganalyzer.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ def __repr__(self) -> str:
232232
txt += " - sparse"
233233
if self.has_recording():
234234
txt += " - has recording"
235+
if self.has_temporary_recording():
236+
txt += " - has temporary recording"
235237
ext_txt = f"Loaded {len(self.extensions)} extensions: " + ", ".join(self.extensions.keys())
236238
txt += "\n" + ext_txt
237239
return txt
@@ -350,7 +352,7 @@ def create_memory(cls, sorting, recording, sparsity, return_scaled, rec_attribut
350352
def create_binary_folder(cls, folder, sorting, recording, sparsity, return_scaled, rec_attributes):
351353
# used by create and save_as
352354

353-
assert recording is not None, "To create a SortingAnalyzer you need recording not None"
355+
assert recording is not None, "To create a SortingAnalyzer you need to specify the recording"
354356

355357
folder = Path(folder)
356358
if folder.is_dir():
@@ -1221,7 +1223,7 @@ def compute(self, input, save=True, extension_params=None, verbose=False, **kwar
12211223
extensions[ext_name] = ext_params
12221224
self.compute_several_extensions(extensions=extensions, save=save, verbose=verbose, **job_kwargs)
12231225
else:
1224-
raise ValueError("SortingAnalyzer.compute() need str, dict or list")
1226+
raise ValueError("SortingAnalyzer.compute() needs a str, dict or list")
12251227

12261228
def compute_one_extension(self, extension_name, save=True, verbose=False, **kwargs) -> "AnalyzerExtension":
12271229
"""
@@ -1355,7 +1357,9 @@ def compute_several_extensions(self, extensions, save=True, verbose=False, **job
13551357

13561358
for extension_name, extension_params in extensions_with_pipeline.items():
13571359
extension_class = get_extension_class(extension_name)
1358-
assert self.has_recording(), f"Extension {extension_name} need the recording"
1360+
assert (
1361+
self.has_recording() or self.has_temporary_recording()
1362+
), f"Extension {extension_name} requires the recording"
13591363

13601364
for variable_name in extension_class.nodepipeline_variables:
13611365
result_routage.append((extension_name, variable_name))
@@ -1603,17 +1607,17 @@ def _sort_extensions_by_dependency(extensions):
16031607
def _get_children_dependencies(extension_name):
16041608
"""
16051609
Extension classes have a `depend_on` attribute to declare on which class they
1606-
depend. For instance "templates" depend on "waveforms". "waveforms depends on "random_spikes".
1610+
depend on. For instance "templates" depends on "waveforms". "waveforms" depends on "random_spikes".
16071611
1608-
This function is making the reverse way : get all children that depend of a
1612+
This function is going the opposite way: it finds all children that depend on a
16091613
particular extension.
16101614
1611-
This is recursive so this includes : children and so grand children and great grand children
1615+
The implementation is recursive so that the output includes children, grand children, great grand children, etc.
16121616
1613-
This function is usefull for deleting on recompute.
1614-
For instance recompute the "waveforms" need to delete "template"
1615-
This make sens if "ms_before" is change in "waveforms" because the template also depends
1616-
on this parameters.
1617+
This function is useful for deleting existing extensions on recompute.
1618+
For instance, recomputing the "waveforms" needs to delete the "templates", since the latter depends on the former.
1619+
For this particular example, if we change the "ms_before" parameter of the "waveforms", also the "templates" will
1620+
require recomputation as this parameter is inherited.
16171621
"""
16181622
names = []
16191623
children = _extension_children[extension_name]

src/spikeinterface/postprocessing/principal_component.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,12 @@ def run_for_all_spikes(self, file_path=None, verbose=False, **job_kwargs):
359359

360360
job_kwargs = fix_job_kwargs(job_kwargs)
361361
p = self.params
362-
we = self.sorting_analyzer
363-
sorting = we.sorting
362+
sorting_analyzer = self.sorting_analyzer
363+
sorting = sorting_analyzer.sorting
364364
assert (
365-
we.has_recording()
366-
), "To compute PCA projections for all spikes, the waveform extractor needs the recording"
367-
recording = we.recording
365+
sorting_analyzer.has_recording() or sorting_analyzer.has_temporary_recording()
366+
), "To compute PCA projections for all spikes, the sorting analyzer needs the recording"
367+
recording = sorting_analyzer.recording
368368

369369
# assert sorting.get_num_segments() == 1
370370
assert p["mode"] in ("by_channel_local", "by_channel_global")
@@ -374,8 +374,9 @@ def run_for_all_spikes(self, file_path=None, verbose=False, **job_kwargs):
374374

375375
sparsity = self.sorting_analyzer.sparsity
376376
if sparsity is None:
377-
sparse_channels_indices = {unit_id: np.arange(we.get_num_channels()) for unit_id in we.unit_ids}
378-
max_channels_per_template = we.get_num_channels()
377+
num_channels = recording.get_num_channels()
378+
sparse_channels_indices = {unit_id: np.arange(num_channels) for unit_id in sorting_analyzer.unit_ids}
379+
max_channels_per_template = num_channels
379380
else:
380381
sparse_channels_indices = sparsity.unit_id_to_channel_indices
381382
max_channels_per_template = max([chan_inds.size for chan_inds in sparse_channels_indices.values()])
@@ -449,9 +450,7 @@ def _fit_by_channel_local(self, n_jobs, progress_bar):
449450
return pca_models
450451

451452
def _fit_by_channel_global(self, progress_bar):
452-
# we = self.sorting_analyzer
453453
p = self.params
454-
# unit_ids = we.unit_ids
455454
unit_ids = self.sorting_analyzer.unit_ids
456455

457456
# there is one unique PCA accross channels

0 commit comments

Comments
 (0)