Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Half-voxel shift with Nifti files #730

Open
balbasty opened this issue Feb 13, 2025 · 2 comments
Open

Half-voxel shift with Nifti files #730

balbasty opened this issue Feb 13, 2025 · 2 comments

Comments

@balbasty
Copy link

Hi

I think that neuroglancer incorrectly induces a half voxel shift when loading nifti files.

The nifti format specifies that "The (x,y,z) coordinates refer to the CENTER of a voxel".
Neuroglancer assumes that they refer to the corner of a voxel and does not insert the appropriate half voxel shift to compensate for it.
(In contrast, it does insert a half voxel shift for OME-Zarrs: https://github.com/google/neuroglancer/blob/master/src/datasource/zarr/ome.ts#L244).

As a side note, it also differs from the spec in that it always uses the qform rather than selecting the most appropriate affine based on intent codes.

And finally, it's not in-spec, but most viewers assume that the spatial unit is "mm" when it is set to "unknown", whereas it seems that neuroglancer falls back to "meter" (?)

Thanks you for the great work with neuroglancer!

Yael

@jbms
Copy link
Collaborator

jbms commented Feb 13, 2025

At the time nifti support was first added, neuroglancer didn't support integer coordinates corresponding to the center rather than corner, but indeed it now does.

It will be a bit tricky to change that now in a way that doesn't break existing neuroglancer links, but it can probably be done.

The same goes for changing "unknown" to mean "mm", and changing the transform --- will have to be done carefully to avoid breaking existing links.

As far as the transform, can you describe what you would like to have happen?

@balbasty
Copy link
Author

For the choice of transform, I think that nifti-reader-js already implements the correct logic, which is to use the method with highest code, and trust the sform over the qform in case of a tie. This is also how nibabel selects the correct affine.

But I agree this is the trickiest change, as it will very likely break existing links. I think I'd be ok with keeping the existing behaviour (always use the qform), as long as it's properly documented.

What I am doing currently is build the correct transform myself and set it in the state, but it's a bit convoluted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants