8000 ENH: Add get/set_zooms(units='norm') to manipulate zooms in mm/s units by effigies · Pull Request #567 · nipy/nibabel · GitHub
[go: up one dir, main page]

Skip to content

ENH: Add get/set_zooms(units='norm') to manipulate zooms in mm/s units #567

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

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
8000
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3f3b450
ENH: Add get_norm_zooms for zooms in mm/s units
effigies Oct 24, 2017
d26acfb
ENH: Add get_norm_zooms for MGHHeader
effigies Dec 18, 2017
de9323c
ENH: Add set_norm_zooms
effigies Dec 21, 2017
5c30366
FIX: Various unit issues
effigies Dec 21, 2017
4b86d3e
TEST: Test get/set_norm_zooms
effigies Dec 21, 2017
eb1d8ff
TEST: Fix warnings
effigies Dec 21, 2017
6ba8b66
RF: get_norm_zooms -> get_zooms(units="canonical")
effigies Jan 12, 2018
1357a3b
TEST: Update get_zooms tests
effigies Jan 13, 2018
096da88
FIX: Set default t_code even if no t_zoom
effigies Jan 13, 2018
798fc4e
TEST: Add units specification to tests
effigies Feb 19, 2018
f31aba5
TEST: Add setup/teardown to try to catch warnings properly [WIP]
effigies Feb 19, 2018
27234c3
TEST: Try using clear_and_catch_warnings
effigies Feb 19, 2018
8899bc7
RF: Add units parameter to set_zooms
effigies Mar 12, 2018
da54665
TEST: More complete zoom testing, revert unnecessary change
effigies Mar 12, 2018
1620f31
TEST: Improve warning filters, check set_zooms behavior more thoroughly
effigies Mar 12, 2018
5d96f5c
TEST: Explicitly test non-temporal t_units during set_zooms(units="no…
effigies Mar 12, 2018
233f7f0
TEST: Filter warnings for unmodified superclass tests only
effigies Mar 12, 2018
4babf08
ENH: Add units/raise_unknown to MINC/ECAT get_zooms
effigies Mar 12, 2018
6cd83f7
ENH: Validate units parameter in all get/set_zooms
effigies Mar 13, 2018
94cbd0d
FIX: Correct and simplify NIFTI logic
effigies Mar 14, 2018
cfc5abe
TEST: Clear nifti1 module warnings
effigies Mar 20, 2018
3562921
TEST: Check edge cases
effigies Mar 20, 2018
d9199ca
TEST: Add unit to bad set_zoom call
effigies Mar 20, 2018
98e43a0
TEST: Check get_zooms units arg in MINC/ECAT
effigies Mar 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TEST: Add units specification to tests
  • Loading branch information
effigies committed Dec 26, 2022
commit 798fc4e655c4740c31660ccda6e0737a17e8f35c
2 changes: 1 addition & 1 deletion nibabel/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def from_header(klass, header=None, check=True):
f"but output header {klass} does not support it")
obj.set_data_dtype(header.get_data_dtype())
obj.set_data_shape(header.get_data_shape())
obj.set_zooms(header.get_zooms())
obj.set_zooms(header.get_zooms(units='raw'))
if check:
obj.check_fix()
return obj
Expand Down
2 changes: 1 addition & 1 deletion nibabel/nifti1.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ def get_data_shape(self):

Expanding number of dimensions gets default zooms

>>> hdr.get_zooms()
>>> hdr.get_zooms(units='canonical')
(1.0, 1.0, 1.0)

Notes
Expand Down
22 changes: 14 additions & 8 deletions nibabel/tests/test_analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ def test_general_init(self):
assert_array_equal(np.diag(hdr.get_base_affine()),
[-1, 1, 1, 1])
# But zooms only go with number of dimensions
assert hdr.get_zooms() == (1.0,)
assert hdr.get_zooms(units='raw') == (1.0,)
assert hdr.get_zooms(units='canonical') == (1.0,)

