Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ behavior they verify rather than listed separately.
Escape, and outside clicks release filter focus so global shortcuts resume.
- Display metadata columns containing multiple values in the Cluster and
Similarity Views instead of leaving their cells blank.
- Rescale the Waveform View y axis when the waveforms type changes. Templates
and mean waveforms are no longer drawn as flat lines after switching away
from raw waveforms, and raw waveforms no longer overflow their box after
switching back.
- Sort text columns holding numbers, such as the channel column `ch`, by
numeric value in the Cluster and Similarity Views. Channel 2 no longer
appears after channel 10.
Expand Down
56 changes: 56 additions & 0 deletions phy/cluster/views/tests/test_waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,59 @@ def on_select_channel(sender, channel_id=None, button=None, key=None):
v.set_state(v.state)

_stop_and_close(qtbot, v)


def test_waveform_view_rescale_on_waveforms_type(qtbot, gui):
nc = 5
ns = 10

raw = 100 * artificial_waveforms(ns, 20, nc)
# Mean waveforms are a thousand times smaller here, the way templates typically
# are next to raw traces.
mean = raw / 1000.0

def _waveforms(data):
def get_waveforms(cluster_id):
return Bunch(
data=data,
channel_ids=np.arange(nc),
channel_positions=staggered_positions(nc),
)

return get_waveforms

v = WaveformView(
waveforms={'waveforms': _waveforms(raw), 'mean_waveforms': _waveforms(mean)},
sample_rate=10000.0,
)
with qtbot.waitExposed(v.canvas):
v.show()
v.attach(gui)

v.on_select(cluster_ids=[0])
raw_max = v.data_bounds[3]
assert raw_max > 0

# The y axis follows the displayed waveforms type, otherwise the smaller
# waveforms are drawn as flat lines.
v.next_waveforms_type()
assert v.waveforms_type == 'mean_waveforms'
ac(v.data_bounds[3], raw_max / 1000.0, rtol=1e-5)

v.previous_waveforms_type()
assert v.waveforms_type == 'waveforms'
ac(v.data_bounds[3], raw_max, rtol=1e-5)

v.toggle_mean_waveforms(True)
assert v.waveforms_type == 'mean_waveforms'
ac(v.data_bounds[3], raw_max / 1000.0, rtol=1e-5)

v.toggle_mean_waveforms(False)
assert v.waveforms_type == 'waveforms'
ac(v.data_bounds[3], raw_max, rtol=1e-5)

v.waveforms_type = 'mean_waveforms'
v.plot()
ac(v.data_bounds[3], raw_max / 1000.0, rtol=1e-5)

_stop_and_close(qtbot, v)
22 changes: 20 additions & 2 deletions phy/cluster/views/waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,27 +511,45 @@ def waveforms_type(self):

@waveforms_type.setter
def waveforms_type(self, value):
previous_type = self.waveforms_type
self.waveforms_types.set(value)
self._rescale_if_waveforms_type_changed(previous_type)

def _rescale_if_waveforms_type_changed(self, previous_type):
"""Discard the cached y axis bounds when the waveforms type has changed.

Raw waveforms, mean waveforms and templates have very different amplitude
scales, so bounds computed for one type make the others unreadable, either as
flat lines or as traces overflowing their box. Dropping the bounds makes the
next plot recompute them for the type now displayed.

"""
if self.waveforms_type != previous_type:
self.data_bounds = None

def next_waveforms_type(self):
"""Switch to the next waveforms type."""
previous_type = self.waveforms_type
self.waveforms_types.next()
self._rescale_if_waveforms_type_changed(previous_type)
logger.debug('Switch to waveforms type %s.', self.waveforms_type)
self.plot()

def previous_waveforms_type(self):
"""Switch to the previous waveforms type."""
previous_type = self.waveforms_type
self.waveforms_types.previous()
self._rescale_if_waveforms_type_changed(previous_type)
logger.debug('Switch to waveforms type %s.', self.waveforms_type)
self.plot()

def toggle_mean_waveforms(self, checked):
"""Switch to the `mean_waveforms` type, if it is available."""
if self.waveforms_type == 'mean_waveforms' and 'waveforms' in self.waveforms:
self.waveforms_types.set('waveforms')
self.waveforms_type = 'waveforms'
logger.debug('Switch to raw waveforms.')
self.plot()
elif 'mean_waveforms' in self.waveforms:
self.waveforms_types.set('mean_waveforms')
self.waveforms_type = 'mean_waveforms'
logger.debug('Switch to mean waveforms.')
self.plot()
Loading