Skip to content

Commit 6547fbe

Browse files
committed
Merge remote-tracking branch 'upstream/maint/3.1.x'
2 parents 559d4e0 + 6f5f766 commit 6547fbe

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

nibabel/cifti2/cifti2.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -1473,16 +1473,28 @@ def to_file_map(self, file_map=None):
14731473
def update_headers(self):
14741474
""" Harmonize NIfTI headers with image data
14751475
1476+
Ensures that the NIfTI-2 header records the data shape in the last three
1477+
``dim`` fields. Per the spec:
1478+
1479+
Because the first four dimensions in NIfTI are reserved for space and time, the CIFTI
1480+
dimensions are stored in the NIfTI header in dim[5] and up, where dim[5] is the length
1481+
of the first CIFTI dimension (number of values in a row), dim[6] is the length of the
1482+
second CIFTI dimension, and dim[7] is the length of the third CIFTI dimension, if
1483+
applicable. The fields dim[1] through dim[4] will be 1; dim[0] will be 6 or 7,
1484+
depending on whether a third matrix dimension exists.
1485+
14761486
>>> import numpy as np
14771487
>>> data = np.zeros((2,3,4))
14781488
>>> img = Cifti2Image(data)
14791489
>>> img.shape == (2, 3, 4)
14801490
True
14811491
>>> img.update_headers()
1482-
>>> img.nifti_header.get_data_shape() == (2, 3, 4)
1492+
>>> img.nifti_header.get_data_shape() == (1, 1, 1, 1, 2, 3, 4)
1493+
True
1494+
>>> img.shape == (2, 3, 4)
14831495
True
14841496
"""
1485-
self._nifti_header.set_data_shape(self._dataobj.shape)
1497+
self._nifti_header.set_data_shape((1, 1, 1, 1) + self._dataobj.shape)
14861498

14871499
def get_data_dtype(self):
14881500
return self._nifti_header.get_data_dtype()

nibabel/parrec.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,8 @@ def as_analyze_map(self):
772772
f"{self.general_info['protocol_name']}"
773773
)[:80] # max len
774774
is_fmri = (self.general_info['max_dynamics'] > 1)
775-
t = 'msec' if is_fmri else 'unknown'
775+
# PAR/REC uses msec, but in _calc_zooms we convert to sec
776+
t = 'sec' if is_fmri else 'unknown'
776777
xyzt_units = unit_codes['mm'] + unit_codes[t]
777778
return dict(descr=descr, xyzt_units=xyzt_units) # , pixdim=pixdim)
778779

nibabel/tests/test_parrec.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from numpy import array as npa
1010

1111
from .. import load as top_load
12-
from ..nifti1 import Nifti1Image, Nifti1Extension
12+
from ..nifti1 import Nifti1Image, Nifti1Extension, Nifti1Header
1313
from .. import parrec
1414
from ..parrec import (parse_PAR_header, PARRECHeader, PARRECError, vol_numbers,
1515
vol_is_full, PARRECImage, PARRECArrayProxy, exts2pars)
@@ -549,6 +549,18 @@ def test_epi_params():
549549
assert_almost_equal(epi_hdr.get_zooms()[-1], 2.0)
550550

551551

552+
def test_xyzt_unit_conversion():
553+
# Check conversion to NIfTI-like has sensible units
554+
for par_root in ('T2_-interleaved', 'T2_', 'phantom_EPI_asc_CLEAR_2_1'):
555+
epi_par = pjoin(DATA_PATH, par_root + '.PAR')
556+
with open(epi_par, 'rt') as fobj:
557+
epi_hdr = PARRECHeader.from_fileobj(fobj)
558+
nifti_hdr = Nifti1Header.from_header(epi_hdr)
559+
assert len(nifti_hdr.get_data_shape()) == 4
560+
assert_almost_equal(nifti_hdr.get_zooms()[-1], 2.0)
561+
assert nifti_hdr.get_xyzt_units() == ('mm', 'sec')
562+
563+
552564
def test_truncations():
553565
# Test tests for truncation
554566
par = pjoin(DATA_PATH, 'T2_.PAR')

0 commit comments

Comments
 (0)