Make `Viz.slice_from_time()` take input array

Probably means it doesn't need to be a `Flume` method but it's
convenient to expect the caller to pass in the `np.ndarray` with
a `'time'` field instead of a `timeframe: str` arg; also, return the
slice mask instead of the sliced array as output (again allowing the
caller to do any slicing). Also, handle the slice-outside-time-range
case by just returning the entire index range with a `None` mask.

Adjust `Viz.view_data()` to instead do timeframe (for rt vs. hist shm
array) lookup and equiv array slicing with the returned mask.
multichartz
Tyler Goodlet 2022-11-28 10:09:45 -05:00
parent ee57f5c09f
commit b72658e243
1 changed files with 64 additions and 24 deletions

View File

@ -236,29 +236,43 @@ class Flume(Struct):
def slice_from_time( def slice_from_time(
self, self,
array: np.ndarray, arr: np.ndarray,
start_t: float, start_t: float,
stop_t: float, stop_t: float,
timeframe_s: int = 1,
return_data: bool = False,
) -> np.ndarray: ) -> tuple[
slice,
slice,
np.ndarray | None,
]:
''' '''
Slice an input struct array providing only datums Slice an input struct array to a time range and return the absolute
"in view" of this chart. and "readable" slices for that array as well as the indexing mask
for the caller to use to slice the input array if needed.
''' '''
arr = {
1: self.rt_shm.array,
60: self.hist_shm.arry,
}[timeframe_s]
times = arr['time'] times = arr['time']
index = array['index'] index = arr['index']
if (
start_t < 0
or start_t >= stop_t
):
return (
slice(
index[0],
index[-1],
),
slice(
0,
len(arr),
),
None,
)
# use advanced indexing to map the # use advanced indexing to map the
# time range to the index range. # time range to the index range.
mask = ( mask: np.ndarray = (
(times >= start_t) (times >= start_t)
& &
(times < stop_t) (times < stop_t)
@ -273,7 +287,24 @@ class Flume(Struct):
# ] # ]
i_by_t = index[mask] i_by_t = index[mask]
try:
i_0 = i_by_t[0] i_0 = i_by_t[0]
except IndexError:
if (
start_t < times[0]
or stop_t >= times[-1]
):
return (
slice(
index[0],
index[-1],
),
slice(
0,
len(arr),
),
None,
)
abs_slc = slice( abs_slc = slice(
i_0, i_0,
@ -285,17 +316,12 @@ class Flume(Struct):
0, 0,
i_by_t[-1] - i_0, i_by_t[-1] - i_0,
) )
if not return_data:
return (
abs_slc,
read_slc,
)
# also return the readable data from the timerange # also return the readable data from the timerange
return ( return (
abs_slc, abs_slc,
read_slc, read_slc,
arr[mask], mask,
) )
def view_data( def view_data(
@ -304,18 +330,32 @@ class Flume(Struct):
timeframe_s: int = 1, timeframe_s: int = 1,
) -> np.ndarray: ) -> np.ndarray:
'''
Return sliced-to-view source data along with absolute
(``ShmArray._array['index']``) and read-relative
(``ShmArray.array``) slices.
'''
# get far-side x-indices plot view # get far-side x-indices plot view
vr = plot.viewRect() vr = plot.viewRect()
if timeframe_s > 1:
arr = self.hist_shm.array
else:
arr = self.rt_shm.array
( (
abs_slc, abs_slc,
buf_slc, read_slc,
iv_arr, mask,
) = self.slice_from_time( ) = self.slice_from_time(
arr,
start_t=vr.left(), start_t=vr.left(),
stop_t=vr.right(), stop_t=vr.right(),
timeframe_s=timeframe_s, timeframe_s=timeframe_s,
return_data=True,
) )
return iv_arr return (
abs_slc,
read_slc,
arr[mask] if mask is not None else arr,
)