You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Not jerkyness when zoomed out, and it's only with the heatmap.
Neither padding nor sampling onto a consistent x-grid chosen a-priori fixes this. Suspect it might be something to do with being very zoomed in in world space.
def_compute_delta_x_avg(self) ->float|None:
""" Estimate a stable x step by sampling local spacing at the 20%, 40%, 60%, and 80% positions of the p reference range (5 consecutive data points each). Returns the mean step if the four estimates agree within 10%, otherwise warns and returns None so _create_heatmap_data falls back to a per-window x step. """p_dim=self.processor.spatial_dims[1]
p_range=self._ref_index.ref_ranges[p_dim]
p_map=self.processor.slider_dim_transforms[p_dim]
p_span=p_range.stop-p_range.startp_mid=p_range.start+p_span/2i_mid=p_map(p_mid)
i_mid_inc=p_map(p_mid+p_range.step)
delta_p=p_range.step/max(1, i_mid_inc-i_mid)
# probe window that yields ~5 consecutive data pointsprobe_window=5*delta_porig_dw=self.processor.display_windowself.processor.display_window=probe_windowbase_indices= {d: self._ref_index[d] fordinself.processor.slider_dims}
local_steps=list()
forfracin (0.2, 0.4, 0.6, 0.8):
ref_val=p_range.start+frac*p_spanindices= {**base_indices, p_dim: ref_val}
x= (run_sync(self.processor.get(indices)))["data"][0, :, 0]
ifx.size>=2:
local_steps.append((x[-1] -x[0]) / (x.size-1))
self.processor.display_window=orig_dwiflen(local_steps) <2:
returnNonesteps=np.array(local_steps, dtype=np.float64)
mean_step=float(steps.mean())
spread=float((steps.max() -steps.min()) /mean_step)
ifspread>0.10:
warn(
f"Heatmap x step varies by {spread:.1%} across the recording "f"({steps.min():.4g} to {steps.max():.4g}). "f"Using per-window x step; heatmap may jitter."
)
returnNonereturnmean_stepdef_create_heatmap_data(self, data_slice) ->tuple[np.ndarray, float, float]:
"""return padded [n_rows, cap] heatmap, world-space x offset, and x step (sample period)"""# data slice is of shape [n_timeseries, n_timepoints, xy]x=data_slice[0, :, 0]
ifself._delta_x_avgisnotNone:
print("using x avg")
x_step=self._delta_x_avgp_dim=self.processor.spatial_dims[1]
center=self._ref_index[p_dim]
dw=self.processor.display_windown_cols=max(2, round(dw/x_step))
x_canonical_start=center-dw/2x_canonical=x_canonical_start+np.arange(n_cols) *x_stepy_interp=np.empty((data_slice.shape[0], n_cols), dtype=np.float32)
foriinrange(data_slice.shape[0]):
y_interp[i] =np.interp(x_canonical, x, data_slice[i, :, 1], left=np.nan, right=np.nan)
x0=x_canonical_startelse:
# check if we need to interpolatenorm=np.linalg.norm(np.diff(np.diff(x))) /x.sizeifnorm>1e-6:
# x is not uniform up to float32 precision, must interpolatex_uniform=np.linspace(x[0], x[-1], num=x.size)
y_interp=np.empty(shape=data_slice[..., 1].shape, dtype=np.float32)
# this for loop is actually slightly faster than numpy.apply_along_axis()foriinrange(data_slice.shape[0]):
y_interp[i] =np.interp(x_uniform, x, data_slice[i, :, 1])
else:
# x is sufficiently uniformy_interp=data_slice[..., 1]
n_cols=y_interp.shape[1]
x0=x[0]
# true sample period: n_cols-1 intervals between n_cols valuesx_step= (x[-1] -x0) / (n_cols-1)
# pad with NaN columns on each side so frame-to-frame fluctuations in n_cols don't# trigger an ImageGraphic texture rebuild. reuse existing capacity if it still fits,# rebuild only when too small or > 10% too big. the max() in `upper` guards the small-n# case where ceil(1.10 * n_cols) falls below `target` and would force a rebuild on the# frame right after allocating.pad=max(1, int(np.ceil(0.03*n_cols)))
target=n_cols+2*padupper=max(int(np.ceil(1.10*n_cols)), target)
existing=self._graphic.data.shape[1] ifself._graphicisnotNoneelse0ifn_cols<=existing<=upper:
cap=existingpad_left= (cap-n_cols) //2else:
cap=targetpad_left=padimage_data=np.full((y_interp.shape[0], cap), np.nan, dtype=np.float32)
image_data[:, pad_left:pad_left+n_cols] =y_interp# shift offset by pad_left columns so data column at index pad_left lands at world-x = x0returnimage_data, x0- (pad_left*x_step), x_step
getting this when zoomed in on the ephys viz
jerky-ephys-1.mp4
jerky-ephys-3.mp4
Not jerkyness when zoomed out, and it's only with the heatmap.
Neither padding nor sampling onto a consistent x-grid chosen a-priori fixes this. Suspect it might be something to do with being very zoomed in in world space.