def test_header_size(self):
assert self.header_class.template_dtype.itemsize == self.sizeof_hdr
Expand Down Expand Up @@ -437,7 +438,8 @@ def test_data_shape_zooms_affine(self):
else:
assert hdr.get_data_shape() == (0,)
# Default zoom - for 3D - is 1(())
assert hdr.get_zooms() == (1,) * L
assert hdr.get_zooms(units='raw') == (1,) * L
assert hdr.get_zooms(units='canonical') == (1,) * L
# errors if zooms do not match shape
if len(shape):
with pytest.raises(HeaderDataError):
Expand All @@ -455,11 +457,14 @@ def test_data_shape_zooms_affine(self):
hdr = self.header_class()
hdr.set_data_shape((1, 2, 3))
hdr.set_zooms((4, 5, 6))
assert_array_equal(hdr.get_zooms(), (4, 5, 6))
assert_array_equal(hdr.get_zooms(units='raw'), (4, 5, 6))
assert_array_equal(hdr.get_zooms(units='canonical'), (4, 5, 6))
hdr.set_data_shape((1, 2))
assert_array_equal(hdr.get_zooms(), (4, 5))
assert_array_equal(hdr.get_zooms(units='raw'), (4, 5))
assert_array_equal(hdr.get_zooms(units='canonical'), (4, 5))
hdr.set_data_shape((1, 2, 3))
assert_array_equal(hdr.get_zooms(), (4, 5, 1))
assert_array_equal(hdr.get_zooms(units='raw'), (4, 5, 1))
assert_array_equal(hdr.get_zooms(units='canonical'), (4, 5, 1))
# Setting zooms changes affine
assert_array_equal(np.diag(hdr.get_base_affine()),
[-4, 5, 1, 1])
Expand D 8000 own Expand Up @@ -529,12 +534,13 @@ def get_data_dtype(self): return np.dtype('i2')

def get_data_shape(self): return (5, 4, 3)

def get_zooms(self): return (10.0, 9.0, 8.0)
def get_zooms(self, units=None, raise_unknown=None): return (10.0, 9.0, 8.0)
converted = klass.from_header(C())
assert isinstance(converted, klass)
assert converted.get_data_dtype() == np.dtype('i2')
assert converted.get_data_shape() == (5, 4, 3)
assert converted.get_zooms() == (10.0, 9.0, 8.0)
assert converted.get_zooms(units='raw') == (10.0, 9.0, 8.0)
assert converted.get_zooms(units='canonical') == (10.0, 9.0, 8.0)

def test_base_affine(self):
klass = self.header_class
Expand Down Expand Up @@ -640,7 +646,7 @@ def get_data_shape(self):

class H4(H3):

