Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
c1b7063
Drop the legacy `relayed_from` cruft from our view box
goodboy Nov 14, 2022
fe932a9
Make `PlotItemOverlay` add items inwards->out
goodboy Nov 16, 2022
4d2b5c8
Use `Curve.x_last()` for zoom focal point
goodboy Dec 7, 2022
7e29c36
Modernize optional path variable type annots
goodboy Dec 28, 2022
e742d18
Mouse interaction tweaks
goodboy Dec 28, 2022
65dca16
Always zero-on-step $vlm
goodboy Jan 3, 2023
3e17e52
Add back another panes resize during startup
goodboy Jan 3, 2023
63f0567
Drop `Flume.index_stream()`, `._sampling.open_sample_stream()` replac…
goodboy Jan 5, 2023
02c3ea1
Use `open_sample_stream()` in display loop
goodboy Jan 5, 2023
c5db729
Fix query-mode cursor labels to work with epoch-indexing
goodboy Jan 5, 2023
12c6d58
Drop bp blocks from formatters mod
goodboy Jan 5, 2023
7afc930
Handle last-in-view time slicing edge case
goodboy Jan 5, 2023
4027d68
Clean a buncha cruft from render mod
goodboy Jan 5, 2023
0c5b5a5
Take outer-interval values in `Viz.datums_range()`
goodboy Jan 6, 2023
5ea4be1
Make (cache) search-results a `set` and avoid overlay duplicate entries
goodboy Jan 6, 2023
35cc37d
Lol, pull hist chart from the display state
goodboy Jan 6, 2023
efa4089
Attempt to keep selected item highlighted
goodboy Jan 9, 2023
4a6339f
Downthrottle to 16Hz on multi-feed charts
goodboy Jan 12, 2023
5ced05a
Breakpoint bad (-ve or too large) x-ranges to m4
goodboy Jan 12, 2023
a8e1796
Comment bad x-range bp for now
goodboy Jan 13, 2023
4ba9949
Fix `open_trade_ledger()` enter value type annot
goodboy Jan 13, 2023
0fc06a9
Passthrough `tractor` kwargs directly
goodboy Jan 13, 2023
92ce1b3
Only handle hist discrepancies when market is open
goodboy Jan 13, 2023
c09c392
Drop multi mxmn from display mod
goodboy Jan 14, 2023
bcf2a98
Drop x-range query from `ChartPlotWidget.maxmin()`
goodboy Jan 14, 2023
07c8ed8
Use (modern) literal type annots in view code
goodboy Jan 14, 2023
23c03a0
Add back coord-caching to ohlc graphic
goodboy Jan 15, 2023
da618e1
Always cache `read_slc` alongside y-mnmx values
goodboy Jan 16, 2023
97bb3b4
Set a `PlotItem.viz` for interaction lookup
goodboy Jan 16, 2023
934b32c
Use `Viz` over charts where possible in display loop
goodboy Jan 16, 2023
4003729
Use `Viz.update_graphics()` throughout remainder of graphics loop whe…
goodboy Jan 17, 2023
60440bc
Ensure full hist OHLC path is drawn on tread
goodboy Jan 17, 2023
1add591
Only update last datum graphic(s) on clear ticks
goodboy Jan 17, 2023
d622b41
Only draw up to 2nd last datum for OHLC bars paths
goodboy Jan 17, 2023
433697c
Add cached refs to last 1d xy outputs
goodboy Jan 17, 2023
9650b32
Use `Viz.draw_last()` inside `.update_graphics()`
goodboy Jan 17, 2023
b71c61e
More thoroughly profile the display loop
goodboy Jan 17, 2023
3ad7844
Drop `ChartView._maxmin()` idea, use `Viz.maxmin()`
goodboy Jan 18, 2023
a3bbbed
Drop `ChartView._maxmin()` usage in `.ui._fsp`
goodboy Jan 18, 2023
f9eb880
Backlink subchart views to "main chart" in `.add_plot()`
goodboy Jan 18, 2023
e1e3afb
Support read-slice input to `Viz.maxmin()`
goodboy Jan 18, 2023
9780263
Adjust vlm fsp code to new `Viz.update_graphics()` output sig
goodboy Jan 18, 2023
8b5b1c2
Rework display loop maxmin-ing with `Viz` pipelining
goodboy Jan 18, 2023
1606b3a
Document `Viz.incr_info()` outputs
goodboy Jan 18, 2023
efddd43
Drop masked `._maxmin()` override code from fsp stuff
goodboy Jan 19, 2023
5d9b7c7
Fix `Viz.draw_last()` to divide by `.flat_index_ratio` for uppx index…
goodboy Jan 19, 2023
1a10514
Disable coordinate caching on OHLC ds curves to avoid smearing
goodboy Jan 19, 2023
72a9af2
Fix profiler f-strings
goodboy Jan 19, 2023
33df4f9
Return `in_view: bool` from `Viz.update_graphics()`
goodboy Jan 22, 2023
a36d4b1
Factor color and cache mode settings into `FlowGraphics`
goodboy Jan 23, 2023
49ca743
Add back `.prepareGeometryChange()`, seems faster?
goodboy Jan 23, 2023
731eb91
Make profiler work when nested and not?
goodboy Jan 23, 2023
81b8cd5
Use normal pen when last-datum color not provided
goodboy Jan 24, 2023
9876f20
Support chart draw-api-kwargs-passthrough in lined plot meths
goodboy Jan 24, 2023
9ce5203
Fix `do_px_step` output for epoch step sizing
goodboy Jan 24, 2023
ebf53e3
Fix return type annot for `slice_from_time()`
goodboy Jan 24, 2023
59f34c9
Return fast on bad range in `.default_view()`
goodboy Jan 24, 2023
fefb0de
Don't update overlays as fsps
goodboy Feb 3, 2023
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
2 changes: 1 addition & 1 deletion piker/_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ async def open_piker_runtime(
# and spawn the service tree distributed per that.
start_method: str = 'trio',

tractor_kwargs: dict = {},
**tractor_kwargs,

) -> tuple[
tractor.Actor,
Expand Down
13 changes: 11 additions & 2 deletions piker/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,14 @@ def __new__(
# don't do anything
return cls._disabledProfiler

# create an actual profiling object
cls._depth += 1
obj = super(Profiler, cls).__new__(cls)
obj._msgs = []

# create an actual profiling object
if cls._depth < 1:
cls._msgs = []

obj._name = msg or func_qualname
obj._delayed = delayed
obj._markCount = 0
Expand All @@ -174,8 +179,12 @@ def __call__(self, msg=None):

self._markCount += 1
newTime = perf_counter()
tot_ms = (newTime - self._firstTime) * 1000
ms = (newTime - self._lastTime) * 1000
self._newMsg(" %s: %0.4f ms", msg, ms)
self._newMsg(
f" {msg}: {ms:0.4f}, tot:{tot_ms:0.4f}"
)

self._lastTime = newTime

def mark(self, msg=None):
Expand Down
81 changes: 31 additions & 50 deletions piker/data/_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class IncrementalFormatter(msgspec.Struct):
shm: ShmArray
viz: Viz

# the value to be multiplied any any index into the x/y_1d arrays
# given the input index is based on the original source data array.
flat_index_ratio: float = 1

@property
def index_field(self) -> 'str':
'''
Expand Down Expand Up @@ -92,8 +96,8 @@ def xy_slice(self) -> slice:
xy_nd_stop: int | None = None

# TODO: eventually incrementally update 1d-pre-graphics path data?
# x_1d: Optional[np.ndarray] = None
# y_1d: Optional[np.ndarray] = None
x_1d: np.ndarray | None = None
y_1d: np.ndarray | None = None

# incremental view-change state(s) tracking
_last_vr: tuple[float, float] | None = None
Expand All @@ -107,32 +111,6 @@ def index_step_size(self) -> float:
'''
return self.viz.index_step()

def __repr__(self) -> str:
msg = (
f'{type(self)}: ->\n\n'
f'fqsn={self.viz.name}\n'
f'shm_name={self.shm.token["shm_name"]}\n\n'

f'last_vr={self._last_vr}\n'
f'last_ivdr={self._last_ivdr}\n\n'

f'xy_slice={self.xy_slice}\n'
# f'xy_nd_stop={self.xy_nd_stop}\n\n'
)

x_nd_len = 0
y_nd_len = 0
if self.x_nd is not None:
x_nd_len = len(self.x_nd)
y_nd_len = len(self.y_nd)

msg += (
f'x_nd_len={x_nd_len}\n'
f'y_nd_len={y_nd_len}\n'
)

return msg

def diff(
self,
new_read: tuple[np.ndarray],
Expand Down Expand Up @@ -180,8 +158,6 @@ def diff(
# set us in a zero-to-append state
nd_stop = self.xy_nd_stop = src_stop

align_index = array[self.index_field]

# 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.
Expand Down Expand Up @@ -334,6 +310,9 @@ def format_to_1d(
array = in_view
profiler(f'{self.viz.name} view range slice {view_range}')

# TODO: we need to check if the last-datum-in-view is true and
# if so only slice to the 2nd last datumonly slice to the 2nd
# last datum.
# hist = array[:slice_to_head]

# XXX: WOA WTF TRACTOR DEBUGGING BUGGG
Expand All @@ -353,6 +332,11 @@ def format_to_1d(
array_key,
view_range,
)
# cache/save last 1d outputs for use by other
# readers (eg. `Viz.draw_last_datum()` in the
# only-draw-last-uppx case).
self.x_1d = x_1d
self.y_1d = y_1d

# app_tres = None
# if append_len:
Expand All @@ -376,11 +360,6 @@ def format_to_1d(
# update the last "in view data range"
if len(x_1d):
self._last_ivdr = x_1d[0], x_1d[-1]
if (
self.index_field == 'time'
and (x_1d[-1] == 0.5).any()
):
breakpoint()

profiler('.format_to_1d()')

Expand Down Expand Up @@ -503,14 +482,22 @@ def format_xy_nd_to_1d(
# NOTE: we don't include the very last datum which is filled in
# normally by another graphics object.
x_1d = array[self.index_field][:-1]
if (
self.index_field == 'time'
and x_1d.any()
and (x_1d[-1] == 0.5).any()
):
breakpoint()

y_1d = array[array_key][:-1]

# name = self.viz.name
# if 'trade_rate' == name:
# s = 4
# x_nd = list(self.x_nd[self.xy_slice][-s:-1])
# y_nd = list(self.y_nd[self.xy_slice][-s:-1])
# print(
# f'{name}:\n'
# f'XY data:\n'
# f'x: {x_nd}\n'
# f'y: {y_nd}\n\n'
# f'x_1d: {list(x_1d[-s:])}\n'
# f'y_1d: {list(y_1d[-s:])}\n\n'

# )
return (
x_1d,
y_1d,
Expand All @@ -532,6 +519,7 @@ class OHLCBarsFmtr(IncrementalFormatter):
fields: list[str] = field(
default_factory=lambda: ['open', 'high', 'low', 'close']
)
flat_index_ratio: float = 4

def allocate_xy_nd(
self,
Expand Down Expand Up @@ -627,7 +615,7 @@ def format_xy_nd_to_1d(

'''
x, y, c = path_arrays_from_ohlc(
array,
array[:-1],
start,
bar_w=self.index_step_size,
bar_gap=w * self.index_step_size,
Expand Down Expand Up @@ -826,13 +814,6 @@ def format_xy_nd_to_1d(
x_1d = x_step_iv.reshape(x_step_iv.size)
y_1d = y_step_iv.reshape(y_step_iv.size)

if (
self.index_field == 'time'
and x_1d.any()
and (x_1d == 0.5).any()
):
breakpoint()

# debugging
# if y_1d.any():
# s = 6
Expand Down
8 changes: 8 additions & 0 deletions piker/data/_m4.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 -> <some epoch float> 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)
Expand Down
64 changes: 42 additions & 22 deletions piker/data/_pathops.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
Super fast ``QPainterPath`` generation related operator routines.

"""
from math import (
ceil,
floor,
)

import numpy as np
from numpy.lib import recfunctions as rfn
from numba import (
Expand Down Expand Up @@ -58,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(
Expand Down Expand Up @@ -285,10 +297,7 @@ def slice_from_time(
stop_t: float,
step: int | None = None,

) -> tuple[
slice,
slice,
]:
) -> slice:
'''
Calculate array indices mapped from a time range and return them in
a slice.
Expand All @@ -308,22 +317,32 @@ def slice_from_time(
)

times = arr['time']
t_first = round(times[0])
t_first = floor(times[0])
t_last = ceil(times[-1])

# the greatest index we can return which slices to the
# end of the input array.
read_i_max = arr.shape[0]

# TODO: require this is always passed in?
if step is None:
step = round(times[-1] - times[-2])
step = round(t_last - times[-2])
if step == 0:
# XXX: HOW TF is this happening?
step = 1

# compute (presumed) uniform-time-step index offsets
i_start_t = round(start_t)
read_i_start = round(((i_start_t - t_first) // step)) - 1
i_start_t = floor(start_t)
read_i_start = floor(((i_start_t - t_first) // step)) - 1

i_stop_t = ceil(stop_t)

i_stop_t = round(stop_t)
read_i_stop = round((i_stop_t - t_first) // step) + 1
# XXX: edge case -> always set stop index to last in array whenever
# the input stop time is detected to be greater then the equiv time
# stamp at that last entry.
if i_stop_t >= t_last:
read_i_stop = read_i_max
else:
read_i_stop = ceil((i_stop_t - t_first) // step) + 1

# always clip outputs to array support
# for read start:
Expand Down Expand Up @@ -367,7 +386,7 @@ def slice_from_time(
# up_to_arith_start = index[:read_i_start]

if (
new_read_i_start < read_i_start
new_read_i_start <= read_i_start
):
# t_diff = t_iv_start - start_t
# print(
Expand All @@ -391,14 +410,15 @@ def slice_from_time(
# )
new_read_i_stop = np.searchsorted(
times[read_i_start:],
# times,
i_stop_t,
side='left',
)

if (
new_read_i_stop < read_i_stop
new_read_i_stop <= read_i_stop
):
read_i_stop = read_i_start + new_read_i_stop
read_i_stop = read_i_start + new_read_i_stop + 1

# sanity checks for range size
# samples = (i_stop_t - i_start_t) // step
Expand Down
Loading