def get_kernel(Q2, Tl, b, n2, fmap, chi): # fmap, chi are shaped (Q3,Q1,Q2) # kernel is exp(f[q3,q1,n2,q2]) --IFFT-->> exp(f[q3,q1,n2,n2p]) q2_ax = np.arange(-Q2 / 2.0, Q2 / 2.0, dtype=fmap.dtype) T_n2 = fmap.dtype.type(b * Tl) n2 = fmap.dtype.type(n2) pi = fmap.dtype.type(np.pi) zarg = fmap[:, :, None, :] * T_n2[None, None, :, None] - (2 * pi * n2[:, None] * q2_ax[None, :] / Q2) print zarg.dtype K = np.empty(zarg.shape, zarg.dtype.char.upper()) np.cos(zarg, K.real) np.sin(zarg, K.imag) del zarg np.multiply(K, chi[:, :, None, :], K) ifft1(K, inplace=True) # a little hacky here.. if k-space was sampled asymmetrically, # then we only want to keep as many n2p points as there are n2 points # the points should be last len(n2) points in the N2P dimension # To find out if the image was sampled asymmetrically, check # that n2 has as many points >=0 as it does < 0 n_pe_really = 2 * (n2 >= 0).sum() if n2.shape[0] < n_pe_really: subslice = [slice(None)] * len(K.shape) n2pts = len(n2) subslice[-1] = slice(-n2pts, None, None) Ktrunc = K[subslice].copy() del K return Ktrunc return K
def get_kernel(Q2, Tl, b, n2, fmap, chi): # fmap, chi are shaped (Q3,Q1,Q2) # kernel is exp(f[q3,q1,n2,q2]) --IFFT-->> exp(f[q3,q1,n2,n2p]) q2_ax = np.arange(-Q2 / 2., Q2 / 2., dtype=fmap.dtype) T_n2 = fmap.dtype.type(b * Tl) n2 = fmap.dtype.type(n2) pi = fmap.dtype.type(np.pi) zarg = fmap[:,:,None,:] * T_n2[None,None,:,None] - \ (2*pi*n2[:,None]*q2_ax[None,:]/Q2) print zarg.dtype K = np.empty(zarg.shape, zarg.dtype.char.upper()) np.cos(zarg, K.real) np.sin(zarg, K.imag) del zarg np.multiply(K, chi[:, :, None, :], K) ifft1(K, inplace=True) # a little hacky here.. if k-space was sampled asymmetrically, # then we only want to keep as many n2p points as there are n2 points # the points should be last len(n2) points in the N2P dimension # To find out if the image was sampled asymmetrically, check # that n2 has as many points >=0 as it does < 0 n_pe_really = 2 * (n2 >= 0).sum() if n2.shape[0] < n_pe_really: subslice = [slice(None)] * len(K.shape) n2pts = len(n2) subslice[-1] = slice(-n2pts, None, None) Ktrunc = K[subslice].copy() del K return Ktrunc return K
def upsample(a, m=2): L = a.shape[0] dt = a.dtype.char b = np.zeros((L * m, ), dtype=dt.upper()) b[::m] = m * a fft1(b, shift=True, inplace=True) b[:(L * m - L) / 2] = 0. b[(L * m + L) / 2:] = 0. P.plot(np.abs(b)) P.show() ifft1(b, shift=True, inplace=True) return b.astype(dt)
def upsample(a, m=2): L = a.shape[0] dt = a.dtype.char b = np.zeros((L*m,), dtype=dt.upper()) b[::m] = m*a fft1(b, shift=True, inplace=True) b[:(L*m-L)/2] = 0. b[(L*m+L)/2:] = 0. P.plot(np.abs(b)) P.show() ifft1(b, shift=True, inplace=True) return b.astype(dt)
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
def bench_ifft1_time(self): from numpy.fft import ifft as numpy_ifft from scipy.fftpack import ifft as scipy_ifft print print ' 1D Double Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input ' print '-------------------------------------------------' print ' size | recon | numpy | scipy |' print '-------------------------------------------------' for size,repeat in [(100,7000),(1000,2000), (256,10000), (512,10000), (1024,1000), (2048,1000), (2048*2,500), (2048*4,500), ]: print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(cdouble) + \ random(repeat, size).astype(cdouble)*1j tr0 = time.time() y = ifft1(x, shift=False) trf = time.time() print '|%8.2f' % (trf-tr0), sys.stdout.flush() tn0 = time.time() ny = numpy_ifft(x) tnf = time.time() assert_array_almost_equal(ny,y) print '|%8.2f' % (tnf-tn0), sys.stdout.flush() ts0 = time.time() sy = scipy_ifft(x) tsf = time.time() assert_array_almost_equal(sy,y) print '|%8.2f' % (tsf-ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) sys.stdout.flush() print print ' 1D Double Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input shifted ' print '-------------------------------------------------' print ' size | recon | numpy | scipy |' print '-------------------------------------------------' for size,repeat in [(100,7000),(1000,2000), (256,10000), (512,10000), (1024,1000), (2048,1000), (2048*2,500), (2048*4,500), ]: chk = checkerline(size).astype(double) print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(cdouble) + \ random(repeat, size).astype(cdouble)*1j tr0 = time.time() y = ifft1(x, shift=True) trf = time.time() print '|%8.2f' % (trf-tr0), sys.stdout.flush() tn0 = time.time() ny = chk*numpy_ifft(chk*x) tnf = time.time() assert_array_almost_equal(ny,y) print '|%8.2f' % (tnf-tn0), sys.stdout.flush() ts0 = time.time() sy = chk*scipy_ifft(chk*x) tsf = time.time() assert_array_almost_equal(sy,y) print '|%8.2f' % (tsf-ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) sys.stdout.flush() print print ' 1D Single Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input ' print '-------------------------------------------------' print ' size | recon | numpy | scipy* |' print '-------------------------------------------------' for size,repeat in [(100,7000),(1000,2000), (256,10000), (512,10000), (1024,1000), (2048,1000), (2048*2,500), (2048*4,500), ]: print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(csingle) + \ random(repeat, size).astype(csingle)*1j tr0 = time.time() y = ifft1(x, shift=False) trf = time.time() print '|%8.2f' % (trf-tr0), sys.stdout.flush() tn0 = time.time() ny = numpy_ifft(x) tnf = time.time() assert_array_almost_equal(ny,y, decimal=2) print '|%8.2f' % (tnf-tn0), sys.stdout.flush() ts0 = time.time() sy = scipy_ifft(x.astype(cdouble)).astype(csingle) tsf = time.time() assert_array_almost_equal(sy,y, decimal=2) print '|%8.2f' % (tsf-ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) print "(* casted float->FT{double}->float)" sys.stdout.flush() print print ' 1D Single Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input shifted ' print '-------------------------------------------------' print ' size | recon | numpy | scipy* |' print '-------------------------------------------------' for size,repeat in [(100,7000),(1000,2000), (256,10000), (512,10000), (1024,1000), (2048,1000), (2048*2,500), (2048*4,500), ]: chk = checkerline(size).astype(single) print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(csingle) + \ random(repeat, size).astype(csingle)*1j tr0 = time.time() y = ifft1(x, shift=True) trf = time.time() print '|%8.2f' % (trf-tr0), sys.stdout.flush() tn0 = time.time() ny = chk*numpy_ifft(chk*x) tnf = time.time() assert_array_almost_equal(ny,y, decimal=2) print '|%8.2f' % (tnf-tn0), sys.stdout.flush() ts0 = time.time() sy = chk*(scipy_ifft((chk*x).astype(cdouble))).astype(csingle) tsf = time.time() assert_array_almost_equal(sy,y, decimal=2) print '|%8.2f' % (tsf-ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) print "(* casted float->FT{double}->float)" sys.stdout.flush()
def bench_ifft1_time(self): from numpy.fft import ifft as numpy_ifft from scipy.fftpack import ifft as scipy_ifft print print ' 1D Double Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input ' print '-------------------------------------------------' print ' size | recon | numpy | scipy |' print '-------------------------------------------------' for size, repeat in [ (100, 7000), (1000, 2000), (256, 10000), (512, 10000), (1024, 1000), (2048, 1000), (2048 * 2, 500), (2048 * 4, 500), ]: print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(cdouble) + \ random(repeat, size).astype(cdouble)*1j tr0 = time.time() y = ifft1(x, shift=False) trf = time.time() print '|%8.2f' % (trf - tr0), sys.stdout.flush() tn0 = time.time() ny = numpy_ifft(x) tnf = time.time() assert_array_almost_equal(ny, y) print '|%8.2f' % (tnf - tn0), sys.stdout.flush() ts0 = time.time() sy = scipy_ifft(x) tsf = time.time() assert_array_almost_equal(sy, y) print '|%8.2f' % (tsf - ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) sys.stdout.flush() print print ' 1D Double Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input shifted ' print '-------------------------------------------------' print ' size | recon | numpy | scipy |' print '-------------------------------------------------' for size, repeat in [ (100, 7000), (1000, 2000), (256, 10000), (512, 10000), (1024, 1000), (2048, 1000), (2048 * 2, 500), (2048 * 4, 500), ]: chk = checkerline(size).astype(double) print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(cdouble) + \ random(repeat, size).astype(cdouble)*1j tr0 = time.time() y = ifft1(x, shift=True) trf = time.time() print '|%8.2f' % (trf - tr0), sys.stdout.flush() tn0 = time.time() ny = chk * numpy_ifft(chk * x) tnf = time.time() assert_array_almost_equal(ny, y) print '|%8.2f' % (tnf - tn0), sys.stdout.flush() ts0 = time.time() sy = chk * scipy_ifft(chk * x) tsf = time.time() assert_array_almost_equal(sy, y) print '|%8.2f' % (tsf - ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) sys.stdout.flush() print print ' 1D Single Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input ' print '-------------------------------------------------' print ' size | recon | numpy | scipy* |' print '-------------------------------------------------' for size, repeat in [ (100, 7000), (1000, 2000), (256, 10000), (512, 10000), (1024, 1000), (2048, 1000), (2048 * 2, 500), (2048 * 4, 500), ]: print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(csingle) + \ random(repeat, size).astype(csingle)*1j tr0 = time.time() y = ifft1(x, shift=False) trf = time.time() print '|%8.2f' % (trf - tr0), sys.stdout.flush() tn0 = time.time() ny = numpy_ifft(x) tnf = time.time() assert_array_almost_equal(ny, y, decimal=2) print '|%8.2f' % (tnf - tn0), sys.stdout.flush() ts0 = time.time() sy = scipy_ifft(x.astype(cdouble)).astype(csingle) tsf = time.time() assert_array_almost_equal(sy, y, decimal=2) print '|%8.2f' % (tsf - ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) print "(* casted float->FT{double}->float)" sys.stdout.flush() print print ' 1D Single Precision (I)Fast Fourier Transform' print '=================================================' print ' | complex input shifted ' print '-------------------------------------------------' print ' size | recon | numpy | scipy* |' print '-------------------------------------------------' for size, repeat in [ (100, 7000), (1000, 2000), (256, 10000), (512, 10000), (1024, 1000), (2048, 1000), (2048 * 2, 500), (2048 * 4, 500), ]: chk = checkerline(size).astype(single) print '%5s' % size, sys.stdout.flush() x = random(repeat, size).astype(csingle) + \ random(repeat, size).astype(csingle)*1j tr0 = time.time() y = ifft1(x, shift=True) trf = time.time() print '|%8.2f' % (trf - tr0), sys.stdout.flush() tn0 = time.time() ny = chk * numpy_ifft(chk * x) tnf = time.time() assert_array_almost_equal(ny, y, decimal=2) print '|%8.2f' % (tnf - tn0), sys.stdout.flush() ts0 = time.time() sy = chk * (scipy_ifft((chk * x).astype(cdouble))).astype(csingle) tsf = time.time() assert_array_almost_equal(sy, y, decimal=2) print '|%8.2f' % (tsf - ts0), sys.stdout.flush() print ' (secs for %s calls)' % (repeat) print "(* casted float->FT{double}->float)" sys.stdout.flush()