Skip to content

Commit 63b2c12

Browse files
committed
Fix spikerate and scatter item clicked
1 parent 7357c69 commit 63b2c12

File tree

6 files changed

+66
-62
lines changed

6 files changed

+66
-62
lines changed

spikeinterface_gui/basescatterview.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ def _panel_refresh(self):
461461
colors = []
462462

463463
segment_index = self.controller.get_time()[1]
464+
if segment_index != self.segment_index:
465+
self.segment_index = segment_index
466+
self.segment_selector.value = f"Segment {self.segment_index}"
464467

465468
visible_unit_ids = self.controller.get_visible_unit_ids()
466469
for unit_id in visible_unit_ids:
@@ -487,6 +490,9 @@ def _panel_refresh(self):
487490
line_width=2,
488491
)
489492
self.hist_lines.append(hist_lines)
493+
t_start, t_end = self.controller.get_t_start_t_stop()
494+
self.scatter_fig.x_range.start = t_start
495+
self.scatter_fig.x_range.end = t_end
490496

491497
self._max_count = max_count
492498

@@ -522,7 +528,7 @@ def _panel_change_segment(self, event):
522528
self._current_selected = 0
523529
self.segment_index = int(self.segment_selector.value.split()[-1])
524530
self.controller.set_time(segment_index=self.segment_index)
525-
t_start, t_end = self.controller.get_t_start_t_end()
531+
t_start, t_end = self.controller.get_t_start_t_stop()
526532
self.scatter_fig.x_range.start = t_start
527533
self.scatter_fig.x_range.end = t_end
528534
self.refresh()

spikeinterface_gui/controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ def set_indices_spike_selected(self, inds):
614614
# set time info
615615
segment_index = self.spikes['segment_index'][self._spike_selected_indices[0]]
616616
sample_index = self.spikes['sample_index'][self._spike_selected_indices[0]]
617-
self.set_time(time=sample_index / self.sampling_frequency, segment_index=segment_index)
617+
self.set_time(time=self.sample_index_to_time(sample_index), segment_index=segment_index)
618618

619619
def get_spike_indices(self, unit_id, segment_index=None):
620620
if segment_index is None:

spikeinterface_gui/mainsettingsview.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def on_change_color_mode(self):
4141

4242
def on_use_times(self):
4343
self.controller.main_settings['use_times'] = self.main_settings['use_times']
44-
print("Use times changed:", self.main_settings['use_times'])
4544
self.controller.update_time_info()
4645
self.notify_use_times_updated()
4746
# for view in self.controller.views:

spikeinterface_gui/spikerateview.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ def on_time_info_updated(self):
1919
self.refresh()
2020

2121
def on_use_times_updated(self):
22-
print(f"Refreshing SpikeRateView")
2322
self.refresh()
2423

2524
## Qt ##
@@ -105,25 +104,26 @@ def _panel_make_layout(self):
105104
self.segment_selector.param.watch(self._panel_change_segment, 'value')
106105

107106
self.rate_fig = bpl.figure(
108-
width=250,
109-
height=250,
110107
tools="pan,wheel_zoom,reset",
111108
active_drag="pan",
112109
active_scroll="wheel_zoom",
113110
background_fill_color=_bg_color,
114111
border_fill_color=_bg_color,
115112
outline_line_color="white",
113+
sizing_mode="stretch_both",
116114
)
117115
self.rate_fig.toolbar.logo = None
118116
self.rate_fig.grid.visible = False
119117

120118
self.layout = pn.Column(
121119
pn.Row(self.segment_selector, sizing_mode="stretch_width"),
122-
pn.Row(self.rate_fig,sizing_mode="stretch_both"),
120+
pn.Row(self.rate_fig, sizing_mode="stretch_both"),
123121
)
124122
self.is_warning_active = False
125123

126124
def _panel_refresh(self):
125+
from bokeh.models import Range1d
126+
127127
segment_index = self.controller.get_time()[1]
128128
if segment_index != self.segment_index:
129129
self.segment_index = segment_index
@@ -136,11 +136,12 @@ def _panel_refresh(self):
136136
total_frames = self.controller.final_spike_samples
137137
bins_s = self.settings['bin_s']
138138
num_bins = total_frames[segment_index] // int(sampling_frequency) // bins_s
139-
t_start, _ = self.controller.get_t_start_t_stop()
139+
t_start, t_stop = self.controller.get_t_start_t_stop()
140140

141141
# clear fig
142142
self.rate_fig.renderers = []
143143

144+
max_count = 0
144145
for unit_id in visible_unit_ids:
145146

146147
spike_inds = self.controller.get_spike_indices(unit_id, segment_index=segment_index)
@@ -152,13 +153,15 @@ def _panel_refresh(self):
152153
color = self.get_unit_color(unit_id)
153154

