Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d0bbcc7

Browse files
committed
ENH: Add option to allow inferring of intent code based on output file suffixes
1 parent 3d266fc commit d0bbcc7

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

‎nibabel/cifti2/cifti2.py‎

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ class Cifti2HeaderError(Exception):
8888
'CIFTI_STRUCTURE_THALAMUS_LEFT',
8989
'CIFTI_STRUCTURE_THALAMUS_RIGHT')
9090

91+
# "Standard CIFTI Mapping Combinations" within CIFTI-2 spec
92+
# https://www.nitrc.org/forum/attachment.php?attachid=341&group_id=454&forum_id=1955
93+
CIFTI_EXTENSIONS_TO_INTENTS = {
94+
'.dconn': 'NIFTI_INTENT_CONNECTIVITY_DENSE',
95+
'.dtseries': 'NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES',
96+
'.pconn': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED',
97+
'.ptseries': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SERIES',
98+
'.dscalar': 'NIFTI_INTENT_CONNECTIVITY_DENSE_SCALARS',
99+
'.dlabel': 'NIFTI_INTENT_CONNECTIVITY_DENSE_LABELS',
100+
'.pscalar': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SCALAR',
101+
'.pdconn': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED_DENSE',
102+
'.dpconn': 'NIFTI_INTENT_CONNECTIVITY_DENSE_PARCELLATED',
103+
'.pconnseries': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED_PARCELLATED_SERIES',
104+
'.pconnscalar': 'NIFTI_INTENT_CONNECTIVITY_PARCELLATED_PARCELLATED_SCALAR',
105+
'.dfan': 'NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES',
106+
}
107+
91108

92109
def _value_if_klass(val, klass):
93110
if val is None or isinstance(val, klass):
@@ -1459,11 +1476,7 @@ def to_file_map(self, file_map=None):
14591476
raise ValueError(
14601477
f"Dataobj shape {self._dataobj.shape} does not match shape "
14611478
f"expected from CIFTI-2 header {self.header.matrix.get_data_shape()}")
1462-
# if intent code is not set, default to unknown CIFTI
1463-
if header.get_intent()[0] == 'none':
1464-
header.set_intent('NIFTI_INTENT_CONNECTIVITY_UNKNOWN')
1465-
data = reshape_dataobj(self.dataobj,
1466-
(1, 1, 1, 1) + self.dataobj.shape)
1479+
data = reshape_dataobj(self.dataobj, (1, 1, 1, 1) + self.dataobj.shape)
14671480
# If qform not set, reset pixdim values so Nifti2 does not complain
14681481
if header['qform_code'] == 0:
14691482
header['pixdim'][:4] = 1
@@ -1490,6 +1503,33 @@ def get_data_dtype(self):
14901503
def set_data_dtype(self, dtype):
14911504
self._nifti_header.set_data_dtype(dtype)
14921505

1506+
def to_filename(self, filename, infer_intent=False):
1507+
"""
1508+
Ensures NIfTI header intent code is set prior to saving.
1509+
1510+
Parameters
1511+
----------
1512+
infer_intent : boolean, optional
1513+
If ``True``, attempt to infer and set intent code based on filename suffix.
1514+
"""
1515+
header = self._nifti_header
1516+
if infer_intent:
1517+
# try to infer intent code based on filename suffix
1518+
intent = _infer_intent_from_filename(filename)
1519+
if intent is not None:
1520+
header.set_intent(intent)
1521+
# if intent code is not set, default to unknown
1522+
if header.get_intent()[0] == 'none':
1523+
header.set_intent('NIFTI_INTENT_CONNECTIVITY_UNKNOWN')
1524+
super().to_filename(filename)
1525+
1526+
1527+
def _infer_intent_from_filename(filename):
1528+
"""Parses output filename for common suffixes and fetches corresponding intent code"""
1529+
from pathlib import Path
1530+
ext = Path(filename).suffixes[0]
1531+
return CIFTI_EXTENSIONS_TO_INTENTS.get(ext)
1532+
14931533

14941534
load = Cifti2Image.from_filename
14951535
save = Cifti2Image.instance_to_filename

‎nibabel/cifti2/tests/test_new_cifti2.py‎

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,9 @@ def test_dtseries():
237237
hdr = ci.Cifti2Header(matrix)
238238
data = np.random.randn(13, 10)
239239
img = ci.Cifti2Image(data, hdr)
240-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES')
241240

242241
with InTemporaryDirectory():
243-
ci.save(img, 'test.dtseries.nii')
242+
ci.save(img, 'test.dtseries.nii', infer_intent=True)
244243
img2 = nib.load('test.dtseries.nii')
245244
assert img2.nifti_header.get_intent()[0] == 'ConnDenseSeries'
246245
assert isinstance(img2, ci.Cifti2Image)
@@ -281,10 +280,9 @@ def test_dlabel():
281280
hdr = ci.Cifti2Header(matrix)
282281
data = np.random.randn(2, 10)
283282
img = ci.Cifti2Image(data, hdr)
284-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_LABELS')
285283

286284
with InTemporaryDirectory():
287-
ci.save(img, 'test.dlabel.nii')
285+
ci.save(img, 'test.dlabel.nii', infer_intent=True)
288286
img2 = nib.load('test.dlabel.nii')
289287
assert img2.nifti_header.get_intent()[0] == 'ConnDenseLabel'
290288
assert isinstance(img2, ci.Cifti2Image)
@@ -301,10 +299,9 @@ def test_dconn():
301299
hdr = ci.Cifti2Header(matrix)
302300
data = np.random.randn(10, 10)
303301
img = ci.Cifti2Image(data, hdr)
304-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE')
305302

