Skip to content

Position can be defaulted to out of bounds location on setting a state with no position #885

@seankmartin

Description

@seankmartin

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:
Image

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:

Image

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

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions