def spec2grid(sfield): """ Transform one frame of SQG model output to a grided (physical) representation. Assumes 'sfield' to be up-half plane, and specifies lower half plane by conjugate sym (since physical field is assumed real-valued). Input field should have dimensions (...,kmax+1,2*kmax+1,nz), where kmax=2^n-1, hence physical resolution will be 2^(n+1) x 2^(n+1). NOTE: top row of the input field corresponds to ky = 0, the kx<0 part is NOT assumed a priori to be conjugate- symmetric with the kx>0 part. NOTE: grid2spec(spec2grid(fk)) = fk. OPTIONAL: da = true pads input with 0s before transfoming to gridspace, for dealiased products. Default is da = false. Args: sfield: complex spectrum field with shape (t(optional), ky, kx, z(optional)) """ if not _is_single_layer(sfield): hres = sfield.shape[-2] + 1 fk = fullspec(sfield) fk = fftpack.ifftshift(fk, axes=(-2,-3)) return hres*hres*np.real(fftpack.ifft2(fk, axes=(-2,-3))) else: hres = sfield.shape[-1] + 1 fk = fullspec(sfield, True) fk = fftpack.ifftshift(fk, axes=(-1,-2)) return hres*hres*np.real(fftpack.ifft2(fk, axes=(-1,-2)))
def fftPropagate(field, grid, propDistance): '''Propagates a sampled 1D field along the optical axis. fftPropagate propagates a sampled 1D field a distance L by computing the field's angular spectrum, multiplying each spectral component by the propagation kernel exp(j * 2 * pi * fx * L / wavelength), and then recomibining the propagated spectral components. The angular spectrum is computed using a FFT. Parameters ---------- field : 1D array of complex The sampled field to propagate. grid : Grid The grid on which the sampled field lies. propDistance : float The distance to propagate the field in the same physical units as the grid. ''' scalingFactor = (grid.physicalSize / (grid.gridSize - 1)) F = scalingFactor * fftshift(fft(ifftshift(field))) # Compute the z-component of the wavevector # Adding 0j ensures that numpy.sqrt returns complex numbers kz = 2 * np.pi * np.sqrt(1 - (grid.pfX * grid.wavelength)**2 + 0j) / grid.wavelength # Propagate the field's spectral components Fprop = F * np.exp(1j * kz * propDistance) # Recombine the spectral components fieldProp = fftshift(ifft(ifftshift(Fprop))) / scalingFactor return fieldProp
def convolve2D_fft(theta,F): func = KS_kernel_real #func = gaussian_real assert theta.shape == F.shape N1,N2 = theta.shape dtheta1 = theta[1,1].real - theta[0,0].real theta1 = dtheta1*(numpy.arange(2*N1)-N1) theta1 = fftpack.ifftshift(theta1) dtheta2 = theta[1,1].imag - theta[0,0].imag theta2 = dtheta2*(numpy.arange(2*N2)-N2) theta2 = fftpack.ifftshift(theta2) theta_kernel = numpy.zeros((2*N1,2*N2),dtype=complex) theta_kernel += theta1.reshape((2*N1,1)) theta_kernel += 1j*theta2 kernel = func(theta_kernel) dA = dtheta1 * dtheta2 F_fft = fftpack.fft2(F, (2*N1,2*N2) ) * dA F_fft *= fftpack.fft2(kernel,(2*N1,2*N2) ) out = fftpack.ifft2(F_fft) return out[:N1,:N2]
def rescale_target_superpixel_resolution(E_target): '''Rescale the target field to the superpixel resolution (currently only 4x4 superpixels implemented)''' superpixelSize = 4 ny,nx = scipy.shape(E_target) maskCenterX = scipy.ceil((nx+1)/2) maskCenterY = scipy.ceil((ny+1)/2) nSuperpixelX = int(nx/superpixelSize) nSuperpixelY = int(ny/superpixelSize) FourierMaskSuperpixelResolution = fourier_mask(ny,nx,superpixelSize) E_target_ft = fft.fftshift(fft.fft2(fft.ifftshift(E_target))) #Apply mask E_target_ft = FourierMaskSuperpixelResolution*E_target_ft #Remove zeros outside of mask E_superpixelResolution_ft = E_target_ft[(maskCenterY - scipy.ceil((nSuperpixelY-1)/2)-1):(maskCenterY + scipy.floor((nSuperpixelY-1)/2)),(maskCenterX - scipy.ceil((nSuperpixelX-1)/2)-1):(maskCenterX + scipy.floor((nSuperpixelX-1)/2))] # Add phase gradient to compensate for anomalous 1.5 pixel shift in real # plane phaseFactor = [[(scipy.exp(2*1j*pi*((k+1)/nSuperpixelY+(j+1)/nSuperpixelX)*3/8)) for j in range(nSuperpixelX)] for k in range(nSuperpixelY)] # QUESTION E_superpixelResolution_ft = E_superpixelResolution_ft*phaseFactor # Fourier transform back to DMD plane E_superpixelResolution = fft.fftshift(fft.ifft2(fft.ifftshift(E_superpixelResolution_ft))) return E_superpixelResolution
def frankotchellappa(dzdx, dzdy): rows, cols = dzdx.shape # The following sets up matrices specifying frequencies in the x and y # directions corresponding to the Fourier transforms of the gradient # data. They range from -0.5 cycles/pixel to + 0.5 cycles/pixel. # The scaling of this is irrelevant as long as it represents a full # circle domain. This is functionally equivalent to any constant * pi pi_over_2 = np.pi / 2.0 row_grid = np.linspace(-pi_over_2, pi_over_2, rows) col_grid = np.linspace(-pi_over_2, pi_over_2, cols) wy, wx = np.meshgrid(row_grid, col_grid, indexing='ij') # Quadrant shift to put zero frequency at the appropriate edge wx = ifftshift(wx) wy = ifftshift(wy) # Fourier transforms of gradients DZDX = fft2(dzdx) DZDY = fft2(dzdy) # Integrate in the frequency domain by phase shifting by pi/2 and # weighting the Fourier coefficients by their frequencies in x and y and # then dividing by the squared frequency denom = (wx ** 2 + wy ** 2) Z = (-1j * wx * DZDX - 1j * wy * DZDY) / denom Z = np.nan_to_num(Z) return np.real(ifft2(Z))
def kappa_to_gamma(kappa,dt1,dt2=None): """ simple application of Kaiser-Squires (1995) kernel in fourier space to convert complex shear to complex convergence: imaginary part of convergence is B-mode. """ if not dt2: dt2 = dt1 N1,N2 = kappa.shape #convert angles from arcminutes to radians dt1 = dt1 * np.pi / 180. / 60. dt2 = dt2 * np.pi / 180. / 60. #compute k values corresponding to field size dk1 = np.pi / N1 / dt1 dk2 = np.pi / N2 / dt2 k1 = fftpack.ifftshift( dk1 * (np.arange(2*N1)-N1) ) k2 = fftpack.ifftshift( dk2 * (np.arange(2*N2)-N2) ) ipart,rpart = np.meshgrid(k2,k1) k = rpart + 1j*ipart #compute Kaiser-Squires kernel on this grid. Eq. 43 p. 329 fourier_map = np.conj( KS_kernel(k) ) #compute Fourier transform of the kappa kappa_fft = fftpack.fft2( kappa, (2*N1,2*N2) ) gamma_fft = kappa_fft * fourier_map gamma = fftpack.ifft2(gamma_fft)[:N1,:N2] return gamma
def convolve2D_analytic(theta,F): func = KS_kernel_fourier #func = gaussian_fourier assert theta.shape == F.shape dtheta1 = theta[1,1].real - theta[0,0].real dtheta2 = theta[1,1].imag - theta[0,0].imag N1,N2 = theta.shape dell1 = numpy.pi / N1 / dtheta1 dell2 = numpy.pi / N2 / dtheta2 ell1 = fftpack.ifftshift( dell1 * (numpy.arange(2*N1)-N1) ) ell2 = fftpack.ifftshift( dell2 * (numpy.arange(2*N2)-N2) ) ell = numpy.zeros((2*N1,2*N2),dtype=complex) ell += ell1.reshape((2*N1,1)) ell += 1j * ell2 F_fft = fftpack.fft2(F,(2*N1,2*N2) ) F_fft *= func( ell ) out = fftpack.ifft2(F_fft) return out[:N1,:N2]
def gamma_to_kappa(shear,dt1,dt2=None): """ simple application of Kaiser-Squires (1995) kernel in fourier space to convert complex shear to complex convergence: imaginary part of convergence is B-mode. """ if not dt2: dt2 = dt1 N1,N2 = shear.shape #convert angles from arcminutes to radians dt1 = dt1 * numpy.pi / 180. / 60. dt2 = dt2 * numpy.pi / 180. / 60. #compute k values corresponding to field size dk1 = numpy.pi / N1 / dt1 dk2 = numpy.pi / N2 / dt2 k1 = fftpack.ifftshift( dk1 * (numpy.arange(2*N1)-N1) ) k2 = fftpack.ifftshift( dk2 * (numpy.arange(2*N2)-N2) ) ipart,rpart = numpy.meshgrid(k2,k1) k = rpart + 1j*ipart #compute (inverse) Kaiser-Squires kernel on this grid fourier_map = numpy.conj( KS_kernel(-k) ) #compute Fourier transform of the shear gamma_fft = fftpack.fft2( shear, (2*N1,2*N2) ) kappa_fft = fourier_map * gamma_fft kappa = fftpack.ifft2(kappa_fft)[:N1,:N2] return kappa
def test_definition(self): x = [0,1,2,3,4,-4,-3,-2,-1] y = [-4,-3,-2,-1,0,1,2,3,4] assert_array_almost_equal(fftshift(x),y) assert_array_almost_equal(ifftshift(y),x) x = [0,1,2,3,4,-5,-4,-3,-2,-1] y = [-5,-4,-3,-2,-1,0,1,2,3,4] assert_array_almost_equal(fftshift(x),y) assert_array_almost_equal(ifftshift(y),x)
def preWhitenCube(**kwargs): ''' Pre-whitenening using noise estimates from a cube taken from the difference map. Returns a the pre-whitened volume and various spectra. (Alp Kucukelbir, 2013) ''' print '\n= Pre-whitening the Cubes' tStart = time() n = kwargs.get('n', 0) vxSize = kwargs.get('vxSize', 0) elbowAngstrom = kwargs.get('elbowAngstrom', 0) rampWeight = kwargs.get('rampWeight',1.0) dataF = kwargs.get('dataF', 0) dataBGF = kwargs.get('dataBGF', 0) dataBGSpect = kwargs.get('dataBGSpect', 0) epsilon = 1e-10 pWfilter = createPreWhiteningFilter(n = n, spectrum = dataBGSpect, elbowAngstrom = elbowAngstrom, rampWeight = rampWeight, vxSize = vxSize) # Apply the pre-whitening filter to the inside cube dataF = np.multiply(pWfilter['pWfilter'],dataF) dataPWFabs = np.abs(dataF) dataPWFabs = dataPWFabs-np.min(dataPWFabs) dataPWFabs = dataPWFabs/np.max(dataPWFabs) dataPWSpect = sphericalAverage(dataPWFabs**2) + epsilon dataPW = np.real(fftpack.ifftn(fftpack.ifftshift(dataF))) del dataF # Apply the pre-whitening filter to the outside cube dataBGF = np.multiply(pWfilter['pWfilter'],dataBGF) dataPWBGFabs = np.abs(dataBGF) dataPWBGFabs = dataPWBGFabs-np.min(dataPWBGFabs) dataPWBGFabs = dataPWBGFabs/np.max(dataPWBGFabs) dataPWBGSpect = sphericalAverage(dataPWBGFabs**2) + epsilon dataBGPW = np.real(fftpack.ifftn(fftpack.ifftshift(dataBGF))) del dataBGF m, s = divmod(time() - tStart, 60) print " :: Time elapsed: %d minutes and %.2f seconds" % (m, s) return {'dataPW':dataPW, 'dataBGPW':dataBGPW, 'dataPWSpect': dataPWSpect, 'dataPWBGSpect': dataPWBGSpect, 'peval': pWfilter['peval'], 'pcoef': pWfilter['pcoef'] }
def filtergrid(rows, cols): # Set up u1 and u2 matrices with ranges normalised to +/- 0.5 u1, u2 = np.meshgrid(np.linspace(-0.5, 0.5, cols, endpoint=(cols % 2)), np.linspace(-0.5, 0.5, rows, endpoint=(rows % 2)), sparse=True) # Quadrant shift to put 0 frequency at the top left corner u1 = ifftshift(u1) u2 = ifftshift(u2) # Compute frequency values as a radius from centre (but quadrant shifted) radius = np.sqrt(u1 * u1 + u2 * u2) return radius, u1, u2
def Afunc(self, f): fs = reshape(f, (self.height, self.width, self.depth)) F = fftn(fs) d_1 = ifftshift(ifftn(F*self.H)); d_e = ifftshift(ifftn(F*self.He)); d_e2 = ifftshift(ifftn(F*self.He2)); d = (1.5*real(d_1) + 2*real(d_e*self.e1) + 0.5*real(d_e2*self.e2)) d = real(d); return ravel(d)
def Ahfunc(self, f): fs = reshape(f, (self.height, self.width, self.depth)) F = fftn(fs) d_1 = ifftshift(ifftn(F*self.Ht)); d_e = ifftshift(ifftn(F*self.Het)); d_e2 = ifftshift(ifftn(F*self.He2t)); d = (1.5*d_1 + 2*real(d_e*exp(1j*self.alpha)) + 0.5*real(d_e2*exp(2*1j*self.alpha))); d = real(d); return ravel(d)
def plot_pulse(A_t,A_w,t,w, l0 = 1550 * nm, t_zoom = ps, l_zoom = 10*nm): ## Fix maximum if 'A_max' not in plot_pulse.__dict__: plot_pulse.A_max = amax(A_t) plot_pulse.A_w_max = amax(A_w) w0 = 2 * pi * C_SPEED / l0 ## Plot Time domain fig = pl.gcf() fig.add_subplot(211) pl.plot(t / t_zoom, absolute(A_t/plot_pulse.A_max), hold = False) pl.axis([amin(t) / t_zoom*0.4,amax(t) / t_zoom*0.4, 0, 1.1]) pl.xlabel(r'$time\ (%s s)$'%units[t_zoom]) atten_win = 0.01 npoints = len(w) apod = arange(npoints) apod = exp(-apod/(npoints*atten_win)) + exp(-(npoints-apod)/(npoints*atten_win)) apod = ifftshift(apod) ## Plot Freq domain fig.add_subplot(212) pl.plot((2 * pi * C_SPEED)/(w+w0)/nm, log10(absolute(A_w)**2/absolute(plot_pulse.A_w_max)**2) * 10, hold=False) #pl.plot((2 * pi * C_SPEED)/(w+w0) / Q_('um'), log10(absolute(apod)**2/absolute(amax(apod))**2 ) *10, hold=True) #pl.semilogy() pl.axis([(l0-l_zoom)/Q_('um'), (l0+l_zoom)/nm, -60, 5]) pl.xlabel(r'$wavelength\ (\mu m)$') pl.ylabel(r'$spectrum (db)$') pl.show()
def invertPsd1d(self, psdx=None, psd1d=None, phasespec=None, seed=None): """Convert a 1d PSD, generate a phase spectrum (or use user-supplied values) into a 2d PSD (psd2dI).""" # Converting the 2d PSD into a 1d PSD is a lossy process, and then there is additional randomness # added when the phase spectrum is not the same as the original phase spectrum, so this may or may not # look that much like the original image (unless you keep the phases, doesn't look like image). # 'Swing' the 1d PSD across the whole fov. if psd1d == None: psd1d = self.psd1d xr = self.rfreq / self.xfreqscale else: if psdx == None: xr = numpy.arange(0, len(psd1d), 1.0) # Resample into even bins (definitely necessarily if using psd1d). xrange = numpy.arange(0, numpy.sqrt(self.xcen**2 + self.ycen**2)+1.0, 1.0) psd1d = numpy.interp(xrange, xr, psd1d, right=psd1d[len(psd1d)-1]) # Calculate radii - distance from center. rad = numpy.hypot((self.yy-self.ycen), (self.xx-self.xcen)) # Calculate the PSD2D from the 1d value. self.psd2dI = numpy.interp(rad.flatten(), xrange, psd1d) self.psd2dI = self.psd2dI.reshape(self.ny, self.nx) if phasespec == None: self._makeRandomPhases(seed=seed) else: self.phasespecI = phasespec if not(self.shift): # The 1d PSD is centered, so the 2d PSD will be 'shifted' here. self.psd2dI = fftpack.ifftshift(self.psd2dI) return
def deconv(self, data, lamb, clip = False): '''This is what you actually call to do the deconvolution. parameters are: data - the raw data lamb - the regularisation parameter ''' #test to see if we need to recalculate filter factor if not lamb == self.lamb: self.WF = self.Ht/(self.H2 + lamb**2) self._r[:] = data #F = fftn(fs) #d = ifftshift(ifftn(F*self.H)); self._plan_r_F() self._F *= self.WF #self._F /= (self.H2 + lamb**2) self._plan_F_r() res = ifftshift(self._r) if clip: res = numpy.maximum(res, 0) return res
def make_white(var): im_scale_shift=var['im_scale_shift'] im2_list=[] im_count=len(var['im']) w = Waitbar(True) for count,im in enumerate(var['im']): yf=fftshift(fft2(im*im_scale_shift[0]+im_scale_shift[1])) fl=1.0/absolute(yf) yffl=yf*fl; im2=real(ifft2(ifftshift(yffl))) im2=im2/im2.std() im2=im2-im2.mean() if count==0: print "Whiten." im2_list.append(im2) w.update((count+1)/float(im_count)) print w, sys.stdout.flush() print var2={'im':im2_list,'im_scale_shift':[1.0,0.0]} return var2
def pdf(self): """ Applies the 3D FFT in the q-space grid to generate the DSI diffusion propagator, remove the background noise with a hard threshold and then deconvolve the propagator with the Lucy-Richardson deconvolution algorithm """ values = self.data #create the signal volume Sq = np.zeros((self.qgrid_sz, self.qgrid_sz, self.qgrid_sz)) #fill q-space for i in range(self.dn): qx, qy, qz = self.model.qgrid[i] Sq[qx, qy, qz] += values[i] #get deconvolution PSF DSID_PSF = self.model.cache_get('deconv_psf', key=self.model.gtab) if DSID_PSF is None: DSID_PSF = gen_PSF(self.model.qgrid, self.qgrid_sz, self.qgrid_sz, self.qgrid_sz) self.model.cache_set('deconv_psf', self.model.gtab, DSID_PSF) #apply fourier transform Pr = fftshift(np.abs(np.real(fftn(ifftshift(Sq), 3 * (self.qgrid_sz, ))))) #threshold propagator Pr = threshold_propagator(Pr) #apply LR deconvolution Pr = LR_deconv(Pr, DSID_PSF, 5, 2) return Pr
def __FilterData2D(self,data): #lowpass filter to suppress noise #a = ndimage.gaussian_filter(data.astype('f'), self.filterRadiusLowpass) a = ifftshift(ifftn((fftn(data.astype('f'))*cachedOTFH)*(self.lamb**2 + cachedOTF2.mean())/(self.lamb**2 + cachedOTF2))).real #lowpass filter again to find background b = ndimage.gaussian_filter(a, self.filterRadiusHighpass) return 24*(a - b)
def test5(): global L0, N L = deepcopy(L0) rho = zeros(N, 'double') rho[0] = 1. rho[N/2] = 1. print rho print fft(rho) rho = fftshift(fft(rho)) print "fft(rho) =", rho L = fft(L).T L = fft(L).T L = fftshift(L) #print L x = linalg.solve(L, rho) print "x =", x #x[abs(x)<0.001] = 0 x = ifftshift(ifft(x)).real * N print "ifft(x) =", x F = [] for i in xrange(len(x)-1): F.append(x[i+1] - x[i]) print "F =", F print "--------------------------------"
def vortex_beam_by_fourier(r, theta, Q, w0): ''' Spiral phase plate with vorticity Q Calculated by Fourier transform - not exact r and theta must be square ''' # The original function F0 = N.exp(-r ** 2 / w0 ** 2 + 1.0j * Q * theta) oldsize = F0.shape[0] # Pad it with large amounts of zeros padding = N.zeros_like(F0) inarray = N.vstack(( N.hstack((padding, padding, padding)), N.hstack((padding, F0, padding)), N.hstack((padding, padding, padding)) )) insize = inarray.shape[0] # Do the Fourier transform FF = fftpack.fftshift(fftpack.fft2(fftpack.ifftshift(inarray))) FF = FF[int((insize - oldsize) / 2):int((insize + oldsize) / 2), int((insize - oldsize) / 2):int((insize + oldsize) / 2)] del F0 return FF
def whiten(self, smooth=None, apply_filter=None): """ Apply spectral whitening to data. """ logging.info("Whitening {:} traces...", len(self.traces)) for tr in self.traces: mask = np.ma.getmask(tr.data) N = len(tr.data) nfft = nextpow2(N) spec = fft(tr.data, nfft) df = tr.stats['sampling_rate'] spec_ampl = np.sqrt(np.abs(np.multiply(spec, np.conjugate(spec)))) if isinstance(smooth, basestring) and isnumber(smooth) and\ (smooth > 0): smooth = int(smooth * N / df) spec /= ifftshift(smooth_func(fftshift(spec_ampl), smooth)) else: spec /= spec_ampl if apply_filter is not None: spec *= bandpass_response(*apply_filter, sr=df, N=len(spec), whole=True)[1] ret = np.real(ifft(spec, nfft)[:N]) tr.data = fill_array(ret, mask=mask, fill_value=0.)
def invertPsd2d(self, useI=False, usePhasespec=True, seed=None): """Convert the 2d PSD and phase spec into an FFT image (FftI). """ # The PHASEs of the FFT are encoded in the phasespec ('where things are') # The AMPLITUDE of the FFT is encoded in the PSD ('how bright things are' .. also radial scale) # amp = sqrt(| R(uv)^2 + I(u,v)^2|) == length of 'z' (z = x + iy, in fourier image) # phase = arctan(y/x) if useI: psd2d = self.psd2dI phasespec = self.phasespecI else: psd2d = self.psd2d phasespec = self.phasespec if self.shift: amp = numpy.sqrt(fftpack.ifftshift(psd2d)) else: amp = numpy.sqrt(psd2d) # Can override using own phasespec for random (if coming in here to use 2d PSD for image) if not(usePhasespec): self._makeRandomPhases(seed=seed) phasespec = self.phasespecI # Shift doesn't matter for phases, because 'unshifted' it above, before calculating phase. x = numpy.cos(phasespec) * amp y = numpy.sin(phasespec) * amp self.fimageI = x + 1j*y if self.shift: self.fimageI = fftpack.fftshift(self.fimageI) return
def MakePulseDataRepLPC(pulse,spec,N,rep1,numtype = sp.complex128): """ This will make data by assuming the data is an autoregressive process. Inputs spec - The properly weighted spectrum. N - The size of the ar process used to model the filter. pulse - The pulse shape. rep1 - The number of repeats of the process. Outputs outdata - A numpy Array with the shape of the """ lp = len(pulse) lenspec = len(spec) r1 = scfft.ifft(scfft.ifftshift(spec)) rp1 = r1[:N] rp2 = r1[1:N+1] # Use Levinson recursion to find the coefs for the data xr1 = sp.linalg.solve_toeplitz(rp1, rp2) lpc = sp.r_[sp.ones(1), -xr1] # The Gain term. G = sp.sqrt(sp.sum(sp.conjugate(r1[:N+1])*lpc)) Gvec = sp.r_[G, sp.zeros(N)] Npnt = (N+1)*3+lp # Create the noise vector and normalize xin = sp.random.randn(rep1, Npnt)+1j*sp.random.randn(rep1, Npnt) xinsum = sp.tile(sp.sqrt(sp.mean(xin.real**2+xin.imag**2, axis=1))[:, sp.newaxis],(1, Npnt)) xin = xin/xinsum outdata = sp.signal.lfilter(Gvec, lpc, xin, axis=1) outpulse = sp.tile(pulse[sp.newaxis], (rep1, 1)) outdata = outpulse*outdata[:, 2*N:2*N+lp] return outdata
def _FFT_raw_fired(self): fft_shift = fft.fft2(Data.TrA_Data) Data.FFT = fft.ifftshift(fft_shift) plt.figure() plt.contourf(np.log(np.abs(Data.FFT)**2),cmap=plt.cm.Greys_r) plt.title('FFT of raw') plt.show()
def psf_calc(self, psf, kz, data_size): '''Pre calculate OTFs etc ...''' g = psf; self.height = data_size[0] self.width = data_size[1] self.depth = data_size[2] (x,y,z) = mgrid[-floor(self.height/2.0):(ceil(self.height/2.0)), -floor(self.width/2.0):(ceil(self.width/2.0)), -floor(self.depth/2.0):(ceil(self.depth/2.0))] gs = shape(g); g = g[int(floor((gs[0] - self.height)/2)):int(self.height + floor((gs[0] - self.height)/2)), int(floor((gs[1] - self.width)/2)):int(self.width + floor((gs[1] - self.width)/2)), int(floor((gs[2] - self.depth)/2)):int(self.depth + floor((gs[2] - self.depth)/2))] g = abs(ifftshift(ifftn(abs(fftn(g))))); g = (g/sum(sum(sum(g)))); self.g = g; self.H = cast['f'](fftn(g)); self.Ht = cast['f'](ifftn(g)); tk = 2*kz*z t = g*exp(1j*tk) self.He = cast['F'](fftn(t)); self.Het = cast['F'](ifftn(t)); tk = 2*tk t = g*exp(1j*tk) self.He2 = cast['F'](fftn(t)); self.He2t = cast['F'](ifftn(t));
def spectralWhitening(data, sr=None, smoothi=None, freq_domain=False, apply_filter=None): """ Apply spectral whitening to data. sr: sampling rate (only needed for smoothing) smoothi: None or int Data is divided by its smoothed (Default: None) amplitude spectrum. """ if freq_domain: mask = False spec = data else: mask = np.ma.getmask(data) N = len(data) nfft = nextpow2(N) spec = fft(data, nfft) #df = sr/N spec_ampl = np.sqrt(np.abs(np.multiply(spec, np.conjugate(spec)))) if isinstance(smoothi, basestring) and isnumber(smoothi) and smoothi > 0: smoothi = int(smoothi * N / sr) spec /= ifftshift(smooth(fftshift(spec_ampl), smoothi)) else: spec /= spec_ampl if apply_filter is not None: spec *= filterResp(*apply_filter, sr=sr, N=len(spec), whole=True)[1] if freq_domain: return spec else: ret = np.real(ifft(spec, nfft)[:N]) if USE_FFTW3: ret = ret.copy() return fillArray(ret, mask=mask, fill_value=0.)
def wiener(data, impulse_response=None, filter_params={}, K=0.25, predefined_filter=None): """Minimum Mean Square Error (Wiener) inverse filter. Parameters ---------- data : (M,N) ndarray Input data. K : float or (M,N) ndarray Ratio between power spectrum of noise and undegraded image. impulse_response : callable `f(r, c, **filter_params)` Impulse response of the filter. See LPIFilter2D.__init__. filter_params : dict Additional keyword parameters to the impulse_response function. Other Parameters ---------------- predefined_filter : LPIFilter2D If you need to apply the same filter multiple times over different images, construct the LPIFilter2D and specify it here. """ if predefined_filter is None: filt = LPIFilter2D(impulse_response, **filter_params) else: filt = predefined_filter F, G = filt._prepare(data) _min_limit(F) H_mag_sqr = np.abs(F)**2 F = 1 / F * H_mag_sqr / (H_mag_sqr + K) return _centre(np.abs(ifftshift(np.dual.ifftn(G * F))), data.shape)
def initialize_time_freq(self): if self.thread_initialize_tfr is not None or self.is_computing.any(): # needd to come back later ... if not self.timer_back_initialize.isActive(): self.timer_back_initialize.start() return # create self.params_time_freq p = self.params_time_freq = { } for param in self.paramTimeFreq.children(): self.params_time_freq[param.name()] = param.value() # we take sampling_rate = f_stop*4 or (original sampling_rate) if p['f_stop']*4 < self.global_sampling_rate: p['sampling_rate'] = p['f_stop']*4 else: p['sampling_rate'] = self.global_sampling_rate self.factor = p['sampling_rate']/self.global_sampling_rate # this compensate unddersampling in FFT. self.xsize2 = self.xsize self.len_wavelet = int(self.xsize2*p['sampling_rate']) self.win = fftpack.ifftshift(np.hamming(self.len_wavelet)) self.thread_initialize_tfr = ThreadInitializeWavelet(len_wavelet = self.len_wavelet, params_time_freq = p, parent = self ) self.thread_initialize_tfr.finished.connect(self.initialize_tfr_done) self.thread_initialize_tfr.start()
def ifft2(arrayin): """Calculate the 2d inverse fourier transform of an array with N/2 as the zero-pixel.""" # do an fft arrayout = np.array(arrayin,dtype=complex) arrayout = fftpack.fftshift(arrayout) arrayout = fftpack.ifft2(arrayout) arrayout = fftpack.ifftshift(arrayout) return arrayout
def fIFFT2D(data, shift=True): ''' Performs a two-dimensional inverse fast Fourier transform (IFFT). Input data : input two-dimensional data to transform; can be a list or an array shift : if True, re-positions the zero-frequency components to the lower-left corner Output data_ifft : two-dimensional IFFT ''' if isinstance(data, list) == True: # if input data is a list, convert to array data = np.array(data) if shift == True: data = fftpack.ifftshift(data) data_ifft = fftpack.ifft2(data) return data_ifft
def pdf(self, normalized=True): """ Applies the 3D FFT in the q-space grid to generate the diffusion propagator """ values = self.data * self.model.filter # create the signal volume Sq = np.zeros((self.qgrid_sz, self.qgrid_sz, self.qgrid_sz)) # fill q-space for i in range(len(values)): qx, qy, qz = self.model.qgrid[i] Sq[qx, qy, qz] += values[i] # apply fourier transform Pr = fftshift(np.real(fftn(ifftshift(Sq), 3 * (self.qgrid_sz, )))) # clipping negative values to 0 (ringing artefact) Pr = np.clip(Pr, 0, Pr.max()) # normalize the propagator to obtain a pdf if normalized: Pr /= Pr.sum() return Pr
def inverse(data, impulse_response=None, filter_params={}, max_gain=2, predefined_filter=None): """Apply the filter in reverse to the given data. Parameters ---------- data : (M,N) ndarray Input data. impulse_response : callable `f(r, c, **filter_params)` Impulse response of the filter. See LPIFilter2D.__init__. filter_params : dict Additional keyword parameters to the impulse_response function. max_gain : float Limit the filter gain. Often, the filter contains zeros, which would cause the inverse filter to have infinite gain. High gain causes amplification of artefacts, so a conservative limit is recommended. Other Parameters ---------------- predefined_filter : LPIFilter2D If you need to apply the same filter multiple times over different images, construct the LPIFilter2D and specify it here. """ assert_nD(data, 2, 'data') if predefined_filter is None: filt = LPIFilter2D(impulse_response, **filter_params) else: filt = predefined_filter F, G = filt._prepare(data) _min_limit(F) F = 1 / F mask = np.abs(F) > max_gain F[mask] = np.sign(F[mask]) * max_gain return _centre(np.abs(ifftshift(np.dual.ifftn(G * F))), data.shape)
def ifrt_complex(bins, N, norm=True, center=False, projNumber=0, Isum=-1, mValues=None): ''' Compute the inverse DRT in O(n logn) complexity using the discrete Fourier slice theorem and the FFT. Input should be DRT projections (bins) to recover an NxN image, where N is prime. projNumber is the number of non-zero projections in bins. This useful for backprojecting mu projections where mu < N. Isum is computed from first row if -1, otherwise provided value is used ''' if Isum < 0: Isum = bins[0, :].sum() # print "ISUM:", Isum dftSpace = np.zeros((N, N), dtype=np.complex) #Set slices (0 <= m <= N) for k, row in enumerate(bins): #iterate per row if mValues and k not in mValues: continue slice = fftpack.fft(row) radon.setSlice(k, dftSpace, slice) # print "filter:", filter dftSpace[0, 0] -= float(Isum) * N #iFFT 2D image result = fftpack.ifft2(dftSpace) if not norm: result *= N #ifft2 already divides by N**2 if center: result = fftpack.ifftshift(result) return result
def RemCurt(im, wt, wd, stfolder, sfn, fname, prev, ext): H, W = im.shape fft2 = fftpack.fft2(im) #fft of img of the stack fft2sh = fftpack.fftshift(fft2) #shifted fft of img of the stack fft2shcorr = copy.copy(fft2sh) # calculation of the corrected FFT modulus of img, comment if using the simpler version of the filter for i in range(W): if abs(W / 2 - i) > wd: for k in range(2 * wt + 1): if abs(fft2sh[int(H / 2 - wt / 2 + k), i]) != 0: fft2shcorr[int(H / 2 - wt / 2 + k), i] = 0 # fft2shcorrArr.append(fft2shcorr) ifft2shcorr = fftpack.ifftshift(fft2shcorr) ifft2corr = fftpack.ifft2(ifft2shcorr) CorrImg = abs(ifft2corr) # fft2shArr.append(fft2sh) if prev == 'N': save_tif(stfolder, sfn, fname, misc.toimage(255 * CorrImg, cmin=0, cmax=255), ext) # print(j) return CorrImg
def performZOGY(im1, im2, im1_psf, im2_psf, sig1=None, sig2=None): from scipy.fftpack import fft2, ifft2, ifftshift if sig1 is None: _, sig1 = computeClippedImageStats(im1) if sig2 is None: _, sig2 = computeClippedImageStats(im2) F_r = F_n = 1. R_hat = fft2(im1) N_hat = fft2(im2) P_r = im1_psf P_n = im2_psf P_r_hat = fft2(P_r) P_n_hat = fft2(P_n) d_hat_numerator = (F_r * P_r_hat * N_hat - F_n * P_n_hat * R_hat) d_hat_denom = np.sqrt((sig1**2 * F_r**2 * np.abs(P_r_hat)**2) + (sig2**2 * F_n**2 * np.abs(P_n_hat)**2)) d_hat = d_hat_numerator / d_hat_denom d = ifft2(d_hat) D = ifftshift(d.real) return D
def fourier(f, A): """Approximate the Fourier transform of f truncated on [-A,A] using the discrete Fourier transform. Args: f -- target function evaluated at -A+2A*k/N, k=0..N-1, N should be even. A -- truncation level. Returns: freqs -- an array of N frequencies. F -- the array of corresponding approximate values of the Fourier transform. """ N = len(f) if not int(N/2) == N/2: raise("N should be even") B = A/2/np.pi F = spf.fft(spf.ifftshift(f)) F = spf.fftshift(F) # shift F to align indices and [-A,A] freqs = np.arange(-N/2,N/2)/(2*B) F *= 2*A/N F /= np.sqrt(2*np.pi) # arbitrary normalization return freqs, F
def _slp_filter(phase, cutoff, rows, cols, x_size, y_size, params): """ Function to perform spatial low pass filter """ cx = np.floor(cols / 2) cy = np.floor(rows / 2) # fft for the input image imf = fftshift(fft2(phase)) # calculate distance distfact = 1.0e3 # to convert into meters [xx, yy] = np.meshgrid(range(cols), range(rows)) xx = (xx - cx) * x_size # these are in meters as x_size in meters yy = (yy - cy) * y_size dist = np.sqrt(xx**2 + yy**2) / distfact # km if params[cf.SLPF_METHOD] == 1: # butterworth low pass filter H = 1. / (1 + ((dist / cutoff)**(2 * params[cf.SLPF_ORDER]))) else: # Gaussian low pass filter H = np.exp(-(dist**2) / (2 * cutoff**2)) outf = imf * H out = np.real(ifft2(ifftshift(outf))) out[np.isnan(phase)] = np.nan return out # out is units of phase, i.e. mm
def freqHighPass(img, r): """ Applies an High Pass filter to img in the frequency domain. In: img, image to filter r, percentage of spectrum to keep (in [0 1]) Out: ifiltered, filtered version of the image P, filtered spectrum """ I = fftpack.fftshift(fftpack.fft2(img)) # entering to frequency domain # fftshift moves zero-frequency component # to the center of the array P = np.zeros(I.shape, dtype=complex) r = int((r * min(img.shape)) / 2) c1 = I.shape[0] / 2 # spectrum center c2 = I.shape[1] / 2 for i in range(c1 - r, c1 + r): # frequency cutting for j in range(c2 - r, c2 + r): # around the center P[i, j] = I[i, j] ifiltered = np.real(fftpack.ifft2(fftpack.ifftshift(P))) return ifiltered, P # back to the spatial domain
def initialize_time_freq(self, threaded=True): #~ print 'initialize_time_freq', threaded if threaded: if self.thread_initialize_tfr is not None or self.is_computing.any( ): # needd to come back later ... if not self.timer_back_initialize.isActive(): self.timer_back_initialize.start() return # create self.params_time_freq p = self.params_time_freq = {} for param in self.paramTimeFreq.children(): self.params_time_freq[param.name()] = param.value() # we take sampling_rate = f_stop*4 or (original sampling_rate) if p['f_stop'] * 4 < self.global_sampling_rate: p['sampling_rate'] = p['f_stop'] * 4 else: p['sampling_rate'] = self.global_sampling_rate self.factor = p[ 'sampling_rate'] / self.global_sampling_rate # this compensate unddersampling in FFT. self.xsize2 = self.xsize self.len_wavelet = int(self.xsize2 * p['sampling_rate']) self.win = fftpack.ifftshift(np.hamming(self.len_wavelet)) if threaded: self.thread_initialize_tfr = ThreadInitializeWavelet( len_wavelet=self.len_wavelet, params_time_freq=p, parent=self) self.thread_initialize_tfr.finished.connect( self.initialize_tfr_done) self.thread_initialize_tfr.start() else: self.wf = generate_wavelet_fourier(len_wavelet=self.len_wavelet, **self.params_time_freq) self.initialize_plots()
def remove_frequency_ring(image, radius1, radius2, multicolor=True): image = image.astype(np.float32) if multicolor: imager = image[:, :, 0] imageg = image[:, :, 1] imageb = image[:, :, 2] imager_res = remove_frequency_ring(imager, radius1, radius2, multicolor=False) imageg_res = remove_frequency_ring(imageg, radius1, radius2, multicolor=False) imageb_res = remove_frequency_ring(imageb, radius1, radius2, multicolor=False) return np.stack([imager_res, imageg_res, imageb_res], axis=-1) rows, cols = image.shape[0:2] crow, ccol = int(rows / 2), int(cols / 2) mask = get_mask(image, radius1, radius2) mask[crow][ccol] = 1 freq = cv2.dft(image, flags=cv2.DFT_COMPLEX_OUTPUT) freq = fftpack.fftshift(freq) freq[:, :, 0] = freq[:, :, 0] * mask freq[:, :, 1] = freq[:, :, 1] * mask freq = fftpack.ifftshift(freq) distorted = cv2.idft(freq, flags=cv2.DFT_SCALE + cv2.DFT_COMPLEX_INPUT) final = distorted[:, :, 0] return final
def generate_kspace_etomo_2D(sinogram): """ This function generates the list of the kspace observations (with zero-padding). Parameters ---------- sinogram: np.ndarray((q, m)) sinogram with size nb_angles and size_x (m) Returns ------- kspace_obs: np.ndarray((q*int(m*sqrt(2))) Fourier space values from the given sinogram """ nb_angles, size_x = sinogram.shape diag_x = int(np.floor(np.sqrt(2) * size_x)) jmin = int(np.floor((np.floor(np.sqrt(2) * size_x) - size_x) / 2)) jmax = -int(np.ceil((np.floor(np.sqrt(2) * size_x) - size_x) / 2)) sinograms_zp = np.zeros((nb_angles, diag_x)) sinograms_zp[:, jmin:jmax] = sinogram # nb_angles, size_x = sinogram.shape # diag_x = int(np.floor(np.sqrt(2) * size_x)) # sinograms_zp = np.zeros((nb_angles, diag_x)) # sinograms_zp[:, (diag_x - size_x) / 2):-int( # np.ceil((np.floor(np.sqrt(2) * size_x) - size_x) / 2))] = sinogram ft_sinogram = [] for t in range(sinogram.shape[0]): ft_sinogram.append( pfft.fftshift( pfft.fft(pfft.ifftshift( sinograms_zp[t].astype("complex128"))))) ft_sinogram = np.asarray(ft_sinogram).flatten() kspace_obs = ft_sinogram.flatten() return kspace_obs
def fft_in_image(filename): ''' @Description: 观察图片中像素值随着x、y轴的空间变化频率 ''' image = io.imread(filename) M, N = image.shape print('shape of the image: {}, dtype: {}'.format(image.shape, image.dtype)) F = fftpack.fftn(image) F_magnitude = np.abs(F) F_magnitude = fftpack.fftshift(F_magnitude) fig, axes = plt.subplots(2, 2, figsize=(8, 7)) # left upper axes[0][0].imshow(image) axes[0][0].set_title('Original image') # left lower axes[1][0].imshow(np.log(1 + F_magnitude), cmap='viridis', extent=(-N // 2, N // 2, -M // 2, M // 2)) axes[1][0].set_title('Spectrum magnitude') # right upper, 将频谱中心的一块儿归零,当做过滤高频噪声,同时过滤高于98%分位的峰值 K = 40 F_magnitude[M // 2 - K:M // 2 + K, N // 2 - K:N // 2 + K] = 0 peaks = F_magnitude < np.percentile(F_magnitude, 98) peaks = fftpack.ifftshift(peaks) F_magnitude_dim = F.copy() F_magnitude_dim = F_magnitude_dim * peaks.astype(int) # 执行反向傅里叶变换还原图像 image_filtered = np.real(fftpack.ifftn(F_magnitude_dim)) axes[0][1].imshow(np.log10(1 + np.abs(F_magnitude_dim)), cmap='viridis') axes[0][1].set_title('Spectrum after suppression') # right lower axes[1][1].imshow(image_filtered) axes[1][1].set_title('Reconstructed image') # save image fig.suptitle('result of fft filter for image reconstruct') plt.savefig('./4_6_result_of_fft_filter.png')
def invertAcovf2d(self, useI=False, usePhasespec=True, seed=None): """Convert the 2d ACovF into a 2d PSD (psd2dI). """ if useI: acovf = self.acovfI else: acovf = self.acovf self.phasespecI = self.phasespec # Let user override phasespec if want to use real 2d ACovF but random phases. if not (usePhasespec): self._makeRandomPhases(seed=seed) # Calculate the 2dPSD from the ACovF. # Note that if the ACovF has values reaching all the way to the edges, this will # induce noise into the PSD2d (just as the discontinuity would induce noise into the FFT of an image). if self.shift: self.psd2dI = fftpack.ifftshift( fftpack.fft2(fftpack.fftshift(acovf))) else: self.psd2dI = fftpack.fft2(acovf) # PSD2d should be entirely real and positive (PSD2d = |R(uv,)**2 + I(u,v)**2| #print 'PSD real limits', self.psd2dI.real.min(), self.psd2dI.real.max() #print 'PSD imaginary limits', self.psd2dI.imag.min(), self.psd2dI.imag.max() # Okay, I admit - this next line is a bit of a hack, but it does seem to work. self.psd2dI = numpy.sqrt(numpy.abs(self.psd2dI)**2) return
def fs_to_rs(wfin, return_mf=False, mesh_in=None): """ Transform from Fourier-space into Real-space. This function acts on cube-functions and returns cube functions. """ assert (isinstance(wfin.mesh, Cube)) cube = wfin.mesh out = ifft(ifftshift(wfin)) if cube.dim == 1: # out = out * np.sqrt(wfin.size*(np.pi)) out *= np.sqrt(wfin.mesh.np * np.pi / 2) else: raise Exception("Not implemented") out = MeshFunction(out, mesh=cube) if return_mf: mesh = mesh_in if (mesh_in != None) else cube.mesh out = cube_to_mesh(out, mesh) return out
def psf_calc(self, psf, kz, data_size): """Pre calculate OTFs etc ...""" g = psf; self.height = data_size[0] self.width = data_size[1] self.depth = data_size[2] (x, y, z) = np.mgrid[-floor(self.height / 2.0):(ceil(self.height / 2.0)), -floor(self.width / 2.0):(ceil(self.width / 2.0)), -floor(self.depth / 2.0):(ceil(self.depth / 2.0))] gs = np.shape(g) g = g[int(floor((gs[0] - self.height) / 2)):int(self.height + floor((gs[0] - self.height) / 2)), int(floor((gs[1] - self.width) / 2)):int(self.width + floor((gs[1] - self.width) / 2)), int(floor((gs[2] - self.depth) / 2)):int(self.depth + floor((gs[2] - self.depth) / 2))] g = abs(ifftshift(ifftn(abs(fftn(g))))) g = (g / sum(sum(sum(g)))) self.g = g; self.H = fftn(g).astype('f') self.Ht = ifftn(g).astype('f') tk = 2 * kz * z t = g * exp(1j * tk) self.He = cast['F'](fftn(t)); self.Het = cast['F'](ifftn(t)); tk = 2 * tk t = g * exp(1j * tk) self.He2 = cast['F'](fftn(t)); self.He2t = cast['F'](ifftn(t));
def spect2acf(omeg, spec, n=None): """ Creates acf and time array associated with the given frequency vector and spectrum Inputs: omeg: The frequency sampling vector spec: The spectrum array. n: optional, default len(spec), Length of output spectrum Output: tau: The time sampling array. acf: The acf from the original spectrum.""" if n is None: n = float(spec.shape[-1]) # padnum = sp.floor(len(spec)/2) df = omeg[1] - omeg[0] # specpadd = sp.pad(spec,(padnum,padnum),mode='constant',constant_values=(0.0,0.0)) acf = scfft.fftshift(scfft.ifft(scfft.ifftshift(spec, axes=-1), n, axis=-1), axes=-1) acf = acf / n dt = 1 / (df * n) tau = sp.arange(-sp.ceil(n / 2.), sp.floor(n / 2.) + 1) * dt return tau, acf
def DarkField(ComplexField, CutOff): """ Processing darkfield images from tomographic acquisitions Parameters ---------- ComplexField : complex128 Reconstructed complex refractive index distribution. CutOff : int Cut-off frequency of the darkfield filter (assumed to be a circulat mask). Returns ------- Field : complex128 Darkfield filtered refractive index distribution. """ Spectrum = fftshift(fftn(ComplexField)) kx, ky, kz = np.meshgrid(np.arange(-int(Spectrum.shape[1]/2), int(Spectrum.shape[1]/2)), np.arange(-int(Spectrum.shape[0]/2), int(Spectrum.shape[0]/2)), np.arange(-int(Spectrum.shape[2]/2), int(Spectrum.shape[2]/2))) Spectrum[kx**2 + ky**2 + kz**2 < CutOff**2] = 0 Field = ifftn(ifftshift(Spectrum)) return Field
def spectral_whitening(data, sr=None, smooth=None, filter=None, waterlevel=1e-8): """ Apply spectral whitening to data Data is divided by its smoothed (Default: None) amplitude spectrum. :param data: numpy array with data to manipulate :param sr: sampling rate (only needed for smoothing) :param smooth: length of smoothing window in Hz (default None -> no smoothing) :param filter: filter spectrum with bandpass after whitening (tuple with min and max frequency) :param waterlevel: waterlevel relative to mean of spectrum :return: whitened data """ data = _fill_array(data, fill_value=0.) mask = np.ma.getmask(data) nfft = next_fast_len(len(data)) spec = fft(data, nfft) spec_ampl = np.abs(spec) spec_ampl /= np.max(spec_ampl) if smooth: smooth = int(smooth * nfft / sr) spec_ampl = ifftshift(smooth_func(fftshift(spec_ampl), smooth)) # save guard against division by 0 spec_ampl[spec_ampl < waterlevel] = waterlevel spec /= spec_ampl if filter is not None: spec *= _filter_resp(*filter, sr=sr, N=len(spec), whole=True)[1] ret = np.real(ifft(spec, nfft)[:len(data)]) return _fill_array(ret, mask=mask, fill_value=0.)
def propagate(self, F, z): """ Propagate a complex pupil, F, a distance z from the nominal focus and return the electric field amplitude Parameters ========== F : 2D array complex pupil z : float distance in nm to propagate """ pf = self.propFac*float(z) r = max(self.appR*(1 -self.apertureZGrad*z), 0) M = (self.x*self.x + self.y*self.y) < (r*r) fs = F*M*self.pfm*(np.cos(pf) + j*np.sin(pf)) self._F[:] = fftshift(fs) self._plan_F_f() return ifftshift(self._f/np.sqrt(self._f.size))
def __min_component_filter(x, y, feature_mask, p=1, fcut=None, Q=None): ############################################################################### """ Minimum component filtering Minimum component filtering is useful for determining the background component of a signal in the presence of spikes Parameters x : array_like 1D array of evenly spaced x values y : array_like 1D array of y values corresponding to x feature_mask : array_like, same size as x & y 1D mask array giving the locations of features in the data which should be ignored for smoothing p : integer (optional) polynomial degree to be used for the fit (default = 1) fcut : float (optional) the cutoff frequency for the low-pass filter. Default value is f_nyq / sqrt(N) Q : float (optional) the strength of the low-pass filter. Larger Q means a steeper cutoff default value is 0.1 * fcut Returns y_filtered : ndarray The filtered version of y. Notes This code follows the procedure explained in the book "Practical Statistics for Astronomers" by Wall & Jenkins book, as well as in Wall, J, A&A 122:371, 1997 """ import numpy as np from scipy import fftpack x = np.asarray(x, dtype=float) y = np.asarray(y, dtype=float) feature_mask = np.asarray(feature_mask, dtype=bool) if ((x.ndim != 1) or (x.shape != y.shape) or (y.shape != feature_mask.shape)): raise ValueError('x, y, and feature_mask must be 1 dimensional ' 'with matching lengths') if fcut is None: f_nyquist = 1. / (x[1] - x[0]) fcut = f_nyquist / np.sqrt(len(x)) if Q is None: Q = 0.1 * fcut # compute polynomial features XX = x[:, None]**np.arange(p + 1) # compute least-squares fit to non-masked data beta = np.linalg.lstsq(XX[~feature_mask], y[~feature_mask])[0] # subtract polynomial fit and mask the data y_mask = y - np.dot(XX, beta) y_mask[feature_mask] = 0 # get Fourier transforms of arrays yFT_mask = fftpack.fft(y_mask) # compute (shifted) frequency array for filter N = len(x) f = fftpack.ifftshift((np.arange(N) - N / 2.) * 1. / N / (x[1] - x[0])) # construct low-pass filter filt = np.exp(-(Q * (abs(f) - fcut) / fcut)**2) filt[abs(f) < fcut] = 1 # reconstruct filtered signal y_filtered = fftpack.ifft(yFT_mask * filt).real + np.dot(XX, beta) return y_filtered
origin='lower', cmap='viridis', interpolation='nearest') plt.title(r"Simulated RE $\tilde{E}(\tau,f_D)$", color='white') ax = plt.gca() ax.set_xticks(xticks) ax.set_xticklabels(xtickslabels) ax.set_yticks(yticks) ax.set_yticklabels(ytickslabels) #ax.tick_params(axis='x', colors='white') #ax.tick_params(axis='y', colors='white') cbar = plt.colorbar() #cbar.ax.tick_params(axis='y', colors='white') retrieved = ifft2(ifftshift(retrieved)) * retrieved.size e = ifft2(ifftshift(e)) * e.size plt.subplot(2, 3, 3) plt.imshow(np.angle(retrieved), extent=extent, origin='lower', cmap='viridis', interpolation='nearest') plt.title(r"Retrieved Phase ${E}(f,\nu)$", color='white') ax = plt.gca() ax.set_xticks(xticks) ax.set_xticklabels(xtickslabels) ax.set_yticks(yticks) ax.set_yticklabels(ytickslabels)
dimHolo / 2)] # Specular spot coordinates calculation ind = np.unravel_index(np.argmax(np.abs(SpectreFilt)**2, axis=None), SpectreFilt.shape) kiy = ind[0] kix = ind[1] # Coordinate writting fidCentrestxt.write(f"{kiy} {kix}\n") # Position of the center for further monitoring Centres[kiy, kix] = 1 # Complex Field (UBorn + Ui) UBorn = ifft2(ifftshift(SpectreFilt)) Amp_UBorn = np.abs(UBorn) Phase_UBornWrap = np.angle(UBorn) # Phase unwrapping Phase_UBorn = holo.unwrapping(Phase_UBornWrap, M.PIX) # Amplitude correction Amp_UBornC = CAber.ampliCorr(Amp_UBorn, Masque, Poly_US, Poly) Amp_UBornC[Amp_UBornC <= -5] = 1 Amp_UBornC[Amp_UBornC >= 5] = 1 # Phase correction Phase_UBornC = CAber.aberCorr(Phase_UBorn, Masque, Poly_US, Poly) # Field calculation
if "setup_text_plots" not in globals(): from astroML.plotting import setup_text_plots setup_text_plots(fontsize=8, usetex=True) #------------------------------------------------------------ # Create the noisy data np.random.seed(5) N = 2000 dt = 0.05 t = dt * np.arange(N) h = np.exp(-0.5 * ((t - 20.) / 1.0)**2) hN = h + np.random.normal(0, 0.5, size=h.shape) Df = 1. / N / dt f = fftpack.ifftshift(Df * (np.arange(N) - N / 2)) HN = fftpack.fft(hN) #------------------------------------------------------------ # Set up the Wiener filter: # fit a model to the PSD consisting of the sum of a # gaussian and white noise h_smooth, PSD, P_S, P_N, Phi = wiener_filter(t, hN, return_PSDs=True) #------------------------------------------------------------ # Use the Savitzky-Golay filter to filter the values h_sg = savitzky_golay(hN, window_size=201, order=4, use_fft=False) #------------------------------------------------------------ # Plot the results N = len(t)
def deconvolve(star, psf): star_fft = fftpack.fftshift(fftpack.fftn(star)) psf_fft = fftpack.fftshift(fftpack.fftn(psf)) return fftpack.fftshift(fftpack.ifftn(fftpack.ifftshift(star_fft/psf_fft)))
ia=0 ja=0 m=copia[0][0] #convierte los 4 puntos mas brillantes despues del maximo en 0 frecuencias[ii[1],jj[1]]=0 frecuencias[ii[2],jj[2]]=0 frecuencias[ii[3],jj[3]]=0 frecuencias[ii[4],jj[4]]=0 #Crea una matriz donde se guardara el resultado nueva = np.ones((l,c)).astype(complex) #Se multiplica uno a uno para volver solo esos cuatro puntos 0 for i in range(l): for j in range(c): nueva[i,j]=ArbolesFFT2[i,j]*frecuencias[i,j] #Halla de nuevo la imagen nueva2=f.ifft2(f.ifftshift(nueva)) plt.imshow(abs(nueva),cmap = 'gray') plt.title("Transformada de Fourier Filtrada") plt.savefig("GualdronTonny_FT2D_filtrada.pdf") plt.close() #verifica que las posiciones de los 4 puntos ruidos sean 0 if(nueva[ii[1],jj[1]]==0 and nueva[ii[2],jj[2]]==0 and nueva[ii[3],jj[3]]==0 and nueva[ii[4],jj[4]]==0): plt.imshow(abs(nueva2),cmap = 'gray') plt.title("Imagen Final") plt.savefig("GualdronTonny_Imagen_filtrada.pdf") plt.close() else: print("No se pudo eliminar el ruido")
def fitcheck(repall=[100]): x_0 = sp.array([[[1.00000000e+11, 2.00000000e+03], [1.00000000e+11, 2.00000000e+03]], [[5.00000000e+11, 2.00000000e+03], [5.00000000e+11, 2.00000000e+03]], [[1.00000000e+11, 3.00000000e+03], [1.00000000e+11, 2.00000000e+03]], [[1.00000000e+11, 2.00000000e+03], [1.00000000e+11, 3.00000000e+03]]]) sns.set_style("whitegrid") sns.set_context("notebook") x_0_red = x_0[0].flatten() x_0_red[-2] = x_0_red[-1] x_0_red[-1] = 0. configfile = 'statsbase.ini' (sensdict, simparams) = readconfigfile(configfile) ambdict = simparams['amb_dict'] pulse = simparams['Pulse'] l_p = len(pulse) Nlags = l_p lagv = sp.arange(l_p) ntypes = x_0.shape[0] nspec = 128 nrg = 64 des_pnt = 16 ISpec = ISRSpectrum(nspec=nspec, sampfreq=50e3) species = ['O+', 'e-'] spvtime = sp.zeros((ntypes, nspec)) lablist = ['Normal', 'E-Ne', 'E-Ti', 'E-Te'] v_i = 0 fitfunc = ISRSfitfunction sumrule = simparams['SUMRULE'] Nrg1 = nrg + 1 - l_p minrg = -sumrule[0].min() maxrg = Nrg1 - sumrule[1].max() Nrg2 = maxrg - minrg for i in range(ntypes): f, curspec, rcs = ISpec.getspecsep(x_0[i], species, v_i, rcsflag=True) specsum = sp.absolute(curspec).sum() spvtime[i] = rcs * curspec * nspec**2 / specsum acforig = scfft.ifft(scfft.ifftshift(spvtime, axes=1), axis=1) / nspec acfamb = sp.dot(ambdict['WttMatrix'], scfft.fftshift(acforig, axes=1).transpose()).transpose() specamb = scfft.fftshift(scfft.fft(acfamb, n=nspec, axis=1), axes=1) fig, axmat = plt.subplots(2, 2) axvec = axmat.flatten() figs, axmats = plt.subplots(2, 2) axvecs = axmats.flatten() for i in range(ntypes): ax = axvec[i] ax.plot(lagv, acfamb[i].real, label='Input') ax.set_title(lablist[i]) axs = axvecs[i] axs.plot(f * 1e-3, specamb[i].real, label='Input', linewidth=4) axs.set_title(lablist[i]) for irep, rep1 in enumerate(repall): rawdata = sp.zeros((ntypes, rep1, nrg), dtype=sp.complex128) acfest = sp.zeros((ntypes, Nrg1, l_p), dtype=rawdata.dtype) acfestsr = sp.zeros((ntypes, Nrg2, l_p), dtype=rawdata.dtype) specest = sp.zeros((ntypes, nspec), dtype=rawdata.dtype) for i in range(ntypes): for j in range(nrg - (l_p - 1)): rawdata[i, :, j:j + l_p] = MakePulseDataRepLPC( pulse, spvtime[i], 20, rep1) + rawdata[i, :, j:j + l_p] acfest[i] = CenteredLagProduct(rawdata[i], pulse=pulse) / (rep1) for irngnew, irng in enumerate(sp.arange(minrg, maxrg)): for ilag in range(Nlags): acfestsr[i][irngnew, ilag] = acfest[i][irng + sumrule[0, ilag]:irng + sumrule[1, ilag] + 1, ilag].mean(axis=0) ax = axvec[i] ax.plot(lagv, acfestsr[i, des_pnt].real / l_p, label='Np = {0}'.format(rep1)) if irep == len(repall) - 1: ax.legend() specest[i] = scfft.fftshift( scfft.fft(acfestsr[i, des_pnt], n=nspec)) axs = axvecs[i] axs.plot(f * 1e-3, specest[i].real / l_p, label='Np = {0}'.format(rep1), linewidth=4) if irep == len(repall) - 1: axs.legend() print('Parameters fitted after {0} pulses'.format(rep1)) print('Ni Ti Te Vi') for i in range(ntypes): d_func = (acfestsr[i, des_pnt] / l_p, sensdict, simparams) (x, cov_x, infodict, mesg, ier) = scipy.optimize.leastsq(func=fitfunc, x0=x_0_red, args=d_func, full_output=True) print(x) print(' ') fig.suptitle('ACF with Sum Rule') fig.savefig('pulsetestacf.png', dpi=400) plt.close(fig) figs.suptitle('Spectrum Full Array') figs.savefig('pulsetestspec.png', dpi=400) plt.close(figs)
def __init__(self): gr.top_block.__init__(self, "Multipath Psk") Qt.QWidget.__init__(self) self.setWindowTitle("Multipath Psk") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "multipath_psk") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.tap4 = tap4 = 0.6 self.tap3 = tap3 = 0.6 self.tap2 = tap2 = 0.5 self.tap1 = tap1 = 0.25 self.taps = taps = fftpack.ifftshift( fftpack.ifft([ tap3, tap4, 1.0, tap1, tap2, tap3, tap4, 1.0, tap1, tap2, tap3, tap4, 1.0, tap1, tap2 ])) self.sps = sps = 8 self.samp_rate = samp_rate = 32000 self.const = const = digital.constellation_16qam().base() self.cma = cma = -20 ################################################## # Blocks ################################################## self._tap4_range = Range(0, 1, 0.01, 0.6, 200) self._tap4_win = RangeWidget(self._tap4_range, self.set_tap4, "tap4", "slider", float) self.top_grid_layout.addWidget(self._tap4_win, 1, 3, 1, 1) self._tap3_range = Range(0, 1, 0.01, 0.6, 200) self._tap3_win = RangeWidget(self._tap3_range, self.set_tap3, "tap3", "slider", float) self.top_grid_layout.addWidget(self._tap3_win, 1, 2, 1, 1) self._tap2_range = Range(0, 1, 0.01, 0.5, 200) self._tap2_win = RangeWidget(self._tap2_range, self.set_tap2, "tap2", "slider", float) self.top_grid_layout.addWidget(self._tap2_win, 1, 1, 1, 1) self._tap1_range = Range(0, 1, 0.01, 0.25, 200) self._tap1_win = RangeWidget(self._tap1_range, self.set_tap1, "tap1", "slider", float) self.top_grid_layout.addWidget(self._tap1_win, 1, 0, 1, 1) self.root_raised_cosine_filter_0 = filter.fir_filter_ccf( 1, firdes.root_raised_cosine(1.0, sps * 1.0, 1.0, 0.35, 22 * sps)) self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 4096, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate, #bw "", #name 1 #number of inputs ) self.qtgui_freq_sink_x_0.set_update_time(0.10) self.qtgui_freq_sink_x_0.set_y_axis(-100, 0) self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB') self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") self.qtgui_freq_sink_x_0.enable_autoscale(False) self.qtgui_freq_sink_x_0.enable_grid(False) self.qtgui_freq_sink_x_0.set_fft_average(1.0) self.qtgui_freq_sink_x_0.enable_axis_labels(True) self.qtgui_freq_sink_x_0.enable_control_panel(False) if not True: self.qtgui_freq_sink_x_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_freq_sink_x_0.set_plot_pos_half(not True) labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "dark blue" ] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_freq_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_0_win = sip.wrapinstance( self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win, 0, 0, 1, 2) self.qtgui_const_sink_x_0 = qtgui.const_sink_c( 1024, #size "", #name 1 #number of inputs ) self.qtgui_const_sink_x_0.set_update_time(0.10) self.qtgui_const_sink_x_0.set_y_axis(-2, 2) self.qtgui_const_sink_x_0.set_x_axis(-2, 2) self.qtgui_const_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "") self.qtgui_const_sink_x_0.enable_autoscale(False) self.qtgui_const_sink_x_0.enable_grid(False) self.qtgui_const_sink_x_0.enable_axis_labels(True) if not True: self.qtgui_const_sink_x_0.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "red", "red", "red", "red", "red", "red", "red", "red" ] styles = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] markers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_const_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_const_sink_x_0.set_line_label(i, labels[i]) self.qtgui_const_sink_x_0.set_line_width(i, widths[i]) self.qtgui_const_sink_x_0.set_line_color(i, colors[i]) self.qtgui_const_sink_x_0.set_line_style(i, styles[i]) self.qtgui_const_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_const_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_const_sink_x_0_win = sip.wrapinstance( self.qtgui_const_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_const_sink_x_0_win, 0, 2, 1, 2) self.digital_constellation_modulator_0 = digital.generic_mod( constellation=const, differential=True, samples_per_symbol=sps, pre_diff_code=True, excess_bw=0.35, verbose=False, log=False, ) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_cc( sps * (1 + 0.0), 0.25 * 0.01 * 0.01, 0.5, 0.01, 0.005) self._cma_range = Range(-40, -10, 1, -20, 200) self._cma_win = RangeWidget(self._cma_range, self.set_cma, "cma", "counter_slider", float) self.top_grid_layout.addWidget(self._cma_win, 2, 0, 1, 4) self.channels_channel_model_0 = channels.channel_model( noise_voltage=0.01, frequency_offset=0.0, epsilon=1.0, taps=(1, ), noise_seed=0, block_tags=False) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex * 1, samp_rate, True) self.analog_random_source_x_0 = blocks.vector_source_b( map(int, numpy.random.randint(0, 256, 1000000)), True) ################################################## # Connections ################################################## self.connect((self.analog_random_source_x_0, 0), (self.digital_constellation_modulator_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.qtgui_freq_sink_x_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.root_raised_cosine_filter_0, 0)) self.connect((self.channels_channel_model_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.qtgui_const_sink_x_0, 0)) self.connect((self.digital_constellation_modulator_0, 0), (self.channels_channel_model_0, 0)) self.connect((self.root_raised_cosine_filter_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))