154155
line = self.rate_fig.line(
155-
x=(bins[1:]+bins[:-1])/(2*sampling_frequency) + t_start,
156-
y=count/bins_s,
156+
x=(bins[1:]+bins[:-1]) / (2*sampling_frequency) + t_start,
157+
y=count / bins_s,
157158
color=color,
158159
line_width=2,
159160
)
161+
max_count = max(max_count, np.max(count/bins_s))
160162

161-
self.rate_fig.y_range.start = 0
163+
self.rate_fig.x_range = Range1d(start=t_start, end=t_stop)
164+
self.rate_fig.y_range = Range1d(start=0, end=max_count*1.2)
162165

163166
def _panel_change_segment(self, event):
164167
self.segment_index = int(self.segment_selector.value.split()[-1])

spikeinterface_gui/tracemapview.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,6 @@ def _qt_on_settings_changed(self, do_refresh=True):
115115
def _qt_on_spike_selection_changed(self):
116116
self._qt_seek_with_selected_spike()
117117

118-
119-
def _qt_scatter_item_clicked(self, x, y):
120-
# useless but needed for the MixinViewTrace
121-
pass
122-
123118
def _qt_refresh(self):
124119
t, _ = self.controller.get_time()
125120
self._qt_seek(t)
@@ -181,6 +176,12 @@ def _qt_on_time_info_updated(self):
181176
# we need refresh in QT because changing tab/docking/undocking doesn't trigger a refresh
182177
self.refresh()
183178

179+
def _qt_on_use_times_updated(self):
180+
# Update time seeker
181+
t_start, t_stop = self.controller.get_t_start_t_stop()
182+
self.timeseeker.set_start_stop(t_start, t_stop)
183+
self.timeseeker.seek(self.controller.get_time()[0])
184+
184185
## Panel ##
185186
def _panel_make_layout(self):
186187
import panel as pn
@@ -272,7 +273,7 @@ def _panel_refresh(self):
272273
auto_scale = False
273274

274275
times_chunk, data_curves, scatter_x, scatter_y, scatter_colors = \
275-
self.get_data_in_chunk(t1, t2, seg_index)
276+
self.get_data_in_chunk(t1, t2, segment_index)
276277
data_curves = data_curves.T
277278

278279
if self.color_limit is None:
@@ -304,7 +305,8 @@ def _panel_refresh(self):
304305
# TODO: if from a different unit, change unit visibility
305306
def _panel_on_tap(self, event):
306307
seg_index = self.controller.get_time()[1]
307-
ind_spike_nearest = find_nearest_spike(self.controller, event.x, seg_index)
308+
time = event.x
309+
ind_spike_nearest = find_nearest_spike(self.controller, time, seg_index)
308310
if ind_spike_nearest is not None:
309311
self.controller.set_indices_spike_selected([ind_spike_nearest])
310312
self._panel_seek_with_selected_spike()
@@ -341,6 +343,17 @@ def _panel_on_time_info_updated(self):
341343
self._block_auto_refresh_and_notify = False
342344
# we don't need a refresh in panel because changing tab triggers a refresh
343345

346+
def _panel_on_use_times_updated(self):
347+
# Update time seeker
348+
t_start, t_stop = self.controller.get_t_start_t_stop()
349+
self.time_slider.start = t_start
350+
self.time_slider.end = t_stop
351+
352+
# Optionally clamp the current value if out of range
353+
self.time_slider.value = self.controller.get_time()[0]
354+
355+
self.refresh()
356+
344357

