def getPixDims(self): """Returns the pixel dimensions on all 7 dimensions. The function is similar to `getVoxDims()`, but instead of the 3d spatial dimensions of a voxel it returns the dimensions of an image pixel on all 7 dimensions supported by the NIfTI dataformat. .. seealso:: :meth:`~nifti.format.NiftiFormat.getVoxDims`, :meth:`~nifti.format.NiftiFormat.setPixDims`, :attr:`~nifti.format.NiftiFormat.pixdim` """ return \ tuple([ ncl.floatArray_frompointer(self.__nimg.pixdim)[i] for i in range(1,8) ] )
def setPixDims(self, value): """Set the pixel dimensions. :Parameter: value: sequence Up to 7 values (max. number of dimensions supported by the NIfTI format) are allowed in the sequence. The supplied sequence can be shorter than seven elements. In this case only present values are assigned starting with the first dimension (spatial: x). .. note:: Calling `setPixDims()` with a length-3 sequence equals calling `setVoxDims()`. .. seealso:: :meth:`~nifti.format.NiftiFormat.setVoxDims`, :meth:`~nifti.format.NiftiFormat.getPixDims`, :attr:`~nifti.format.NiftiFormat.pixdim` """ if len(value) > 7: raise ValueError, \ 'The Nifti format does not support more than 7 dimensions.' pixdim = ncl.floatArray_frompointer( self.__nimg.pixdim ) for i, val in enumerate(value): pixdim[i+1] = float(val) # The nifticlib uses dimension deltas (dx, dy, dz, dt...) to store # the pixdim values (in addition to the pixdim array). When # saving the image to a file, the deltas are used, not the pixdims. # The nifti_update_dims_from_array sync's the deltas with the pixdims. # (It also syncs the dim array with it's duplicate scalar variables.) ncl.nifti_update_dims_from_array(self.__nimg)
def updateNiftiHeaderFromDict(nhdr, hdrdict): """Update a NIfTI header struct with data from a dictionary. The supplied dictionary might contain additonal data elements that do not match any nifti header element. These are silently ignored. Several checks are performed to ensure validity of the resulting nifti header struct. If any check fails a ValueError exception will be thrown. However, some tests are still missing. :Parameters: nhdr: nifti_1_header To be updated NIfTI header struct (in-place update). hdrdict: dict Dictionary containing information intented to be merged into the NIfTI header struct. """ # this function is still incomplete. add more checks if hdrdict.has_key('data_type'): if len(hdrdict['data_type']) > 9: raise ValueError, \ "Nifti header property 'data_type' must not be longer " \ + "than 9 characters." nhdr.data_type = hdrdict['data_type'] if hdrdict.has_key('db_name'): if len(hdrdict['db_name']) > 79: raise ValueError, "Nifti header property 'db_name' must " \ + "not be longer than 17 characters." nhdr.db_name = hdrdict['db_name'] if hdrdict.has_key('extents'): nhdr.extents = hdrdict['extents'] if hdrdict.has_key('session_error'): nhdr.session_error = hdrdict['session_error'] if hdrdict.has_key('regular'): if len(hdrdict['regular']) > 1: raise ValueError, \ "Nifti header property 'regular' has to be a single " \ + "character." nhdr.regular = hdrdict['regular'] if hdrdict.has_key('dim_info'): if len(hdrdict['dim_info']) > 1: raise ValueError, \ "Nifti header property 'dim_info' has to be a " \ + "single character." nhdr.dim_info = hdrdict['dim_info'] if hdrdict.has_key('dim'): dim = ncl.shortArray_frompointer(nhdr.dim) for i in range(8): dim[i] = hdrdict['dim'][i] if hdrdict.has_key('intent_p1'): nhdr.intent_p1 = hdrdict['intent_p1'] if hdrdict.has_key('intent_p2'): nhdr.intent_p2 = hdrdict['intent_p2'] if hdrdict.has_key('intent_p3'): nhdr.intent_p3 = hdrdict['intent_p3'] if hdrdict.has_key('intent_code'): nhdr.intent_code = hdrdict['intent_code'] if hdrdict.has_key('datatype'): nhdr.datatype = hdrdict['datatype'] if hdrdict.has_key('bitpix'): nhdr.bitpix = hdrdict['bitpix'] if hdrdict.has_key('slice_start'): nhdr.slice_start = hdrdict['slice_start'] if hdrdict.has_key('pixdim'): pixdim = ncl.floatArray_frompointer(nhdr.pixdim) for i in range(8): pixdim[i] = hdrdict['pixdim'][i] if hdrdict.has_key('vox_offset'): nhdr.vox_offset = hdrdict['vox_offset'] if hdrdict.has_key('scl_slope'): nhdr.scl_slope = hdrdict['scl_slope'] if hdrdict.has_key('scl_inter'): nhdr.scl_inter = hdrdict['scl_inter'] if hdrdict.has_key('slice_end'): nhdr.slice_end = hdrdict['slice_end'] if hdrdict.has_key('slice_code'): nhdr.slice_code = hdrdict['slice_code'] if hdrdict.has_key('xyz_unit') \ or hdrdict.has_key('time_unit'): # precharge units from current header, in case only one of them is to be # updated tu = ncl.xyzt2space(nhdr.xyzt_units) su = ncl.xyzt2time(nhdr.xyzt_units) # overwrite unit if present if hdrdict.has_key('xyz_unit'): su = _checkUnit(hdrdict['xyz_unit'], valid_xyz_unit_codes) if hdrdict.has_key('time_unit'): tu = _checkUnit(hdrdict['time_unit'], valid_time_unit_codes) # compress both units into hdr format nhdr.xyzt_units = ncl.spacetime2xyzt(su, tu) if hdrdict.has_key('cal_max'): nhdr.cal_max = hdrdict['cal_max'] if hdrdict.has_key('cal_min'): nhdr.cal_min = hdrdict['cal_min'] if hdrdict.has_key('slice_duration'): nhdr.slice_duration = hdrdict['slice_duration'] if hdrdict.has_key('toffset'): nhdr.toffset = hdrdict['toffset'] if hdrdict.has_key('glmax'): nhdr.glmax = hdrdict['glmax'] if hdrdict.has_key('glmin'): nhdr.glmin = hdrdict['glmin'] if hdrdict.has_key('descrip'): if len(hdrdict['descrip']) > 79: raise ValueError, \ "Nifti header property 'descrip' must not be longer " \ + "than 79 characters." nhdr.descrip = hdrdict['descrip'] if hdrdict.has_key('aux_file'): if len(hdrdict['aux_file']) > 23: raise ValueError, \ "Nifti header property 'aux_file' must not be longer " \ + "than 23 characters." nhdr.aux_file = hdrdict['aux_file'] if hdrdict.has_key('qform_code'): nhdr.qform_code = hdrdict['qform_code'] if hdrdict.has_key('sform_code'): nhdr.sform_code = hdrdict['sform_code'] if hdrdict.has_key('quatern'): if not len(hdrdict['quatern']) == 3: raise ValueError, \ "Nifti header property 'quatern' must be float 3-tuple." nhdr.quatern_b = hdrdict['quatern'][0] nhdr.quatern_c = hdrdict['quatern'][1] nhdr.quatern_d = hdrdict['quatern'][2] if hdrdict.has_key('qoffset'): if not len(hdrdict['qoffset']) == 3: raise ValueError, \ "Nifti header property 'qoffset' must be float 3-tuple." nhdr.qoffset_x = hdrdict['qoffset'][0] nhdr.qoffset_y = hdrdict['qoffset'][1] nhdr.qoffset_z = hdrdict['qoffset'][2] if hdrdict.has_key('sform'): if not hdrdict['sform'].shape == (4, 4): raise ValueError, \ "Nifti header property 'sform' must be 4x4 matrix." srow_x = ncl.floatArray_frompointer(nhdr.srow_x) for i in range(4): srow_x[i] = hdrdict['sform'][0][i] srow_y = ncl.floatArray_frompointer(nhdr.srow_y) for i in range(4): srow_y[i] = hdrdict['sform'][1][i] srow_z = ncl.floatArray_frompointer(nhdr.srow_z) for i in range(4): srow_z[i] = hdrdict['sform'][2][i] if hdrdict.has_key('intent_name'): if len(hdrdict['intent_name']) > 15: raise ValueError, \ "Nifti header property 'intent_name' must not be " \ + "longer than 15 characters." nhdr.intent_name = hdrdict['intent_name'] if hdrdict.has_key('magic'): if hdrdict['magic'] != 'ni1' and hdrdict['magic'] != 'n+1': raise ValueError, \ "Nifti header property 'magic' must be 'ni1' or 'n+1'." nhdr.magic = hdrdict['magic']
def nhdr2dict(nhdr, extensions=None): """Convert a NIfTI header struct into a python dictionary. While most elements of the header struct will be translated 1:1 some (e.g. sform matrix) are converted into more convenient datatypes (i.e. 4x4 matrix instead of 16 separate values). :Parameters: nhdr: nifti_1_header extensions: NiftiExtensions instance All extensions will be merged into the returned dictionary under the special `extensions` key. :Returns: dict """ h = {} # the following header elements are converted in a simple loop # as they do not need special handling auto_convert = [ 'session_error', 'extents', 'sizeof_hdr', 'slice_duration', 'slice_start', 'cal_max', 'intent_p1', 'intent_p2', 'intent_p3', 'intent_code', 'sform_code', 'cal_min', 'scl_slope', 'slice_code', 'bitpix', 'descrip', 'glmin', 'dim_info', 'glmax', 'data_type', 'aux_file', 'intent_name', 'vox_offset', 'db_name', 'scl_inter', 'magic', 'datatype', 'regular', 'slice_end', 'qform_code', 'toffset' ] # now just dump all attributes into a dict for attr in auto_convert: h[attr] = eval('nhdr.' + attr) # handle a few special cases # handle 'pixdim': carray -> list pixdim = ncl.floatArray_frompointer(nhdr.pixdim) h['pixdim'] = [ pixdim[i] for i in range(8) ] # handle dim: carray -> list dim = ncl.shortArray_frompointer(nhdr.dim) h['dim'] = [ dim[i] for i in range(8) ] # handle sform: carrays -> (4x4) ndarray srow_x = ncl.floatArray_frompointer( nhdr.srow_x ) srow_y = ncl.floatArray_frompointer( nhdr.srow_y ) srow_z = ncl.floatArray_frompointer( nhdr.srow_z ) h['sform'] = N.array( [ [ srow_x[i] for i in range(4) ], [ srow_y[i] for i in range(4) ], [ srow_z[i] for i in range(4) ], [ 0.0, 0.0, 0.0, 1.0 ] ] ) # handle qform stuff: 3 numbers -> list h['quatern'] = [ nhdr.quatern_b, nhdr.quatern_c, nhdr.quatern_d ] h['qoffset'] = [ nhdr.qoffset_x, nhdr.qoffset_y, nhdr.qoffset_z ] # some more postprocessing # expand units h['xyz_unit'] = ncl.xyzt2space(nhdr.xyzt_units) h['time_unit'] = ncl.xyzt2time(nhdr.xyzt_units) if not extensions: return h # # handle extensions # # simply store a tuple of code (i.e. extension type) and extension data h['extensions'] = [e for e in extensions.iteritems()] return h