コード例 #1
0
    def write_hdr(self, filename):
        "Write ANALYZE format header (.hdr) file."
        image = self.image

        # NOT IMPLEMENTING YET
        # ReconImage r0 is the offset in xyz-space, but ANALYZE
        # calls for an offset in vox-space
        xform = image.orientation_xform.tomatrix()
        orientation_name = canonical_orient(xform)
        inv_xform = np.linalg.inv(xform)
        r0 = np.array([image.x0, image.y0, image.z0])
        dimscl = np.array([image.isize, image.jsize, image.ksize])
        r0_ana = (-np.dot(inv_xform, r0) / dimscl).astype(np.int16)

        dtype = datatype2dtype[self.datatype]
        if dtype in np.sctypes['int']:
            glmax = 2**(datatype2bitpix[self.datatype] - 1) - 1
        elif dtype in np.sctypes['uint']:
            glmax = 2**(datatype2bitpix[self.datatype]) - 1
        else:
            glmax = 1
        imagevalues = {
            'datatype': self.datatype,
            'bitpix': datatype2bitpix[self.datatype],
            # should be 4 for (z,y,x) and (t,z,y,x) ...
            # should be 3 for (y,x) ??
            'ndim': (image.ndim >= 3 and 4 or image.ndim),
            'idim': image.idim,
            'jdim': image.jdim,
            'kdim': image.kdim,
            'tdim': (image.tdim or 1),
            'isize': image.isize,
            'jsize': image.jsize,
            'ksize': image.ksize,
            'tsize': image.tsize,
            'x0': r0_ana[0],
            'y0': r0_ana[1],
            'z0': r0_ana[2],
            'scale_factor': self.scaling,
            # SPM says that these are (0,2^bitpix-1) for integers,
            # or (0,1) for floating points
            'glmin': 0,
            'glmax': glmax,
            'cal_min': 0.0,  # don't suggest display color mapping
            'cal_max': 0.0,
            'orient': orientname2orientcode.get(orientation_name, 255),
        }

        def fieldvalue(fieldname, fieldformat):
            if imagevalues.has_key(fieldname):
                return imagevalues[fieldname]
            return self._default_field_value(fieldname, fieldformat)

        fieldvalues = [fieldvalue(*field) for field in struct_fields.items()]
        header = struct_pack(NATIVE, field_formats, fieldvalues)
        file(filename, 'wb').write(header)
コード例 #2
0
ファイル: nifti.py プロジェクト: KaiQiao1992/recon-tools
    def make_hdr(self):
        "Pack a NIFTI format header."
        # The NIFTI Q-form field is helpful for keeping track of anatomical
        # dimensions in the presence of rotations.
        #
        # (un)rotation is handled like this: take the image as transformed with
        # 2 rotations, Qs, Rb (Qs represents a transform between scanner space
        # and a right-handed interpretation of the data, Rb is the xform
        # applied by slicing coronal-wise, sagital-wise, etc with the slice
        # gradient).
        #     Then I_m = Qs*Rb(psi,theta,phi)*I_real
        # The goal is to encode a quaternion which corrects this rotation:
        #     Rc = inv(Rb)*inv(Qs)
        #     so I_real = Rc*I_m
        #
        # The euler angles for slicing rotations are from procpar
        # To avoid the chance of interpolation, these angles are "normalized"
        # to the closest multiple of pi/2 (ie 22 degrees->0, 49 degrees->90)
        # 

        image = self.image
        Qform = image.orientation_xform.Q
        Qform_mat = image.orientation_xform.tomatrix()
        # hack alert!
##         (pe_dim, fe_dim) = Qform_mat[0,0] == 0. and (2, 1) or (1, 2)
        (pe_dim, fe_dim) = (2,1)
        imagevalues = {
          'dim_info': (3<<4 | pe_dim<<2 | fe_dim),
          'datatype': self.datatype,
          'bitpix': datatype2bitpix[self.datatype],
          'ndim': image.ndim,
          'idim': image.idim,
          'jdim': image.jdim,
          # including t,z info should probably depend on targetdims
          'kdim': image.kdim,
          'tdim': image.tdim,
          'isize': image.isize,
          'jsize': image.jsize,
          'ksize': image.ksize,
          'tsize': image.tsize,
          'scl_slope': self.scaling,
          'xyzt_units': (NIFTI_UNITS_MM | NIFTI_UNITS_SEC),
          'qfac': image.orientation_xform.qfac,
          'qform_code': NIFTI_XFORM_SCANNER_ANAT,
          'quatern_b': Qform[0],
          'quatern_c': Qform[1],
          'quatern_d': Qform[2],
          'qoffset_x': image.x0,
          'qoffset_y': image.y0,
          'qoffset_z': image.z0,
          'slice_start': 0,
          # THIS KDIM ASSUMPTION IS ONLY SAFE BECAUSE NOTHING ROTATES
          # IMAGES OFF THE ORIGINAL SLICE AXIS (YET!!)
          'slice_end': image.kdim-1,
          # VARIAN ACQUIRES FROM +Z TO -Z (IN NEURO FRAME)
          'slice_code': NIFTI_SLICE_SEQ_DEC,
          'slice_duration': float(image.tsize) / image.kdim
          }
        
        if self.filetype=='single':
            imagevalues['vox_offset'] = HEADER_SIZE + self.sizeof_extension
            imagevalues['magic'] = 'n+1'
        else:
            imagevalues['magic'] = 'ni1'

        def fieldvalue(fieldname, fieldformat):
            return imagevalues.get(fieldname) or \
                   self._default_field_value(fieldname, fieldformat)

        fieldvalues = [fieldvalue(*field) for field in struct_fields.items()]
        return struct_pack(NATIVE, field_formats, fieldvalues)