1313from __future__ import division , print_function
1414import warnings
1515from io import BytesIO
16+ from six import string_types
1617
1718import numpy as np
1819import numpy .linalg as npl
232233 (2003 , 'rgb vector' , (), "NIFTI_INTENT_RGB_VECTOR" ),
233234 (2004 , 'rgba vector' , (), "NIFTI_INTENT_RGBA_VECTOR" ),
234235 (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' ),
235249), fields = ('code' , 'label' , 'parameters' , 'niistring' ))
236250
237251
@@ -1301,18 +1315,22 @@ def get_intent(self, code_repr='label'):
13011315 hdr = self ._structarr
13021316 recoder = self ._field_recoders ['intent_code' ]
13031317 code = int (hdr ['intent_code' ])
1318+ known_intent = code in recoder
13041319 if code_repr == 'code' :
13051320 label = code
13061321 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 )
13081326 else :
13091327 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
13111329 params = (float (hdr ['intent_p%d' % (i + 1 )]) for i in range (n_params ))
13121330 name = asstr (np .asscalar (hdr ['intent_name' ]))
13131331 return label , tuple (params ), name
13141332
1315- def set_intent (self , code , params = (), name = '' ):
1333+ def set_intent (self , code , params = (), name = '' , allow_unknown = False ):
13161334 ''' Set the intent code, parameters and name
13171335
13181336 If parameters are not specified, assumed to be all zero. Each
@@ -1331,6 +1349,10 @@ def set_intent(self, code, params=(), name=''):
13311349 defaults to (). Unspecified parameters are set to 0.0
13321350 name : string
13331351 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.
13341356
13351357 Returns
13361358 -------
@@ -1339,7 +1361,7 @@ def set_intent(self, code, params=(), name=''):
13391361 Examples
13401362 --------
13411363 >>> hdr = Nifti1Header()
1342- >>> hdr.set_intent(0) # unknown code
1364+ >>> hdr.set_intent(0) # no intent
13431365 >>> hdr.set_intent('z score')
13441366 >>> hdr.get_intent()
13451367 ('z score', (), '')
@@ -1354,19 +1376,32 @@ def set_intent(self, code, params=(), name=''):
13541376 >>> hdr.set_intent('f test')
13551377 >>> hdr.get_intent()
13561378 ('f test', (0.0, 0.0), '')
1379+ >>> hdr.set_intent(9999, allow_unknown=True) # unknown code
1380+ >>> hdr.get_intent()
1381+ ('unknown code 9999', (), '')
13571382 '''
13581383 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' )
13611396 if len (params ) and len (params ) != len (p_descr ):
13621397 raise HeaderDataError ('Need params of form %s, or empty'
13631398 % (p_descr ,))
1399+ hdr ['intent_code' ] = icode
1400+ hdr ['intent_name' ] = name
13641401 all_params = [0 ] * 3
13651402 all_params [:len (params )] = params [:]
13661403 for i , param in enumerate (all_params ):
13671404 hdr ['intent_p%d' % (i + 1 )] = param
1368- hdr ['intent_code' ] = icode
1369- hdr ['intent_name' ] = name
13701405
13711406 def get_slice_duration (self ):
13721407 ''' Get slice duration
0 commit comments