|
3 | 3 | from threadpoolctl import threadpool_limits |
4 | 4 | import numpy as np |
5 | 5 |
|
6 | | -from spikeinterface.core.job_tools import ChunkRecordingExecutor, fix_job_kwargs |
7 | | -from spikeinterface.core import get_chunk_with_margin |
| 6 | +# from spikeinterface.core.job_tools import ChunkRecordingExecutor, fix_job_kwargs |
| 7 | +# from spikeinterface.core import get_chunk_with_margin |
| 8 | + |
| 9 | +from spikeinterface.core.job_tools import fix_job_kwargs |
| 10 | +from spikeinterface.core.node_pipeline import run_node_pipeline |
| 11 | + |
8 | 12 |
|
9 | 13 |
|
10 | 14 | def find_spikes_from_templates( |
@@ -42,117 +46,174 @@ def find_spikes_from_templates( |
42 | 46 | job_kwargs = fix_job_kwargs(job_kwargs) |
43 | 47 |
|
44 | 48 | method_class = matching_methods[method] |
| 49 | + node0 = method_class(recording, **method_kwargs) |
| 50 | + nodes = [node0] |
45 | 51 |
|
46 | | - # initialize |
47 | | - method_kwargs = method_class.initialize_and_check_kwargs(recording, method_kwargs) |
48 | | - |
49 | | - # add |
50 | | - method_kwargs["margin"] = method_class.get_margin(recording, method_kwargs) |
51 | | - |
52 | | - # serialiaze for worker |
53 | | - method_kwargs_seralized = method_class.serialize_method_kwargs(method_kwargs) |
54 | | - |
55 | | - # and run |
56 | | - func = _find_spikes_chunk |
57 | | - init_func = _init_worker_find_spikes |
58 | | - init_args = (recording, method, method_kwargs_seralized) |
59 | | - processor = ChunkRecordingExecutor( |
| 52 | + spikes = run_node_pipeline( |
60 | 53 | recording, |
61 | | - func, |
62 | | - init_func, |
63 | | - init_args, |
64 | | - handle_returns=True, |
| 54 | + nodes, |
| 55 | + job_kwargs, |
65 | 56 | job_name=f"find spikes ({method})", |
66 | | - verbose=verbose, |
67 | | - **job_kwargs, |
| 57 | + gather_mode="memory", |
| 58 | + squeeze_output=True, |
68 | 59 | ) |
69 | | - spikes = processor.run() |
70 | | - |
71 | | - spikes = np.concatenate(spikes) |
72 | | - |
73 | 60 | if extra_outputs: |
| 61 | + # TODO deprecated extra_outputs |
| 62 | + method_kwargs = {} |
74 | 63 | return spikes, method_kwargs |
75 | 64 | else: |
76 | 65 | return spikes |
77 | 66 |
|
78 | 67 |
|
79 | | -def _init_worker_find_spikes(recording, method, method_kwargs): |
80 | | - """Initialize worker for finding spikes.""" |
81 | 68 |
|
82 | | - from .method_list import matching_methods |
| 69 | +# def find_spikes_from_templates( |
| 70 | +# recording, method="naive", method_kwargs={}, extra_outputs=False, verbose=False, **job_kwargs |
| 71 | +# ) -> np.ndarray | tuple[np.ndarray, dict]: |
| 72 | +# """Find spike from a recording from given templates. |
83 | 73 |
|
84 | | - method_class = matching_methods[method] |
85 | | - method_kwargs = method_class.unserialize_in_worker(method_kwargs) |
| 74 | +# Parameters |
| 75 | +# ---------- |
| 76 | +# recording : RecordingExtractor |
| 77 | +# The recording extractor object |
| 78 | +# method : "naive" | "tridesclous" | "circus" | "circus-omp" | "wobble", default: "naive" |
| 79 | +# Which method to use for template matching |
| 80 | +# method_kwargs : dict, optional |
| 81 | +# Keyword arguments for the chosen method |
| 82 | +# extra_outputs : bool |
| 83 | +# If True then method_kwargs is also returned |
| 84 | +# **job_kwargs : dict |
| 85 | +# Parameters for ChunkRecordingExecutor |
| 86 | +# verbose : Bool, default: False |
| 87 | +# If True, output is verbose |
86 | 88 |
|
87 | | - # create a local dict per worker |
88 | | - worker_ctx = {} |
89 | | - worker_ctx["recording"] = recording |
90 | | - worker_ctx["method"] = method |
91 | | - worker_ctx["method_kwargs"] = method_kwargs |
92 | | - worker_ctx["function"] = method_class.main_function |
| 89 | +# Returns |
| 90 | +# ------- |
| 91 | +# spikes : ndarray |
| 92 | +# Spikes found from templates. |
| 93 | +# method_kwargs: |
| 94 | +# Optionaly returns for debug purpose. |
93 | 95 |
|
94 | | - return worker_ctx |
| 96 | +# """ |
| 97 | +# from .method_list import matching_methods |
95 | 98 |
|
| 99 | +# assert method in matching_methods, f"The 'method' {method} is not valid. Use a method from {matching_methods}" |
96 | 100 |
|
97 | | -def _find_spikes_chunk(segment_index, start_frame, end_frame, worker_ctx): |
98 | | - """Find spikes from a chunk of data.""" |
| 101 | +# job_kwargs = fix_job_kwargs(job_kwargs) |
99 | 102 |
|
100 | | - # recover variables of the worker |
101 | | - recording = worker_ctx["recording"] |
102 | | - method = worker_ctx["method"] |
103 | | - method_kwargs = worker_ctx["method_kwargs"] |
104 | | - margin = method_kwargs["margin"] |
| 103 | +# method_class = matching_methods[method] |
105 | 104 |
|
106 | | - # load trace in memory given some margin |
107 | | - recording_segment = recording._recording_segments[segment_index] |
108 | | - traces, left_margin, right_margin = get_chunk_with_margin( |
109 | | - recording_segment, start_frame, end_frame, None, margin, add_zeros=True |
110 | | - ) |
| 105 | +# # initialize |
| 106 | +# method_kwargs = method_class.initialize_and_check_kwargs(recording, method_kwargs) |
| 107 | + |
| 108 | +# # add |
| 109 | +# method_kwargs["margin"] = method_class.get_margin(recording, method_kwargs) |
| 110 | + |
| 111 | +# # serialiaze for worker |
| 112 | +# method_kwargs_seralized = method_class.serialize_method_kwargs(method_kwargs) |
| 113 | + |
| 114 | +# # and run |
| 115 | +# func = _find_spikes_chunk |
| 116 | +# init_func = _init_worker_find_spikes |
| 117 | +# init_args = (recording, method, method_kwargs_seralized) |
| 118 | +# processor = ChunkRecordingExecutor( |
| 119 | +# recording, |
| 120 | +# func, |
| 121 | +# init_func, |
| 122 | +# init_args, |
| 123 | +# handle_returns=True, |
| 124 | +# job_name=f"find spikes ({method})", |
| 125 | +# verbose=verbose, |
| 126 | +# **job_kwargs, |
| 127 | +# ) |
| 128 | +# spikes = processor.run() |
| 129 | + |
| 130 | +# spikes = np.concatenate(spikes) |
| 131 | + |
| 132 | +# if extra_outputs: |
| 133 | +# return spikes, method_kwargs |
| 134 | +# else: |
| 135 | +# return spikes |
| 136 | + |
| 137 | + |
| 138 | + |
| 139 | + |
| 140 | +# def _init_worker_find_spikes(recording, method, method_kwargs): |
| 141 | +# """Initialize worker for finding spikes.""" |
| 142 | + |
| 143 | +# from .method_list import matching_methods |
| 144 | + |
| 145 | +# method_class = matching_methods[method] |
| 146 | +# method_kwargs = method_class.unserialize_in_worker(method_kwargs) |
| 147 | + |
| 148 | +# # create a local dict per worker |
| 149 | +# worker_ctx = {} |
| 150 | +# worker_ctx["recording"] = recording |
| 151 | +# worker_ctx["method"] = method |
| 152 | +# worker_ctx["method_kwargs"] = method_kwargs |
| 153 | +# worker_ctx["function"] = method_class.main_function |
| 154 | + |
| 155 | +# return worker_ctx |
| 156 | + |
| 157 | + |
| 158 | +# def _find_spikes_chunk(segment_index, start_frame, end_frame, worker_ctx): |
| 159 | +# """Find spikes from a chunk of data.""" |
| 160 | + |
| 161 | +# # recover variables of the worker |
| 162 | +# recording = worker_ctx["recording"] |
| 163 | +# method = worker_ctx["method"] |
| 164 | +# method_kwargs = worker_ctx["method_kwargs"] |
| 165 | +# margin = method_kwargs["margin"] |
| 166 | + |
| 167 | +# # load trace in memory given some margin |
| 168 | +# recording_segment = recording._recording_segments[segment_index] |
| 169 | +# traces, left_margin, right_margin = get_chunk_with_margin( |
| 170 | +# recording_segment, start_frame, end_frame, None, margin, add_zeros=True |
| 171 | +# ) |
| 172 | + |
| 173 | +# function = worker_ctx["function"] |
| 174 | + |
| 175 | +# with threadpool_limits(limits=1): |
| 176 | +# spikes = function(traces, method_kwargs) |
| 177 | + |
| 178 | +# # remove spikes in margin |
| 179 | +# if margin > 0: |
| 180 | +# keep = (spikes["sample_index"] >= margin) & (spikes["sample_index"] < (traces.shape[0] - margin)) |
| 181 | +# spikes = spikes[keep] |
| 182 | + |
| 183 | +# spikes["sample_index"] += start_frame - margin |
| 184 | +# spikes["segment_index"] = segment_index |
| 185 | +# return spikes |
| 186 | + |
| 187 | + |
| 188 | +# # generic class for template engine |
| 189 | +# class BaseTemplateMatchingEngine: |
| 190 | +# default_params = {} |
| 191 | + |
| 192 | +# @classmethod |
| 193 | +# def initialize_and_check_kwargs(cls, recording, kwargs): |
| 194 | +# """This function runs before loops""" |
| 195 | +# # need to be implemented in subclass |
| 196 | +# raise NotImplementedError |
111 | 197 |
|
112 | | - function = worker_ctx["function"] |
113 | | - |
114 | | - with threadpool_limits(limits=1): |
115 | | - spikes = function(traces, method_kwargs) |
116 | | - |
117 | | - # remove spikes in margin |
118 | | - if margin > 0: |
119 | | - keep = (spikes["sample_index"] >= margin) & (spikes["sample_index"] < (traces.shape[0] - margin)) |
120 | | - spikes = spikes[keep] |
121 | | - |
122 | | - spikes["sample_index"] += start_frame - margin |
123 | | - spikes["segment_index"] = segment_index |
124 | | - return spikes |
125 | | - |
126 | | - |
127 | | -# generic class for template engine |
128 | | -class BaseTemplateMatchingEngine: |
129 | | - default_params = {} |
130 | | - |
131 | | - @classmethod |
132 | | - def initialize_and_check_kwargs(cls, recording, kwargs): |
133 | | - """This function runs before loops""" |
134 | | - # need to be implemented in subclass |
135 | | - raise NotImplementedError |
136 | | - |
137 | | - @classmethod |
138 | | - def serialize_method_kwargs(cls, kwargs): |
139 | | - """This function serializes kwargs to distribute them to workers""" |
140 | | - # need to be implemented in subclass |
141 | | - raise NotImplementedError |
142 | | - |
143 | | - @classmethod |
144 | | - def unserialize_in_worker(cls, recording, kwargs): |
145 | | - """This function unserializes kwargs in workers""" |
146 | | - # need to be implemented in subclass |
147 | | - raise NotImplementedError |
148 | | - |
149 | | - @classmethod |
150 | | - def get_margin(cls, recording, kwargs): |
151 | | - # need to be implemented in subclass |
152 | | - raise NotImplementedError |
153 | | - |
154 | | - @classmethod |
155 | | - def main_function(cls, traces, method_kwargs): |
156 | | - """This function returns the number of samples for the chunk margins""" |
157 | | - # need to be implemented in subclass |
158 | | - raise NotImplementedError |
| 198 | +# @classmethod |
| 199 | +# def serialize_method_kwargs(cls, kwargs): |
| 200 | +# """This function serializes kwargs to distribute them to workers""" |
| 201 | +# # need to be implemented in subclass |
| 202 | +# raise NotImplementedError |
| 203 | + |
| 204 | +# @classmethod |
| 205 | +# def unserialize_in_worker(cls, recording, kwargs): |
| 206 | +# """This function unserializes kwargs in workers""" |
| 207 | +# # need to be implemented in subclass |
| 208 | +# raise NotImplementedError |
| 209 | + |
| 210 | +# @classmethod |
| 211 | +# def get_margin(cls, recording, kwargs): |
| 212 | +# # need to be implemented in subclass |
| 213 | +# raise NotImplementedError |
| 214 | + |
| 215 | +# @classmethod |
| 216 | +# def main_function(cls, traces, method_kwargs): |
| 217 | +# """This function returns the number of samples for the chunk margins""" |
| 218 | +# # need to be implemented in subclass |
| 219 | +# raise NotImplementedError |
0 commit comments