13
13
from __future__ import division , print_function
14
14
import warnings
15
15
from io import BytesIO
16
+ from six import string_types
16
17
17
18
import numpy as np
18
19
import numpy .linalg as npl
232
233
(2003 , 'rgb vector' , (), "NIFTI_INTENT_RGB_VECTOR" ),
233
234
(2004 , 'rgba vector' , (), "NIFTI_INTENT_RGBA_VECTOR" ),
234
235
(2005 , 'shape' , (), "NIFTI_INTENT_SHAPE" ),
236
+ # FSL-specific intent codes - codes used by FNIRT
237
+ # ($FSLDIR/warpfns/fnirt_file_reader.h:104)
238
+ (2006 , 'fnirt disp field' , (), 'FSL_FNIRT_DISPLACEMENT_FIELD' ),
239
+ (2007 , 'fnirt cubic spline coef' , (), 'FSL_CUBIC_SPLINE_COEFFICIENTS' ),
240
+ (2008 , 'fnirt dct coef' , (), 'FSL_DCT_COEFFICIENTS' ),
241
+ (2009 , 'fnirt quad spline coef' , (), 'FSL_QUADRATIC_SPLINE_COEFFICIENTS' ),
242
+ # FSL-specific intent codes - codes used by TOPUP
243
+ # ($FSLDIR/topup/topup_file_io.h:104)
244
+ (2016 , 'topup cubic spline coef ' , (),
245
+ 'FSL_TOPUP_CUBIC_SPLINE_COEFFICIENTS' ),
246
+ (2017 , 'topup quad spline coef' , (),
247
+ 'FSL_TOPUP_QUADRATIC_SPLINE_COEFFICIENTS' ),
248
+ (2018 , 'topup field' , (), 'FSL_TOPUP_FIELD' ),
235
249
), fields = ('code' , 'label' , 'parameters' , 'niistring' ))
236
250
237
251
@@ -1301,18 +1315,22 @@ def get_intent(self, code_repr='label'):
1301
1315
hdr = self ._structarr
1302
1316
recoder = self ._field_recoders ['intent_code' ]
1303
1317
code = int (hdr ['intent_code' ])
1318
+ known_intent = code in recoder
1304
1319
if code_repr == 'code' :
1305
1320
label = code
1306
1321
elif code_repr == 'label' :
1307
- label = recoder .label [code ]
1322
+ if known_intent :
1323
+ label = recoder .label [code ]
1324
+ else :
1325
+ label = 'unknown code ' + str (code )
1308
1326
else :
1309
1327
raise TypeError ('repr can be "label" or "code"' )
1310
- n_params = len (recoder .parameters [code ])
1328
+ n_params = len (recoder .parameters [code ]) if known_intent else 0
1311
1329
params = (float (hdr ['intent_p%d' % (i + 1 )]) for i in range (n_params ))
1312
1330
name = asstr (np .asscalar (hdr ['intent_name' ]))
1313
1331
return label , tuple (params ), name
1314
1332
1315
- def set_intent (self , code , params = (), name = '' ):
1333
+ def set_intent (self , code , params = (), name = '' , allow_unknown = False ):
1316
1334
''' Set the intent code, parameters and name
1317
1335
1318
1336
If parameters are not specified, assumed to be all zero. Each
@@ -1331,6 +1349,10 @@ def set_intent(self, code, params=(), name=''):
1331
1349
defaults to (). Unspecified parameters are set to 0.0
1332
1350
name : string
1333
1351
intent name (description). Defaults to ''
1352
+ allow_unknown : {False, True}, optional
1353
+ Allow unknown integer intent codes. If False (the default),
1354
+ a KeyError is raised on attempts to set the intent
1355
+ to an unknown code.
1334
1356
1335
1357
Returns
1336
1358
-------
@@ -1339,7 +1361,7 @@ def set_intent(self, code, params=(), name=''):
1339
1361
Examples
1340
1362
--------
1341
1363
>>> hdr = Nifti1Header()
1342
- >>> hdr.set_intent(0) # unknown code
1364
+ >>> hdr.set_intent(0) # no intent
1343
1365
>>> hdr.set_intent('z score')
1344
1366
>>> hdr.get_intent()
1345
1367
('z score', (), '')
@@ -1354,19 +1376,32 @@ def set_intent(self, code, params=(), name=''):
1354
1376
>>> hdr.set_intent('f test')
1355
1377
>>> hdr.get_intent()
1356
1378
('f test', (0.0, 0.0), '')
1379
+ >>> hdr.set_intent(9999, allow_unknown=True) # unknown code
1380
+ >>> hdr.get_intent()
1381
+ ('unknown code 9999', (), '')
1357
1382
'''
1358
1383
hdr = self ._structarr
1359
- icode = intent_codes .code [code ]
1360
- p_descr = intent_codes .parameters [code ]
1384
+ known_intent = code in intent_codes
1385
+ if not known_intent :
1386
+ # We can set intent via an unknown integer code, but can't via an
1387
+ # unknown string label
1388
+ if not allow_unknown or isinstance (code , string_types ):
1389
+ raise KeyError ('Unknown intent code: ' + str (code ))
1390
+ if known_intent :
1391
+ icode = intent_codes .code [code ]
1392
+ p_descr = intent_codes .parameters [code ]
1393
+ else :
1394
+ icode = code
1395
+ p_descr = ('p1' , 'p2' , 'p3' )
1361
1396
if len (params ) and len (params ) != len (p_descr ):
1362
1397
raise HeaderDataError ('Need params of form %s, or empty'
1363
1398
% (p_descr ,))
1399
+ hdr ['intent_code' ] = icode
1400
+ hdr ['intent_name' ] = name
1364
1401
all_params = [0 ] * 3
1365
1402
all_params [:len (params )] = params [:]
1366
1403
for i , param in enumerate (all_params ):
1367
1404
hdr ['intent_p%d' % (i + 1 )] = param
1368
- hdr ['intent_code' ] = icode
1369
- hdr ['intent_name' ] = name
1370
1405
1371
1406
def get_slice_duration (self ):
1372
1407
''' Get slice duration
0 commit comments