From 9befc1fb1a244a8dfa14dbbd03abe578463b08a8 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Sun, 3 Apr 2022 23:30:10 -0400 Subject: [PATCH] Toy with caching ds data, probably will revert.. --- piker/ui/_curve.py | 201 ++++++++++++++++----------------------------- 1 file changed, 70 insertions(+), 131 deletions(-) diff --git a/piker/ui/_curve.py b/piker/ui/_curve.py index dcc621f5..97fa5c23 100644 --- a/piker/ui/_curve.py +++ b/piker/ui/_curve.py @@ -223,9 +223,9 @@ class FastAppendCurve(pg.GraphicsObject): lbar = max(l, start) rbar = min(r, stop) - return vb.mapViewToDevice( + return round(vb.mapViewToDevice( QLineF(lbar, 0, rbar, 0) - ).length() + ).length()) # def should_ds_or_redraw( # self, @@ -297,7 +297,7 @@ class FastAppendCurve(pg.GraphicsObject): y = y.flatten() # presumably? - self._in_ds = True + # self._in_ds = True return x, y def maybe_downsample( @@ -339,29 +339,30 @@ class FastAppendCurve(pg.GraphicsObject): gt=ms_slower_then, ) flip_cache = False - - if self._xrange: - istart, istop = self._xrange - else: - self._xrange = istart, istop = x[0], x[-1] - # print(f"xrange: {self._xrange}") + draw_full_path = True # XXX: lol brutal, the internals of `CurvePoint` (inherited by # our `LineDot`) required ``.getData()`` to work.. self.xData = x self.yData = y + + # update internal array refs self._x, self._y = x, y - # _, x_last = self._xrange = x[0], x[-1] - # vr = self.viewRect() - # l, r = int(vr.left()), int(vr.right()) - # l, r = self.view_range() - # array = self._arrays[self.name] - # start_index = ohlc[0]['index'] - # lbar = max(l, start_index) - start_index - # rbar = min(r, ohlc[-1]['index']) - start_index + # compute the length diffs between the first/last index entry in + # the input data and the last indexes we have on record from the + # last time we updated the curve index. + if self._xrange: + istart, istop = self._xrange + else: + self._xrange = istart, istop = x[0], x[-1] + + prepend_length = int(istart - x[0]) + append_length = int(x[-1] - istop) + + # print(f"xrange: {self._xrange}") if view_range: - # lbar, rbar = view_range + li, ri = view_range # x, y = x[lbar:rbar], y[lbar:rbar] # x, y = x_iv, y_iv profiler(f'view range slice {view_range}') @@ -373,7 +374,6 @@ class FastAppendCurve(pg.GraphicsObject): uppx = self.x_uppx() px_width = self.px_width() uppx_diff = (uppx - self._last_uppx) - self._last_uppx = uppx # step mode: draw flat top discrete "step" # over the index space for each datum. @@ -401,6 +401,30 @@ class FastAppendCurve(pg.GraphicsObject): x_to_path, y_to_path = x_iv_out, y_iv_out ds_key = px_width, uppx + + # always re-ds if we were dsed but the input range changes. + if self._in_ds: + # slice out the portion of the downsampled data that is + # "in view" and **only** draw a path for that. + + entry = self._ds_cache.get(ds_key) + if entry: + x_ds_out, y_ds_out, first_i, last_i = entry + + # if last_i == x[-1]: + log.info( + f'{self._name} has cached ds {ds_key} -> {entry}' + ) + prepend_length = int(first_i - ri) + append_length = int(ri - last_i) + + # x_to_path = x_ds_out + # y_to_path = y_ds_out + + # else: + # log.warn(f'{self._name} ds updates unhandled!') + # DS only the new part? + # check for downsampling conditions if ( # std m4 downsample conditions @@ -408,10 +432,13 @@ class FastAppendCurve(pg.GraphicsObject): or uppx_diff <= -2 or self._step_mode and abs(uppx_diff) >= 2 + # or self._in_ds and px_width > 1 ): + # if not uppx_diff >= 1: log.info( f'{self._name} sampler change: {self._last_uppx} -> {uppx}' ) + self._last_uppx = uppx # should_ds = {'px_width': px_width, 'uppx': uppx} # if self._step_mode: @@ -430,10 +457,18 @@ class FastAppendCurve(pg.GraphicsObject): px_width=px_width, uppx=uppx, ) - profiler(f'path downsample ds_key={ds_key}') + profiler( + f'path downsample ds_key={ds_key}\n' + f'{x_iv_out.size}, {y_iv_out.size}' + ) # cache downsampled outputs - self._ds_cache[ds_key] = x_ds_out, y_ds_out, x[-1] + self._ds_cache[ds_key] = ( + x_ds_out, + y_ds_out, + x[0], + x[-1], + ) x_to_path = x_ds_out y_to_path = y_ds_out @@ -458,48 +493,27 @@ class FastAppendCurve(pg.GraphicsObject): self._in_ds = False - # always re-ds if we were dsed but the input range changes. - elif ( - self._in_ds # and self._last_vr != view_range - ): - # slice out the portion of the downsampled data that is - # "in view" and **only** draw a path for that. - - entry = self._ds_cache.get(ds_key) - if entry: - x_ds_out, y_ds_out, last_i = entry - - # if last_i == x[-1]: - log.info( - f'{self._name} has cached ds {ds_key} -> {entry}' - ) - # x_to_path = x_ds_out - # y_to_path = y_ds_out - - # else: - # log.warn(f'{self._name} ds updates unhandled!') - # DS only the new part? # render path graphics - log.info( - # f'{self._name}: last sizes {x_to_path.size}, {y_to_path.size}', - f'{self._name}: sizes {x_to_path.size}, {y_to_path.size}', - ) + # log.info( + # # f'{self._name}: last sizes {x_to_path.size}, {y_to_path.size}', + # f'{self._name}: sizes {x_to_path.size}, {y_to_path.size}', + # ) self._last_topaths = x_to_path, y_to_path no_path_yet = self.path is None - self.path = pg.functions.arrayToQPath( - x_to_path, - y_to_path, - connect='all', - finiteCheck=False, - path=self.path, - ) - profiler(f'DRAW PATH IN VIEW -> {self._name}') + if draw_full_path: + self.path = pg.functions.arrayToQPath( + x_to_path, + y_to_path, + connect='all', + finiteCheck=False, + path=self.path, + ) + profiler('generated FULL PATH -> {self._name}') - self._last_vr = view_range # reserve mem allocs see: # - https://doc.qt.io/qt-5/qpainterpath.html#reserve # - https://doc.qt.io/qt-5/qpainterpath.html#capacity @@ -510,82 +524,7 @@ class FastAppendCurve(pg.GraphicsObject): if no_path_yet: self.path.reserve(int(500e3)) - profiler('generated fresh path') - - # if should_redraw and not should_ds: - # log.info(f'DEDOWN -> {self._name}') - # self._in_ds = False - - # should_ds, should_redraw = self.should_ds_or_redraw() - # print( - # f'{self._name} should ds: {should_ds}') - - # if self._in_ds: - # if should_ds or view_range: - - # compute the length diffs between the first/last index entry in - # the input data and the last indexes we have on record from the - # last time we updated the curve index. - prepend_length = int(istart - x[0]) - - # append_length = int(x[-1] - istop) - - # if ( - # view_range - # or should_redraw or should_ds - # or self.path is None - # or prepend_length > 0 - # ): - # # step mode: draw flat top discrete "step" - # # over the index space for each datum. - # if self._step_mode: - # x_out, y_out = step_path_arrays_from_1d( - # x[:-1], y[:-1] - # ) - # # TODO: numba this bish - # profiler('generated step arrays') - - # else: - # # by default we only pull data up to the last (current) index - # x_out, y_out = x[:-1], y[:-1] - - - # if should_redraw: - # profiler('path reversion to non-ds') - # if self.path: - # self.path.clear() - - # if self.fast_path: - # self.fast_path.clear() - - # if should_redraw and not should_ds: - # log.info(f'DEDOWN -> {self._name}') - # self._in_ds = False - - # self.path = pg.functions.arrayToQPath( - # x_out, - # y_out, - # connect='all', - # finiteCheck=False, - # path=self.path, - # ) - # profiler(f'DRAW PATH IN VIEW -> {self._name}') - - # self._last_vr = view_range - # # reserve mem allocs see: - # # - https://doc.qt.io/qt-5/qpainterpath.html#reserve - # # - https://doc.qt.io/qt-5/qpainterpath.html#capacity - # # - https://doc.qt.io/qt-5/qpainterpath.html#clear - # # XXX: right now this is based on had hoc checks on a - # # hidpi 3840x2160 4k monitor but we should optimize for - # # the target display(s) on the sys. - # # if no_path_yet: - # # self.path.reserve(int(500e3)) - - # profiler('generated fresh path') - - # if self._step_mode: - # self.path.closeSubpath() + self._last_vr = view_range # TODO: get this piecewise prepend working - right now it's # giving heck on vwap...