Skip to content

BUG?: MGHHeader.set_zooms() does not persist on I/O roundtrip or affect affine #619

Closed
@larsoner

Description

@larsoner

I am trying to set the affine transform in order to scale an MRI along three dimensions (on latest master). I decided to try to do this by setting the zooms, but the scaling does not seem to persist on I/O round-trip, at least based on how I'm checking.

Reproducing code:

import os
import numpy as np
import nibabel

fname = os.path.join(os.getenv('FREESURFER_HOME'), 'subjects', 'fsaverage', 'mri', 'T1.mgz')

img_mgz = nibabel.load(fname)
nibabel.save(img_mgz, 'test.nii')
img_nii = nibabel.load('test.nii')
zooms = (0.5, 0.5, 0.5)
affine_zoomed = img_mgz.header.get_affine().copy()
affine_zoomed[:3] *= 0.5  # this is what I expect to persist
img_mgz.header.set_zooms(zooms)
img_nii.header.set_zooms(zooms)
# good (3)
assert np.allclose(img_mgz.header.get_zooms(), zooms, atol=1e-5)
assert np.allclose(img_nii.header.get_zooms(), zooms, atol=1e-5)
assert np.allclose(img_mgz.header.get_affine(), affine_zoomed, atol=1e-5)
# bad (1)
assert not np.allclose(img_nii.header.get_best_affine(), affine_zoomed, atol=1e-5)

#
# Do some I/O
#

nibabel.save(img_nii, 'test_nii.nii')
nibabel.save(img_mgz, 'test_mgz.nii')
nibabel.save(img_nii, 'test_nii.mgz')
nibabel.save(img_mgz, 'test_mgz.mgz')

# good (1)
assert np.allclose(nibabel.load('test_nii.nii').header.get_zooms(), zooms, atol=1e-5)
# bad (5)
assert not np.allclose(nibabel.load('test_mgz.nii').header.get_zooms(), zooms, atol=1e-5)
assert not np.allclose(nibabel.load('test_nii.mgz').header.get_zooms(), zooms, atol=1e-5)
assert not np.allclose(nibabel.load('test_mgz.mgz').header.get_zooms(), zooms, atol=1e-5)
# changed due to I/O steps!
assert not np.allclose(img_mgz.header.get_affine(), affine_zoomed, atol=1e-5)
assert not np.allclose(img_mgz.header.get_zooms(), zooms, atol=1e-5)

It looks like with this code 1) there are consistency problems, and 2) problems with img_mgz.header.get_zooms() being affected / reset by the call(s) to nibabel.save.

Is there a different way I should rescale the MRI? Am I doing something silly here?

Metadata

Metadata

Assignees

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