-
Notifications
You must be signed in to change notification settings - Fork 356
Position can be defaulted to out of bounds location on setting a state with no position #885
Description
Summary
If a state has global dimensions ordered differently to the input dimensions for a datasource in a layer and that state also has no position in it, then if that state is applied to a viewer containing a non-empty state, the position inferred by the viewer is incorrect.
Visual output of issue
In images you would get the following. On first applying the state from a blank viewer. This is correct inference of position as midpoint of volume bounds:

On applying the exact same state again from the viewer that now has state itself (you can do this from the JSON state editor or console). This is inferring the midpoint as if the dimensions were order x, y, z - not the real ordering of z, x, y that is in the state. As such the position is out of bounds:
Reproducing
To reproduce, launch neuroglancer and in the console:
// Can be any state with dimensions set but positions not set
// dimensions need to be set to an ordering that is not the
// default ordering for this data source (as that is where the issue arises)
// as such, you also need bounds of different sizes
state = {
"dimensions": {
"z": [
4e-8,
"m"
],
"x": [
4e-9,
"m"
],
"y": [
4e-9,
"m"
]
},
"layers": [
{
"type": "image",
"source": "precomputed://gs://neuroglancer-fafb-data/fafb_v14/fafb_v14_orig",
"tab": "source",
"name": "fafb_v14"
}
]
}
// This should load fine
viewer.state.restoreState(state)
// Mimic the call that happens from the JSON state editor on hitting apply
viewer.state.reset(); viewer.state.restoreState(state);
// If you reset the state, wait a bit, and then set the state it should be fine again
viewer.state.reset();
// Manually wait until the state is reset
viewer.state.restoreState(state);
// We can simulate this wait with a timeout, though uncertain exactly what length of wait is needed
// would be safer with a callback/signal or fixing the issue directly on restoreState
viewer.state.reset(); setTimeout(() => viewer.state.restoreState(state), 100);Possible ideas
- If the aim is to fix this at the state editor level, the state editor has access to the viewer so it could respond to a signal/event when the reset of the state is complete. The problem is, unsure exactly what indicates that reset having been successfully performed. Perhaps this signal could be more broadly useful though.
- Fixing the restoreState. I haven't dug into exactly what is happening, but it seems like perhaps some kind of race condition. We might be able to check the inferred position against the volume bounds information and fix the position setting.