def get_zooms(self):
def get_zooms(self, units=None, raise_unknown=None):
return 4., 5., 6.
exp_hdr = klass()
exp_hdr.set_data_dtype(np.dtype('u1'))
Expand Down
22 changes: 11 additions & 11 deletions nibabel/tests/test_nifti1.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,11 +881,11 @@ def test_set_qform(self):
img.set_qform(new_affine, 1, update_affine=False)
assert_array_almost_equal(img.affine, aff_affine)
# Clear qform using None, zooms unchanged
assert_array_almost_equal(hdr.get_zooms(), [1.1, 1.1, 1.1])
assert_array_almost_equal(hdr.get_zooms(units='raw'), [1.1, 1.1, 1.1])
img.set_qform(None)
qaff, code = img.get_qform(coded=True)
assert (qaff, code) == (None, 0)
assert_array_almost_equal(hdr.get_zooms(), [1.1, 1.1, 1.1])
assert_array_almost_equal(hdr.get_zooms(units='raw'), [1.1, 1.1, 1.1])
# Best affine similarly
assert_array_almost_equal(img.affine, hdr.get_best_affine())
# If sform is not set, qform should update affine
Expand Down Expand Up @@ -942,9 +942,9 @@ def test_set_sform(self):
assert_array_almost_equal(img.affine, aff_affine)
# zooms do not get updated when qform is 0
assert_array_almost_equal(img.get_qform(), orig_aff)
assert_array_almost_equal(hdr.get_zooms(), [2.2, 3.3, 4.3])
assert_array_almost_equal(hdr.get_zooms(units='raw'), [2.2, 3.3, 4.3])
img.set_qform(None)
assert_array_almost_equal(hdr.get_zooms(), [2.2, 3.3, 4.3])
assert_array_almost_equal(hdr.get_zooms(units='raw'), [2.2, 3.3, 4.3])
# Set sform using new_affine when qform is set
img.set_qform(qform_affine, 1)
img.set_sform(new_affine, 1)
Expand All @@ -953,7 +953,7 @@ def test_set_sform(self):
assert_array_almost_equal(saff, new_affine)
assert_array_almost_equal(img.affine, new_affine)
# zooms follow qform
assert_array_almost_equal(hdr.get_zooms(), [1.2, 1.2, 1.2])
assert_array_almost_equal(hdr.get_zooms(units='raw'), [1.2, 1.2, 1.2])
# Clear sform using None, best_affine should fall back on qform
img.set_sform(None)
assert hdr['sform_code'] == 0
Expand Down Expand Up @@ -1042,15 +1042,15 @@ def test_load_pixdims(self):
# Check qform, sform, pixdims are the same
assert_array_equal(img_hdr.get_qform(), qaff)
assert_array_equal(img_hdr.get_sform(), saff)
assert_array_equal(img_hdr.get_zooms(), [2, 3, 4])
assert_array_equal(img_hdr.get_zooms(units='raw'), [2, 3, 4])
# Save to stringio
re_simg = bytesio_round_trip(simg)
assert_array_equal(re_simg.get_fdata(), arr)
# Check qform, sform, pixdims are the same
rimg_hdr = re_simg.header
assert_array_equal(rimg_hdr.get_qform(), qaff)
assert_array_equal(rimg_hdr.get_sform(), saff)
assert_array_equal(rimg_hdr.get_zooms(), [2, 3, 4])
assert_array_equal(rimg_hdr.get_zooms(units='raw'), [2, 3, 4])

def test_affines_init(self):
# Test we are doing vaguely spec-related qform things. The 'spec' here
Expand All @@ -1064,20 +1064,20 @@ def test_affines_init(self):
hdr = img.header
assert hdr['qform_code'] == 0
assert hdr['sform_code'] == 2
assert_array_equal(hdr.get_zooms(), [2, 3, 4])
assert_array_equal(hdr.get_zooms(units='raw'), [2, 3, 4])
# This is also true for affines with header passed
qaff = np.diag([3, 4, 5, 1])
saff = np.diag([6, 7, 8, 1])
hdr.set_qform(qaff, code='scanner')
hdr.set_sform(saff, code='talairach')
assert_array_equal(hdr.get_zooms(), [3, 4, 5])
assert_array_equal(hdr.get_zooms(units='raw'), [3, 4, 5])
img = IC(arr, aff, hdr)
new_hdr = img.header
# Again affine is sort of anonymous space
assert new_hdr['qform_code'] == 0
assert new_hdr['sform_code'] == 2
assert_array_equal(new_hdr.get_sform(), aff)
assert_array_equal(new_hdr.get_zooms(), [2, 3, 4])
assert_array_equal(new_hdr.get_zooms(units='raw'), [2, 3, 4])
# But if no affine passed, codes and matrices stay the same
img = IC(arr, None, hdr)
new_hdr = img.header
Expand All @@ -1086,7 +1086,7 @@ def test_affines_init(self):
assert new_hdr['sform_code'] == 3 # Still talairach
assert_array_equal(new_hdr.get_sform(), saff)
# Pixdims as in the original header
assert_array_equal(new_hdr.get_zooms(), [3, 4, 5])
assert_array_equal(new_hdr.get_zooms(units='raw'), [3, 4, 5])

def test_read_no_extensions(self):
IC = self.image_class
Expand Down
0