Пример #1
0
    def run(self, image):
        if not verify_scanner_image(self, image):
            return
        fmap_file = clean_name(self.fmap_file)[0]
        ##         if hasattr(image, 'n_chan'):
        ##             fmap_file += '.c%02d'%image.chan
        try:
            fmapIm = readImage(fmap_file)
        except:
            self.log("fieldmap not found: " + fmap_file)
            return -1
        (nslice, npe, nfe) = image.shape[-3:]
        # make sure that the length of the q1 columns of the fmap
        # are AT LEAST equal to that of the image
        regrid_fac = max(npe, fmapIm.shape[-2])
        # fmap and chi-mask are swapped to be of shape (Q1,Q2)
        fmap = np.swapaxes(
            regrid_bilinear(fmapIm[0], regrid_fac, axis=-2).astype(np.float64),
            -1, -2)
        chi = np.swapaxes(regrid_bilinear(fmapIm[1], regrid_fac, axis=-2), -1,
                          -2)
        Q1, Q2 = fmap.shape[-2:]

        # compute T_n2 vector
        Tl = image.T_pe
        delT = image.delT

        a, b, n2, _ = image.epi_trajectory()

        K = get_kernel(Q2, Tl, b, n2, fmap, chi)

        for s in range(nslice):
            # dchunk is shaped (nvol, npe, nfe)
            # inverse transform along nfe (can't do in-place)
            dchunk = ifft1(image[:, s, :, :])
            # now shape is (nfe, npe, nvol)
            dchunk = np.swapaxes(dchunk, 0, 2)
            for fe in range(nfe):
                # want to solve Kx = y for x
                # K is (npe,npe), and y is (npe,nvol)
                #
                # There seems to be a trade-off here as nvol changes...
                # Doing this in two steps is faster for large nvol; I think
                # it takes advantage of the faster BLAS matrix-product in dot
                # as opposed to LAPACK's linear solver. For smaller values
                # of nvol, the overhead seems to outweigh the benefit.
                iK = regularized_inverse(K[s, fe], self.lmbda)
                dchunk[fe] = np.dot(iK, dchunk[fe])
            dchunk = np.swapaxes(dchunk, 0, 2)
            # fft x back to kx, can do inplace here
            fft1(dchunk, inplace=True)
            image[:, s, :, :] = dchunk
    def run(self, image):
        if not verify_scanner_image(self, image):
            return
        fmap_file = clean_name(self.fmap_file)[0]
        ##         if hasattr(image, 'n_chan'):
        ##             fmap_file += '.c%02d'%image.chan
        try:
            fmapIm = readImage(fmap_file)
        except:
            self.log("fieldmap not found: " + fmap_file)
            return -1
        (nslice, npe, nfe) = image.shape[-3:]
        # make sure that the length of the q1 columns of the fmap
        # are AT LEAST equal to that of the image
        regrid_fac = max(npe, fmapIm.shape[-2])
        # fmap and chi-mask are swapped to be of shape (Q1,Q2)
        fmap = np.swapaxes(regrid_bilinear(fmapIm[0], regrid_fac, axis=-2).astype(np.float64), -1, -2)
        chi = np.swapaxes(regrid_bilinear(fmapIm[1], regrid_fac, axis=-2), -1, -2)
        Q1, Q2 = fmap.shape[-2:]

        # compute T_n2 vector
        Tl = image.T_pe
        delT = image.delT

        a, b, n2, _ = image.epi_trajectory()

        K = get_kernel(Q2, Tl, b, n2, fmap, chi)

        for s in range(nslice):
            # dchunk is shaped (nvol, npe, nfe)
            # inverse transform along nfe (can't do in-place)
            dchunk = ifft1(image[:, s, :, :])
            # now shape is (nfe, npe, nvol)
            dchunk = np.swapaxes(dchunk, 0, 2)
            for fe in range(nfe):
                # want to solve Kx = y for x
                # K is (npe,npe), and y is (npe,nvol)
                #
                # There seems to be a trade-off here as nvol changes...
                # Doing this in two steps is faster for large nvol; I think
                # it takes advantage of the faster BLAS matrix-product in dot
                # as opposed to LAPACK's linear solver. For smaller values
                # of nvol, the overhead seems to outweigh the benefit.
                iK = regularized_inverse(K[s, fe], self.lmbda)
                dchunk[fe] = np.dot(iK, dchunk[fe])
            dchunk = np.swapaxes(dchunk, 0, 2)
            # fft x back to kx, can do inplace here
            fft1(dchunk, inplace=True)
            image[:, s, :, :] = dchunk
Пример #3
0
    def run(self, image):

        # Make sure it's an asems image
        if not hasattr(image, "asym_times") and not hasattr(image, "te"):
            self.log("No asym_time, can't compute field map.")
            return
        asym_times = image.asym_times

        # Make sure there are at least two volumes
        if image.tdim < 2:
            self.log("Cannot calculate field map from only a single volume."\
                     "  Must have at least two volumes.")
            return

        diffshape = (image.tdim-1,) + image.shape[-3:]
        diffshape = image.tdim > 2 and diffshape or diffshape[-3:]

        phase_map = image._subimage(np.zeros(diffshape, np.float32))
        bytemask = image._subimage(np.zeros(diffshape, np.float32))

        # Get phase difference between scan n+1 and scan n
        # Then find the mask and unwrapped phase, and compute
        # the field strength in terms of rad/s
        fwhm = max(image.isize, image.jsize) * 1.5
        for psub, msub in zip(phase_map, bytemask):
            del_te = asym_times[msub.num+1] - asym_times[msub.num]
            if self.haschans:
                for c in range(image.n_chan):
                    image.load_chan(c)
                    dphs = image[msub.num+1] * np.conjugate(image[msub.num])
                    msk = build_3Dmask(np.power(np.abs(dphs), 0.5),
                                       self.threshfactor)
                    msub[:] += msk