306303
with InTemporaryDirectory():
307-
ci.save(img, 'test.dconn.nii')
304+
ci.save(img, 'test.dconn.nii', infer_intent=True)
308305
img2 = nib.load('test.dconn.nii')
309306
assert img2.nifti_header.get_intent()[0] == 'ConnDense'
310307
assert isinstance(img2, ci.Cifti2Image)
@@ -323,10 +320,9 @@ def test_ptseries():
323320
hdr = ci.Cifti2Header(matrix)
324321
data = np.random.randn(13, 4)
325322
img = ci.Cifti2Image(data, hdr)
326-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SERIES')
327323

328324
with InTemporaryDirectory():
329-
ci.save(img, 'test.ptseries.nii')
325+
ci.save(img, 'test.ptseries.nii', infer_intent=True)
330326
img2 = nib.load('test.ptseries.nii')
331327
assert img2.nifti_header.get_intent()[0] == 'ConnParcelSries'
332328
assert isinstance(img2, ci.Cifti2Image)
@@ -345,10 +341,9 @@ def test_pscalar():
345341
hdr = ci.Cifti2Header(matrix)
346342
data = np.random.randn(2, 4)
347343
img = ci.Cifti2Image(data, hdr)
348-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SCALAR')
349344

350345
with InTemporaryDirectory():
351-
ci.save(img, 'test.pscalar.nii')
346+
ci.save(img, 'test.pscalar.nii', infer_intent=True)
352347
img2 = nib.load('test.pscalar.nii')
353348
assert img2.nifti_header.get_intent()[0] == 'ConnParcelScalr'
354349
assert isinstance(img2, ci.Cifti2Image)
@@ -367,10 +362,9 @@ def test_pdconn():
367362
hdr = ci.Cifti2Header(matrix)
368363
data = np.random.randn(10, 4)
369364
img = ci.Cifti2Image(data, hdr)
370-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_DENSE')
371365

372366
with InTemporaryDirectory():
373-
ci.save(img, 'test.pdconn.nii')
367+
ci.save(img, 'test.pdconn.nii', infer_intent=True)
374368
img2 = ci.load('test.pdconn.nii')
375369
assert img2.nifti_header.get_intent()[0] == 'ConnParcelDense'
376370
assert isinstance(img2, ci.Cifti2Image)
@@ -389,10 +383,9 @@ def test_dpconn():
389383
hdr = ci.Cifti2Header(matrix)
390384
data = np.random.randn(4, 10)
391385
img = ci.Cifti2Image(data, hdr)
392-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_PARCELLATED')
393386

394387
with InTemporaryDirectory():
395-
ci.save(img, 'test.dpconn.nii')
388+
ci.save(img, 'test.dpconn.nii', infer_intent=True)
396389
img2 = ci.load('test.dpconn.nii')
397390
assert img2.nifti_header.get_intent()[0] == 'ConnDenseParcel'
398391
assert isinstance(img2, ci.Cifti2Image)
@@ -430,10 +423,9 @@ def test_pconn():
430423
hdr = ci.Cifti2Header(matrix)
431424
data = np.random.randn(4, 4)
432425
img = ci.Cifti2Image(data, hdr)
433-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED')
434426

435427
with InTemporaryDirectory():
436-
ci.save(img, 'test.pconn.nii')
428+
ci.save(img, 'test.pconn.nii', infer_intent=True)
437429
img2 = ci.load('test.pconn.nii')
438430
assert img.nifti_header.get_intent()[0] == 'ConnParcels'
439431
assert isinstance(img2, ci.Cifti2Image)
@@ -453,11 +445,9 @@ def test_pconnseries():
453445
hdr = ci.Cifti2Header(matrix)
454446
data = np.random.randn(4, 4, 13)
455447
img = ci.Cifti2Image(data, hdr)
456-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_'
457-
'PARCELLATED_SERIES')
458448

459449
with InTemporaryDirectory():
460-
ci.save(img, 'test.pconnseries.nii')
450+
ci.save(img, 'test.pconnseries.nii', infer_intent=True)
461451
img2 = ci.load('test.pconnseries.nii')
462452
assert img.nifti_header.get_intent()[0] == 'ConnPPSr'
463453
assert isinstance(img2, ci.Cifti2Image)
@@ -478,11 +468,9 @@ def test_pconnscalar():
478468
hdr = ci.Cifti2Header(matrix)
479469
data = np.random.randn(4, 4, 2)
480470
img = ci.Cifti2Image(data, hdr)
481-
img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_'
482-
'PARCELLATED_SCALAR')
483471

484472
with InTemporaryDirectory():
485-
ci.save(img, 'test.pconnscalar.nii')
473+
ci.save(img, 'test.pconnscalar.nii', infer_intent=True)
486474
img2 = ci.load('test.pconnscalar.nii')
487475
assert img.nifti_header.get_intent()[0] == 'ConnPPSc'
488476
assert isinstance(img2, ci.Cifti2Image)
@@ -517,7 +505,7 @@ def test_wrong_shape():
517505
ci.Cifti2Image(data, hdr)
518506
with suppress_warnings():
519507
img = ci.Cifti2Image(data, hdr)
520-
508+
521509
with pytest.raises(ValueError):
522510
img.to_file_map()
523511

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /