Toy with caching ds data, probably will revert..
parent
54a1397d2c
commit
9befc1fb1a
|
@ -223,9 +223,9 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
lbar = max(l, start)
|
lbar = max(l, start)
|
||||||
rbar = min(r, stop)
|
rbar = min(r, stop)
|
||||||
|
|
||||||
return vb.mapViewToDevice(
|
return round(vb.mapViewToDevice(
|
||||||
QLineF(lbar, 0, rbar, 0)
|
QLineF(lbar, 0, rbar, 0)
|
||||||
).length()
|
).length())
|
||||||
|
|
||||||
# def should_ds_or_redraw(
|
# def should_ds_or_redraw(
|
||||||
# self,
|
# self,
|
||||||
|
@ -297,7 +297,7 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
y = y.flatten()
|
y = y.flatten()
|
||||||
|
|
||||||
# presumably?
|
# presumably?
|
||||||
self._in_ds = True
|
# self._in_ds = True
|
||||||
return x, y
|
return x, y
|
||||||
|
|
||||||
def maybe_downsample(
|
def maybe_downsample(
|
||||||
|
@ -339,29 +339,30 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
gt=ms_slower_then,
|
gt=ms_slower_then,
|
||||||
)
|
)
|
||||||
flip_cache = False
|
flip_cache = False
|
||||||
|
draw_full_path = True
|
||||||
if self._xrange:
|
|
||||||
istart, istop = self._xrange
|
|
||||||
else:
|
|
||||||
self._xrange = istart, istop = x[0], x[-1]
|
|
||||||
# print(f"xrange: {self._xrange}")
|
|
||||||
|
|
||||||
# XXX: lol brutal, the internals of `CurvePoint` (inherited by
|
# XXX: lol brutal, the internals of `CurvePoint` (inherited by
|
||||||
# our `LineDot`) required ``.getData()`` to work..
|
# our `LineDot`) required ``.getData()`` to work..
|
||||||
self.xData = x
|
self.xData = x
|
||||||
self.yData = y
|
self.yData = y
|
||||||
|
|
||||||
|
# update internal array refs
|
||||||
self._x, self._y = x, y
|
self._x, self._y = x, y
|
||||||
|
|
||||||
# _, x_last = self._xrange = x[0], x[-1]
|
# compute the length diffs between the first/last index entry in
|
||||||
# vr = self.viewRect()
|
# the input data and the last indexes we have on record from the
|
||||||
# l, r = int(vr.left()), int(vr.right())
|
# last time we updated the curve index.
|
||||||
# l, r = self.view_range()
|
if self._xrange:
|
||||||
# array = self._arrays[self.name]
|
istart, istop = self._xrange
|
||||||
# start_index = ohlc[0]['index']
|
else:
|
||||||
# lbar = max(l, start_index) - start_index
|
self._xrange = istart, istop = x[0], x[-1]
|
||||||
# rbar = min(r, ohlc[-1]['index']) - start_index
|
|
||||||
|
prepend_length = int(istart - x[0])
|
||||||
|
append_length = int(x[-1] - istop)
|
||||||
|
|
||||||
|
# print(f"xrange: {self._xrange}")
|
||||||
if view_range:
|
if view_range:
|
||||||
# lbar, rbar = view_range
|
li, ri = view_range
|
||||||
# x, y = x[lbar:rbar], y[lbar:rbar]
|
# x, y = x[lbar:rbar], y[lbar:rbar]
|
||||||
# x, y = x_iv, y_iv
|
# x, y = x_iv, y_iv
|
||||||
profiler(f'view range slice {view_range}')
|
profiler(f'view range slice {view_range}')
|
||||||
|
@ -373,7 +374,6 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
uppx = self.x_uppx()
|
uppx = self.x_uppx()
|
||||||
px_width = self.px_width()
|
px_width = self.px_width()
|
||||||
uppx_diff = (uppx - self._last_uppx)
|
uppx_diff = (uppx - self._last_uppx)
|
||||||
self._last_uppx = uppx
|
|
||||||
|
|
||||||
# step mode: draw flat top discrete "step"
|
# step mode: draw flat top discrete "step"
|
||||||
# over the index space for each datum.
|
# 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
|
x_to_path, y_to_path = x_iv_out, y_iv_out
|
||||||
|
|
||||||
ds_key = px_width, uppx
|
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
|
# check for downsampling conditions
|
||||||
if (
|
if (
|
||||||
# std m4 downsample conditions
|
# std m4 downsample conditions
|
||||||
|
@ -408,10 +432,13 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
or uppx_diff <= -2
|
or uppx_diff <= -2
|
||||||
or self._step_mode and abs(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(
|
log.info(
|
||||||
f'{self._name} sampler change: {self._last_uppx} -> {uppx}'
|
f'{self._name} sampler change: {self._last_uppx} -> {uppx}'
|
||||||
)
|
)
|
||||||
|
self._last_uppx = uppx
|
||||||
# should_ds = {'px_width': px_width, 'uppx': uppx}
|
# should_ds = {'px_width': px_width, 'uppx': uppx}
|
||||||
|
|
||||||
# if self._step_mode:
|
# if self._step_mode:
|
||||||
|
@ -430,10 +457,18 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
px_width=px_width,
|
px_width=px_width,
|
||||||
uppx=uppx,
|
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
|
# 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
|
x_to_path = x_ds_out
|
||||||
y_to_path = y_ds_out
|
y_to_path = y_ds_out
|
||||||
|
@ -458,48 +493,27 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
|
|
||||||
self._in_ds = False
|
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
|
# render path graphics
|
||||||
log.info(
|
# log.info(
|
||||||
# f'{self._name}: last sizes {x_to_path.size}, {y_to_path.size}',
|
# # 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}',
|
# f'{self._name}: sizes {x_to_path.size}, {y_to_path.size}',
|
||||||
)
|
# )
|
||||||
|
|
||||||
self._last_topaths = x_to_path, y_to_path
|
self._last_topaths = x_to_path, y_to_path
|
||||||
|
|
||||||
no_path_yet = self.path is None
|
no_path_yet = self.path is None
|
||||||
|
|
||||||
self.path = pg.functions.arrayToQPath(
|
if draw_full_path:
|
||||||
x_to_path,
|
self.path = pg.functions.arrayToQPath(
|
||||||
y_to_path,
|
x_to_path,
|
||||||
connect='all',
|
y_to_path,
|
||||||
finiteCheck=False,
|
connect='all',
|
||||||
path=self.path,
|
finiteCheck=False,
|
||||||
)
|
path=self.path,
|
||||||
profiler(f'DRAW PATH IN VIEW -> {self._name}')
|
)
|
||||||
|
profiler('generated FULL PATH -> {self._name}')
|
||||||
|
|
||||||
self._last_vr = view_range
|
|
||||||
# reserve mem allocs see:
|
# reserve mem allocs see:
|
||||||
# - https://doc.qt.io/qt-5/qpainterpath.html#reserve
|
# - 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#capacity
|
||||||
|
@ -510,82 +524,7 @@ class FastAppendCurve(pg.GraphicsObject):
|
||||||
if no_path_yet:
|
if no_path_yet:
|
||||||
self.path.reserve(int(500e3))
|
self.path.reserve(int(500e3))
|
||||||
|
|
||||||
profiler('generated fresh path')
|
self._last_vr = view_range
|
||||||
|
|
||||||
# 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()
|
|
||||||
|
|
||||||
# TODO: get this piecewise prepend working - right now it's
|
# TODO: get this piecewise prepend working - right now it's
|
||||||
# giving heck on vwap...
|
# giving heck on vwap...
|
||||||
|
|
Loading…
Reference in New Issue