##                     psub[:] += (unwrap3D(np.angle(dphs)) * msk) #/ del_te
##                     psub[:] += gaussian_smooth(np.angle(dphs), 1.5, 3)
##                     smooth_phs = unwrap3D(gaussian_smooth(np.angle(dphs),
##                                                           sigma_y, sigma_x,
##                                                           gaussian_dims))*msk
                    smooth_phs = ReconImage(np.angle(dphs),
                                            isize=image.isize,
                                            jsize=image.jsize)
                    GaussianSmooth(fwhm=fwhm).run(smooth_phs)
                    psub[:] += smooth_phs[:]
                #psub[:] = np.where(msub[:], psub[:]/msub[:], 0)
                psub[:] /= image.n_chan
                msub[:] = np.where(msub[:], 1, 0)
                #psub[:] = (unwrap3D(psub[:]) * msub[:]) #/ del_te
                image.use_membuffer(0)
            else:
                dphs = image[msub.num+1] * np.conjugate(image[msub.num])
                msub[:] = build_3Dmask(np.power(np.abs(dphs), 0.5),
                                       self.threshfactor)
                #psub[:] = (unwrap3D(np.angle(dphs)) * msub[:]) #/ del_te
                psub[:] = np.angle(dphs)
                GaussianSmooth(fwhm=fwhm).run(psub)
                psub[:] = unwrap3D(psub[:])*msub[:]
                psub[:] /= del_te

        # for each diff vol, write a file with vol0 = fmap, vol1 = mask
        fmap_file = clean_name(self.fmap_file)[0]
        if phase_map.ndim > 3:
            for index in range(phase_map.tdim):
                catIm = phase_map.subImage(index).concatenate(
                    bytemask.subImage(index), newdim=True)
                catIm.writeImage(fmap_file+"-%d"%index,
                                 format_type="nifti-single")
        else:
            catIm = phase_map.concatenate(bytemask, newdim=True)
            catIm.writeImage(fmap_file, format_type="nifti-single")
Пример #4
0
    def run(self, image):

        # Make sure it's an asems image
        if not hasattr(image, "asym_times") and not hasattr(image, "te"):
            self.log("No asym_time, can't compute field map.")
            return
        asym_times = image.asym_times

        # Make sure there are at least two volumes
        if image.tdim < 2:
            self.log("Cannot calculate field map from only a single volume."\
                     "  Must have at least two volumes.")
            return

        diffshape = (image.tdim - 1, ) + image.shape[-3:]
        diffshape = image.tdim > 2 and diffshape or diffshape[-3:]

        phase_map = image._subimage(np.zeros(diffshape, np.float32))
        bytemask = image._subimage(np.zeros(diffshape, np.float32))

        # Get phase difference between scan n+1 and scan n
        # Then find the mask and unwrapped phase, and compute
        # the field strength in terms of rad/s
        fwhm = max(image.isize, image.jsize) * 1.5
        for psub, msub in zip(phase_map, bytemask):
            del_te = asym_times[msub.num + 1] - asym_times[msub.num]
            if self.haschans:
                for c in range(image.n_chan):
                    image.load_chan(c)
                    dphs = image[msub.num + 1] * np.conjugate(image[msub.num])
                    msk = build_3Dmask(np.power(np.abs(dphs), 0.5),
                                       self.threshfactor)
                    msub[:] += msk
                    ##                     psub[:] += (unwrap3D(np.angle(dphs)) * msk) #/ del_te
                    ##                     psub[:] += gaussian_smooth(np.angle(dphs), 1.5, 3)
                    ##                     smooth_phs = unwrap3D(gaussian_smooth(np.angle(dphs),
                    ##                                                           sigma_y, sigma_x,
                    ##                                                           gaussian_dims))*msk
                    smooth_phs = ReconImage(np.angle(dphs),
                                            isize=image.isize,
                                            jsize=image.jsize)
                    GaussianSmooth(fwhm=fwhm).run(smooth_phs)
                    psub[:] += smooth_phs[:]
                #psub[:] = np.where(msub[:], psub[:]/msub[:], 0)
                psub[:] /= image.n_chan
                msub[:] = np.where(msub[:], 1, 0)
                #psub[:] = (unwrap3D(psub[:]) * msub[:]) #/ del_te
                image.use_membuffer(0)
            else:
                dphs = image[msub.num + 1] * np.conjugate(image[msub.num])
                msub[:] = build_3Dmask(np.power(np.abs(dphs), 0.5),
                                       self.threshfactor)
                #psub[:] = (unwrap3D(np.angle(dphs)) * msub[:]) #/ del_te
                psub[:] = np.angle(dphs)
                GaussianSmooth(fwhm=fwhm).run(psub)
                psub[:] = unwrap3D(psub[:]) * msub[:]
                psub[:] /= del_te

        # for each diff vol, write a file with vol0 = fmap, vol1 = mask
        fmap_file = clean_name(self.fmap_file)[0]
        if phase_map.ndim > 3:
            for index in range(phase_map.tdim):
                catIm = phase_map.subImage(index).concatenate(
                    bytemask.subImage(index), newdim=True)
                catIm.writeImage(fmap_file + "-%d" % index,
                                 format_type="nifti-single")
        else:
            catIm = phase_map.concatenate(bytemask, newdim=True)
            catIm.writeImage(fmap_file, format_type="nifti-single")