345358
TraceMapView._gui_help_txt = """
346359
## Trace Map View

spikeinterface_gui/traceview.py

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ def _qt_initialize_plot(self):
145145
self.graphicsview.setCentralItem(self.plot)
146146
self.plot.hideButtons()
147147
self.plot.showAxis('left', False)
148-
149148
self.viewBox.doubleclicked.connect(self._qt_scatter_item_clicked)
150149

151150
self.viewBox.gain_zoom.connect(self.apply_gain_zoom)
@@ -240,11 +239,14 @@ def _qt_seek_with_selected_spike(self):
240239
self.notify_time_info_updated()
241240
self.refresh()
242241

243-
def _qt_on_use_times_updated(self):
244-
# Update time seeker
245-
t_start, t_stop = self.controller.get_t_start_t_stop()
246-
self.timeseeker.set_start_stop(t_start, t_stop)
247-
242+
def _qt_scatter_item_clicked(self, x, y):
243+
ind_spike_nearest = find_nearest_spike(self.controller, x, segment_index=self.controller.get_time()[1])
244+
if ind_spike_nearest is not None:
245+
self.controller.set_indices_spike_selected([ind_spike_nearest])
246+
247+
self.notify_spike_selection_changed()
248+
self._qt_seek_with_selected_spike()
249+
248250
## panel ##
249251
def _panel_create_toolbar(self):
250252
import panel as pn
@@ -346,16 +348,6 @@ def _panel_seek_with_selected_spike(self):
346348
self.refresh()
347349
self.notify_time_info_updated()
348350

349-
def _panel_on_use_times_updated(self):
350-
# Update time seeker
351-
t_start, t_stop = self.controller.get_t_start_t_stop()
352-
self.time_slider.start = t_start
353-
self.time_slider.end = t_stop
354-
355-
# Optionally clamp the current value if out of range
356-
self.time_slider.value = max(t_start, min(self.time_slider.value, t_stop))
357-
self.refresh()
358-
359351
# TODO: pan behavior like Qt?
360352
# def _panel_on_pan_start(self, event):
361353
# self.drag_state["x_start"] = event.x
@@ -476,25 +468,6 @@ def _qt_on_settings_changed(self):
476468
def _qt_on_spike_selection_changed(self):
477469
MixinViewTrace._qt_seek_with_selected_spike(self)
478470

479-
def _qt_scatter_item_clicked(self, x, y):
480-
# TODO sam : make it faster without boolean mask
481-
ind_click = int(x*self.controller.sampling_frequency )
482-
in_seg, = np.nonzero(self.controller.spikes['segment_index'] == self.controller.get_time()[1])
483-
nearest = np.argmin(np.abs(self.controller.spikes[in_seg]['sample_index'] - ind_click))
484-
485-
ind_spike_nearest = in_seg[nearest]
486-
sample_index = self.controller.spikes[ind_spike_nearest]['sample_index']
487-
488-
if np.abs(ind_click - sample_index) > (self.controller.sampling_frequency // 30):
489-
return
490-
491-
#~ self.controller.spikes['selected'][:] = False
492-
#~ self.controller.spikes['selected'][ind_spike_nearest] = True
493-
self.controller.set_indices_spike_selected([ind_spike_nearest])
494-
495-
self.notify_spike_selection_changed()
496-
self.refresh()
497-
498471
def _qt_refresh(self):
499472
t, _ = self.controller.get_time()
500473
self._qt_seek(t)
@@ -567,10 +540,11 @@ def _qt_on_time_info_updated(self):
567540
# we need refresh in QT because changing tab/docking/undocking doesn't trigger a refresh
568541
self.refresh()
569542

570-
# def _qt_on_use_times_updated(self):
571-
# # Update time seeker
572-
# t_start, t_stop = self.controller.get_t_start_t_stop()
573-
# self.timeseeker.set_start_stop(t_start, t_stop)
543+
def _qt_on_use_times_updated(self):
544+
# Update time seeker
545+
t_start, t_stop = self.controller.get_t_start_t_stop()
546+
self.timeseeker.set_start_stop(t_start, t_stop)
547+
self.timeseeker.seek(self.controller.get_time()[0])
574548

575549
## panel ##
576550
def _panel_make_layout(self):
@@ -679,7 +653,8 @@ def _panel_refresh(self):
679653

680654
# TODO: if from a different unit, change unit visibility
681655
def _panel_on_tap(self, event):
682-
ind_spike_nearest = find_nearest_spike(self.controller, event.x, self.controller.get_time()[1])
656+
time = event.x
657+
ind_spike_nearest = find_nearest_spike(self.controller, time, self.controller.get_time()[1])
683658
if ind_spike_nearest is not None:
684659
self.controller.set_indices_spike_selected([ind_spike_nearest])
685660
self._panel_seek_with_selected_spike()
@@ -693,8 +668,7 @@ def _panel_gain_zoom(self, event):
693668
factor_ratio = 1.3 if event.delta > 0 else 1 / 1.3
694669
else:
695670
factor_ratio = 1.0
696-
factor = 1.3 if event.delta > 0 else 1 / 1.3
697-
self.apply_gain_zoom(factor)
671+
self.apply_gain_zoom(factor_ratio)
698672

699673
def _panel_auto_scale(self, event):
700674
self.auto_scale()
@@ -709,14 +683,23 @@ def _panel_on_time_info_updated(self):
709683
self._block_auto_refresh = False
710684
# we don't need a refresh in panel because changing tab triggers a refresh
711685

686+
def _panel_on_use_times_updated(self):
687+
# Update time seeker
688+
t_start, t_stop = self.controller.get_t_start_t_stop()
689+
self.time_slider.start = t_start
690+
self.time_slider.end = t_stop
691+
692+
# Optionally clamp the current value if out of range
693+
self.time_slider.value = self.controller.get_time()[0]
694+
self.refresh()
695+
712696

713697

714-
# TODO sam refactor Qt and this
715698
def find_nearest_spike(controller, x, segment_index, max_distance_samples=None):
716699
if max_distance_samples is None:
717700
max_distance_samples = controller.sampling_frequency // 30
718701

719-
ind_click = int(x * controller.sampling_frequency)
702+
ind_click = controller.time_to_sample_index(x)
720703
(in_seg,) = np.nonzero(controller.spikes["segment_index"] == segment_index)
721704

722705
if len(in_seg) == 0:

0 commit comments

Comments
 (0)