Napari non-integer step size

I’m loading numpy planes from OMERO and opening in napari, which is mostly working fine.
But occasionally I get an unexpected step size and range in one of the dimensions.

For example, I print the numpy 3D array:

print(data.shape)
(50, 128, 128)

but in napari, I get a range of 57.65…

viewer.dims.range
Out[1]: [(0.0, 57.657657657657666, 1.1531531531531534), (0, 128, 1), (0, 128, 1)]

Or, a 4D example:

print(data.shape)
(15, 6, 1024, 1024)

viewer.dims.range
[(0, 15, 1),
 (0.0, 28.985507246376812, 4.830917874396135),
 (0, 1024, 1),
 (0, 1024, 1)]

This only happens in a handful of all the images I’ve tried. Most of the time, the dims.range exactly matches the size of the numpy data and all the step sizes are 1.
Any ideas what could be causing this?
I’m using napari 0.6.2
Thanks,
Will

1 Like

I’m using napari 0.6.2

Pretty cool that you have a time machine! =P

This only happens in a handful of all the images

It’s certainly weird! Does this work when you grab just the numpy array (forgetting all the OMERO stuff)? Are you perhaps setting the scale? The range might include the scale setting.

If you could share a minimal data + code example, it would be very helpful for us to track it down!

… Looking at the numbers more closely, it does look like it’s the scale:

In [1]: 4.830917874396135 * 6                                                                                                 
Out[1]: 28.985507246376812

In [2]: 1.1531531531531534 * 50                                                                                               
Out[2]: 57.657657657657666

Thanks. Yes, I am setting the scale since I wanted the 3D volume to be scaled correctly.

Is there any way in which I can achieve the scaling correctly but still work with integer steps?
(otherwise I guess I can just do the conversion when I’m mapping between Z indexes in OMERO and Z-slider in napari).

Will

Unfortunately, currently the concept of “real space” and “pixel space” coordinates is quite jumbled in napari, and this is one of the things we really want to fix in time for 0.3. So, the answer is, possibly not, and certainly nothing simple and stable. I’d suggest manually keeping track for now.

Here are some related discussions on the repo:



(in particular the first comment from me)
and

We are working on this! :grimacing: I had a nice chat with Stephan Saalfeld recently so I’m a lot more clear on how we need to think about this going forward. :blush:

1 Like

As @jni says this is now a top priority for us and probably best to track those issues. Right now you can get the following info:

    img = np.random.random((50, 128, 128))
    viewer = napari.view_image(img, scale=[1.25, 1, 1])
    print(img.shape) #(50, 128, 128)
    print(viewer.dims.range) #[(0.0, 62.5, 1.25), (0, 128, 1), (0, 128, 1)]
    print(viewer.layers[0].shape) #(62, 128, 128)
    print(viewer.layers[0].data.shape) #(50, 128, 128)

Can you explain in a little more detail what you’d like to access and with what api in the context of my minimal example, or does [(r[0], r[1] // r[2]) for r in viewer.dims.range] provide what you want? We could also consider doing that calculation for you if you want and outputting a convenience variable. We actually do that conversion internally here when slicing - https://github.com/napari/napari/blob/b4eec93934d5791e7e85769924b4e27ddce513a9/napari/components/dims.py#L270

The reason it was done this way was to capture scaling and the “full data size” for reseting the camera / understanding the zoom for axes that can either be displayed or not displayed. As @jni notes though this needs some work

1 Like

Hi and thanks for the background info.
Given my background with OMERO, I was expecting napari to behave in the same way: All the sliders are purely mapped to dimension index. We have metadata to know how Z index and T index are related to actual distance or time, but we always show the slider index beside each slider (with or without the extra metadata).

So, if your img.shape is (50, 128, 128) then the ‘Z’ slider has 50 positions of 0-49 and I would expect to see 0-49 shown in the UI. In your example, the napari viewer seems to tell me that I have 62 Z planes, since I can slide the slider to 62 and there’s nothing to tell me I only have 50. But then I’m very confused when on index e.g. 58 and I click the > and the slider moves but the image doesn’t change.

In your example, if I use scale=[0.25, 1, 1] then I can’t even access all the planes (as I think was mentioned in one of the links above) and the slider <> buttons don’t work.

I’m not familiar with all the use-cases you’re trying to support with pyramids and mapping between multiple images of different scales, but certainly in this simpler examples the current behaviour is confusing. Hope you can find a solution that works for both.
Thanks,
Will

@will-moore thanks thats helpful. Makes sense. I think we’ll move towards that a system like that soon, but maintain the other functionality as well

1 Like