From edca7b2cb24921e3ade02e3803278dfe05fd9ff2 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 12 Jan 2023 16:03:19 -0500 Subject: [PATCH] Breakpoint bad (-ve or too large) x-ranges to m4 This should never really happen but when it does it appears to be a race with writing startup pre-graphics-formatter array data where we get `x_end` epoch value subtracting some really small offset value (like `-/+0.5`) or the opposite where the `x_start` is epoch and `x_end` is small. This adds a warning msg and `breakpoint()` as well as guards around the entire code downsampling code path so that when resumed the downsampling cycle should just be skipped and avoid a crash. --- piker/data/_m4.py | 8 ++++++++ piker/data/_pathops.py | 23 +++++++++++++++-------- piker/ui/_render.py | 14 ++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/piker/data/_m4.py b/piker/data/_m4.py index f75d3209..b9b494d3 100644 --- a/piker/data/_m4.py +++ b/piker/data/_m4.py @@ -91,6 +91,14 @@ def ds_m4( x_end = x[-1] # x end value/highest in domain xrange = (x_end - x_start) + if xrange < 0: + log.error(f'-VE M4 X-RANGE: {x_start} -> {x_end}') + # XXX: broken x-range calc-case, likely the x-end points + # are wrong and have some default value set (such as + # x_end -> while x_start -> 0.5). + breakpoint() + return None + # XXX: always round up on the input pixels # lnx = len(x) # uppx *= max(4 / (1 + math.log(uppx, 2)), 1) diff --git a/piker/data/_pathops.py b/piker/data/_pathops.py index 154b594f..5d514652 100644 --- a/piker/data/_pathops.py +++ b/piker/data/_pathops.py @@ -63,20 +63,27 @@ def xy_downsample( # downsample whenever more then 1 pixels per datum can be shown. # always refresh data bounds until we get diffing # working properly, see above.. - bins, x, y, ymn, ymx = ds_m4( + m4_out = ds_m4( x, y, uppx, ) - # flatten output to 1d arrays suitable for path-graphics generation. - x = np.broadcast_to(x[:, None], y.shape) - x = (x + np.array( - [-x_spacer, 0, 0, x_spacer] - )).flatten() - y = y.flatten() + if m4_out is not None: + bins, x, y, ymn, ymx = m4_out + # flatten output to 1d arrays suitable for path-graphics generation. + x = np.broadcast_to(x[:, None], y.shape) + x = (x + np.array( + [-x_spacer, 0, 0, x_spacer] + )).flatten() + y = y.flatten() - return x, y, ymn, ymx + return x, y, ymn, ymx + + # XXX: we accept a None output for the case where the input range + # to ``ds_m4()`` is bad (-ve) and we want to catch and debug + # that (seemingly super rare) circumstance.. + return None @njit( diff --git a/piker/ui/_render.py b/piker/ui/_render.py index 6024cbac..dc162834 100644 --- a/piker/ui/_render.py +++ b/piker/ui/_render.py @@ -211,17 +211,19 @@ class Renderer(msgspec.Struct): elif should_ds and uppx > 1: - x_1d, y_1d, ymn, ymx = xy_downsample( + ds_out = xy_downsample( x_1d, y_1d, uppx, ) - self.viz.yrange = ymn, ymx - # print(f'{self.viz.name} post ds: ymn, ymx: {ymn},{ymx}') + if ds_out is not None: + x_1d, y_1d, ymn, ymx = ds_out + self.viz.yrange = ymn, ymx + # print(f'{self.viz.name} post ds: ymn, ymx: {ymn},{ymx}') - reset = True - profiler(f'FULL PATH downsample redraw={should_ds}') - self._in_ds = True + reset = True + profiler(f'FULL PATH downsample redraw={should_ds}') + self._in_ds = True path = self.draw_path( x=x_1d,