Exemplo n.º 1
0
def compare_interpolated_spectrum():
    fig = plt.figure(figsize=(8, 8))
    ax = fig.add_subplot(111)

    out = fft(ifftshift(f_full))
    freqs = fftfreq(len(f_full), d=0.01) # spacing, Ang
    sfreqs = fftshift(freqs)
    taper = gauss_taper(freqs, sigma=0.0496) #Ang, corresponds to 2.89 km/s at 5150A.
    tout = out * taper

    ax.plot(sfreqs, fftshift(tout))

    wl_h, fl_h = np.abs(np.load("PH6.8kms_0.01ang.npy"))
    wl_l, fl_l = np.abs(np.load("PH2.5kms.npy"))

    #end edges
    wl_he = wl_h[200:-200]
    fl_he = fl_h[200:-200]
    interp = Sinc_w(wl_l, fl_l, a=5, window='kaiser')
    fl_hi = interp(wl_he)

    d = wl_he[1] - wl_he[0]
    out = fft(ifftshift(fl_hi))
    freqs = fftfreq(len(out), d=d)
    ax.plot(fftshift(freqs), fftshift(out))

    plt.show()
Exemplo n.º 2
0
def FFT_Correlation(x,y):
    """
    FFT-based correlation, much faster than numpy autocorr.
    x and y are row-based vectors of arbitrary lengths.
    This is a vectorized implementation of O(N*log(N)) flops.
    """

    lengthx = x.shape[0]
    lengthy = y.shape[0]

    x = np.reshape(x,(1,lengthx))
    y = np.reshape(y,(1,lengthy))

    length = np.array([lengthx, lengthy]).min()
    
    x = x[:length]
    y = y[:length]
    
    fftx = fft(x, 2 * length - 1, axis=1) #pad with zeros
    ffty = fft(y, 2 * length - 1, axis=1)

    corr_xy = fft.ifft(fftx * np.conjugate(ffty), axis=1)
    corr_xy = np.real(fft.fftshift(corr_xy, axes=1)) #should be no imaginary part

    corr_yx = fft.ifft(ffty * np.conjugate(fftx), axis=1)
    corr_yx = np.real(fft.fftshift(corr_yx, axes=1))

    corr = 0.5 * (corr_xy[:,length:] + corr_yx[:,length:]) / range(1,length)[::-1]
    return np.reshape(corr,corr.shape[1])
Exemplo n.º 3
0
def B_ell(flat_map, component, bin_size, window=None):
    """
    Return the binned beam function of the given flat map component,
    using ell bins of bin_size. If a window name is given, multiply
    the map component by the window function before taking the 2-D
    DFT.

    The returned beam function is the absolute value of the DFT, so it
    has the same units as the map component. The returned bins array
    contains the left edges of the bins corresponding to the returned
    data: for all i in range(bins.size),
    bins[i] <= data[i] < bins[i+1]
    """
    ell_x, ell_y= np.meshgrid(fftshift(fftfreq(flat_map.x.size, flat_map.dx()/(2*np.pi))),
                              fftshift(fftfreq(flat_map.y.size, flat_map.dy()/(2*np.pi))))
    ell_x = ell_x.T
    ell_y = ell_y.T
    ell_r = np.sqrt(ell_x**2 + ell_y**2)
    ell_bins = np.arange(0, np.max(ell_r), bin_size)
    beam = flat_map[component]
    if window is not None:
        beam *= get_window(window, flat_map.y.size)
        beam *= get_window(window, flat_map.x.size)[:, np.newaxis]
    dft = fftshift(fft2(beam))
    # Shift the indices down by 1 so that they correspond to the data
    # indices. These indices should always be valid indices for the
    # DFT data because r_ell has a lower bound at 0 and max(r_ell)
    # will have index ell_bins.size.
    bin_indices = np.digitize(ell_r.flatten(), ell_bins) - 1
    binned = np.zeros(ell_bins.size) # dtype?
    for i in range(binned.size):
        binned[i] = np.sqrt(np.mean(abs(dft.flatten()[i==bin_indices])**2))
    return ell_bins, binned, dft
Exemplo n.º 4
0
 def test_axes_keyword(self):
     freqs = [[ 0,  1,  2], [ 3,  4, -4], [-3, -2, -1]]
     shifted = [[-1, -3, -2], [ 2,  0,  1], [-4,  3,  4]]
     assert_array_almost_equal(fftshift(freqs, axes=(0, 1)), shifted)
     assert_array_almost_equal(fftshift(freqs, axes=0), fftshift(freqs, axes=(0,)))
     assert_array_almost_equal(ifftshift(shifted, axes=(0, 1)), freqs)
     assert_array_almost_equal(ifftshift(shifted, axes=0), ifftshift(shifted, axes=(0,)))
Exemplo n.º 5
0
def sph_fft(x, y):
  dx = x[1] - x[0]
  q = fft.fftshift(fft.fftfreq(len(x), dx)) * 2 * np.pi
  f = -(4*np.pi)*fft.fftshift(np.imag(fft.fft(y*dx * x)))
  f /= q
  f[q == 0] = np.trapz(4*np.pi*y*x**2, x)
  return q, f
Exemplo n.º 6
0
def convFFT(x,y):
    nx=len(x)
    xf=np.pad(x,(nx/2,nx/2),mode='constant')
    yf=np.pad(y,(nx/2,nx/2),mode='constant')
    xf=(fft.fft(fft.fftshift(xf)))
    yf=(fft.fft(fft.fftshift(yf)))
    return fft.fftshift(np.real((fft.ifft(xf*yf))))[nx/2:3*nx/2]
Exemplo n.º 7
0
def get_spectrum_1d(data_reg,x_reg,y_reg):
    """Compute the 1d power spectrum.
    """
    # remove the mean and squarize
    data_reg-=data_reg.mean()
    jpj,jpi = data_reg.shape
    msize = min(jpj,jpi)
    data_reg = data_reg[:msize-1,:msize-1]
    x_reg = x_reg[:msize-1,:msize-1]
    y_reg = y_reg[:msize-1,:msize-1]
    # wavenumber vector
    x1dreg,y1dreg = x_reg[0,:],y_reg[:,0]
    Ni,Nj = msize-1,msize-1
    dx=npy.int(npy.ceil(x1dreg[1]-x1dreg[0]))
    k_max  = npy.pi / dx
    kx = fft.fftshift(fft.fftfreq(Ni, d=1./(2.*k_max)))
    ky = fft.fftshift(fft.fftfreq(Nj, d=1./(2.*k_max)))
    kkx, kky = npy.meshgrid( ky, kx )
    Kh = npy.sqrt(kkx**2 + kky**2)
    Nmin  = min(Ni,Nj)
    leng  = Nmin/2+1
    kstep = npy.zeros(leng)
    kstep[0] =  k_max / Nmin
    for ind in range(1, leng):
        kstep[ind] = kstep[ind-1] + 2*k_max/Nmin
    norm_factor = 1./( (Nj*Ni)**2 )
    # tukey windowing = tapered cosine window
    cff_tukey = 0.25
    yw=npy.linspace(0, 1, Nj)
    wdw_j = npy.ones(yw.shape)
    xw=npy.linspace(0, 1, Ni)
    wdw_i= npy.ones(xw.shape)
    first_conditioni = xw<cff_tukey/2
    first_conditionj = yw<cff_tukey/2
    wdw_i[first_conditioni] = 0.5 * (1 + npy.cos(2*npy.pi/cff_tukey * (xw[first_conditioni] - cff_tukey/2) ))
    wdw_j[first_conditionj] = 0.5 * (1 + npy.cos(2*npy.pi/cff_tukey * (yw[first_conditionj] - cff_tukey/2) ))
    third_conditioni = xw>=(1 - cff_tukey/2)
    third_conditionj = yw>=(1 - cff_tukey/2)
    wdw_i[third_conditioni] = 0.5 * (1 + npy.cos(2*npy.pi/cff_tukey * (xw[third_conditioni] - 1 + cff_tukey/2)))
    wdw_j[third_conditionj] = 0.5 * (1 + npy.cos(2*npy.pi/cff_tukey * (yw[third_conditionj] - 1 + cff_tukey/2)))
    wdw_ii, wdw_jj = npy.meshgrid(wdw_j, wdw_i, sparse=True)
    wdw = wdw_ii * wdw_jj
    data_reg*=wdw
    #2D spectrum
    cff  = norm_factor
    tempconj=fft.fft2(data_reg).conj()
    tempamp=cff * npy.real(tempconj*fft.fft2(data_reg))
    spec_2d=fft.fftshift(tempamp)
    #1D spectrum
    leng    = len(kstep)
    spec_1d = npy.zeros(leng)
    krange     = Kh <= kstep[0]
    spec_1d[0] = spec_2d[krange].sum()
    for ind in range(1, leng):
        krange = (kstep[ind-1] < Kh) & (Kh <= kstep[ind])
        spec_1d[ind] = spec_2d[krange].sum()
    spec_1d[0] /= kstep[0]
    for ind in range(1, leng):
        spec_1d[ind] /= kstep[ind]-kstep[ind-1]
    return spec_1d, kstep
Exemplo n.º 8
0
def gen_wedge_psf(nx, ny, nf, dx, dy, df, z, out, threads=None):
    u = fftshift(fftfreq(nx, dx * np.pi / 180))
    v = fftshift(fftfreq(ny, dy * np.pi / 180))
    e = fftshift(fftfreq(nf, df))

    E = np.sqrt(Cosmo.Om0 * (1 + z) ** 3 +
                Cosmo.Ok0 * (1 + z) ** 2 + Cosmo.Ode0)
    D = Cosmo.comoving_transverse_distance(z).value
    H0 = Cosmo.H0.value * 1e3
    c = const.c.value
    print(E, D, H0)
    kx = u * 2 * np.pi / D
    ky = v * 2 * np.pi / D
    k_perp = np.sqrt(kx ** 2 + ky[np.newaxis, ...].T ** 2)
    k_par = e * 2 * np.pi * H0 * f21 * E / (c * (1 + z) ** 2)
    arr = np.ones((nf, nx, ny), dtype='complex128')
    for i in range(nf):
        mask = (k_perp > np.abs(k_par[i]) * c * (1 + z) / (H0 * E * D))
        arr[i][mask] = 0
    np.save('kx.npy', kx)
    np.save('ky.npy', ky)
    np.save('kpar.npy', k_par)
    np.save('wedge_window.npy', arr.real)
    fft_arr = fftshift(fftn(ifftshift(arr))).real
    hdu = fits.PrimaryHDU(data=fft_arr)
    hdr_dict = dict(cdelt1=dx, cdelt2=dy, cdelt3=df,
                    crpix1=nx/2, crpix2=ny/2, crpix3=nf/2,
                    crval1=0, crval2=0, crval3=0,
                    ctype1='RA---SIN', ctype2='DEC--SIN', ctype3='FREQ',
                    cunit1='deg', cunit2='deg', cunit3='Hz')
    for k, v in hdr_dict.items():
        hdu.header[k] = v
    hdu.writeto(out, clobber=True)
Exemplo n.º 9
0
def fft_2D(R, convert=3e-5, freq_bounds=None):
    """
    Perform a 2D FFT to transform a 3rd order response function defined in the
    rotating frame into a series of 2D spectra.

    First argument must be a MetaArray object wth ticks and rw_freq defined.

    Returns the FFT in another MetaArray object with ticks updated to the
    calculated frequencies (converted using the convert argument which defaults
    to cm to fs).
    """

    # reverses frequency order to keep convention e^{+i \omega t}
    R_2D = fftshift(fft2(ifftshift(R, axes=(0, 2)), axes=(0, 2)),
                    axes=(0, 2))[::-1, :, ::-1]

    dt = [t[1] - t[0] for t in R.ticks]

    freqs = [fftshift(fftfreq(R.shape[axis], dt[axis] * convert))
             + R.rw_freq for axis in (0, 2)]

    if freq_bounds is not None:
        bounds = [bound_indices(ticks, freq_bounds) for ticks in freqs]
        freqs = [freq[bound[0]:bound[1]] for freq, bound in zip(freqs, bounds)]
        R_2D = R_2D[bounds[0][0]:bounds[0][1], :, bounds[1][0]:bounds[1][1]]

    return MetaArray(R_2D, ticks=(freqs[0], R.ticks[1], freqs[1]))
Exemplo n.º 10
0
def delayTransformVisibilities(visList,df,kernel=None,wind='Blackman-Harris'):
    '''
     ARGS:
     visList: nfreqxnvis complex matrix of visibilities
     df: float indicating channel width
     RETURNS:
     ndelayxnvis grid of delay-transformed visibilities
    '''
    nf=visList.shape[0]
    if kernel is None:
        kernel=np.ones(nf)

    nv=visList.shape[1]
    windowGrid=np.zeros_like(visList)
    if wind=='Blackman-Harris':
        window=signal.blackmanharris(nf)
    elif wind=='Nithya':
        window=signal.blackmanharris(nf/2)
        window=signal.fftconvolve(window,window,mode='full')
        window=np.append(window,window[-1])
    window/=window.max()
    window/=np.sqrt(np.mean(np.abs(kernel*window)**2.)) 
    for vNum in range(nv):
        windowGrid[:,vNum]=window*kernel
    return df*fft.fftshift(fft.fft(fft.fftshift(visList*windowGrid,axes=[0]),axis=0),axes=[0])
Exemplo n.º 11
0
def create_matching_kernel(source_psf, target_psf, window=None):
    """
    Create a kernel to match 2D point spread functions (PSF) using the
    ratio of Fourier transforms.

    Parameters
    ----------
    source_psf : 2D `~numpy.ndarray`
        The source PSF.  The source PSF should have higher resolution
        (i.e. narrower) than the target PSF.  ``source_psf`` and
        ``target_psf`` must have the same shape and pixel scale.

    target_psf : 2D `~numpy.ndarray`
        The target PSF.  The target PSF should have lower resolution
        (i.e. broader) than the source PSF.  ``source_psf`` and
        ``target_psf`` must have the same shape and pixel scale.

    window : callable, optional
        The window (or taper) function or callable class instance used
        to remove high frequency noise from the PSF matching kernel.
        Some examples include:

        * `~photutils.psf.matching.HanningWindow`
        * `~photutils.psf.matching.TukeyWindow`
        * `~photutils.psf.matching.CosineBellWindow`
        * `~photutils.psf.matching.SplitCosineBellWindow`
        * `~photutils.psf.matching.TopHatWindow`

        For more information on window functions and example usage, see
        :ref:`psf_matching`.

    Returns
    -------
    kernel : 2D `~numpy.ndarray`
        The matching kernel to go from ``source_psf`` to ``target_psf``.
        The output matching kernel is normalized such that it sums to 1.
    """

    # inputs are copied so that they are not changed when normalizing
    source_psf = np.copy(np.asanyarray(source_psf))
    target_psf = np.copy(np.asanyarray(target_psf))

    if source_psf.shape != target_psf.shape:
        raise ValueError('source_psf and target_psf must have the same shape '
                         '(i.e. registered with the same pixel scale).')

    # ensure input PSFs are normalized
    source_psf /= source_psf.sum()
    target_psf /= target_psf.sum()

    source_otf = fftshift(fft2(source_psf))
    target_otf = fftshift(fft2(target_psf))
    ratio = target_otf / source_otf

    # apply a window function in frequency space
    if window is not None:
        ratio *= window(target_psf.shape)

    kernel = np.real(fftshift((ifft2(ifftshift(ratio)))))
    return kernel / kernel.sum()
Exemplo n.º 12
0
	def abs_fft(self, points=None, zoom=None,write = 'off'):
		"""
		Fourier transforms the timesignal;
		points is the number of points to transform, if more points given than data points
		the rest is zero padded
	
		absfft(points=4096)
		"""
		realdata = N.array(self.the_result.y[0])
		imdata = N.array(self.the_result.y[1])
		data = realdata + 1j*imdata
		fftdata = F.fftshift(F.fft(data, points))
		absfft = N.sqrt(fftdata.real**2 + fftdata.imag**2)
		# create our x axis
		n = fftdata.size
		self.the_result.x = F.fftshift(F.fftfreq(n, 1.0/self.sampling_rate))
		self.the_result.y[0] = absfft
		self.the_result.y[1] = N.zeros(n)
		if write == 'on':
			return self
		else:
			if zoom is None:
				return self.the_result
			else:
				center, width = zoom
				return self.zoom(self.the_result, center, width)
Exemplo n.º 13
0
def frp_to_fir(frp, fbins=None):
    '''Transform a fringe rate profile to a fir filter.'''
    frp = ifftshift(frp,axes=-1)
    fir = ifft(frp, axis=-1)
    fir = fftshift(fir, axes=-1)
    if fbins is not None: return fir, fftshift(fftfreq(fbins.size, fbins[1] - fbins[0]))
    else: return fir
Exemplo n.º 14
0
    def compute(self, scene: Scene):
        """ Compute optical irradiance map
        Computation proccedure:
            1) convert radiance to irradiance
            2) apply lens and macular transmittance
            3) apply off-axis fall-off (cos4th)
            4) apply optical transfert function

        Args:
            scene (pyEyeBall.Scene): instance of Scene class, containing the radiance and other scene information

        Examples:
            >>> oi = Optics()
            >>> oi.compute(Scene())
        """
        # set field of view and wavelength samples
        self.fov = scene.fov
        scene.wave = self._wave
        self.dist = scene.dist

        # compute irradiance
        self.photons = pi / (1 + 4 * self.f_number**2 * (1 + abs(self.magnification))**2) * scene.photons

        # apply ocular transmittance
        self.photons *= self.ocular_transmittance

        # apply the relative illuminant (off-axis) fall-off: cos4th function
        x, y = self.spatial_support
        s_factor = np.sqrt(self.image_distance**2 + x**2 + y**2)
        self.photons *= (self.image_distance / s_factor[:, :, None])**4

        # apply optical transfer function of the optics
        for ii in range(self.wave.size):
            otf = fftshift(self.otf(self._wave[ii], self.frequency_support_x, self.frequency_support_y))
            self.photons[:, :, ii] = np.abs(ifftshift(ifft2(otf * fft2(fftshift(self.photons[:, :, ii])))))
Exemplo n.º 15
0
 def plot(self, title, truth=None):
     kwargs = {"interpolation": "nearest",
               "origin": "lower",
               "cmap": "afmhot",
               "vmin": 0.0,
               "vmax": np.max(self.get_real_image())}
     if truth is not None:
         plt.subplot(2,2,3)
         plt.imshow(truth, **kwargs)
         plt.title("truth")
     plt.subplot(2,2,1)
     plt.imshow(self.get_real_image(), **kwargs)
     plt.title("{title}: scores {s1:.1f} {s2:.1f}".format(title=title,
                                                          s1=self.get_score_L1(),
                                                          s2=self.get_score_L2()))
     kwargs["vmin"] = np.log(np.percentile(self.get_data(), 1.))
     kwargs["vmax"] = np.log(np.percentile(self.get_data(), 99.))
     plt.subplot(2,2,4)
     data = np.log(self.get_data().copy())
     data[np.where(self.get_ivar() <= 0)] = kwargs["vmin"]
     plt.imshow(fftshift(data, axes=0), **kwargs)
     plt.title("data")
     plt.subplot(2,2,2)
     plt.title(title)
     plt.imshow(np.log(fftshift(self.get_squared_norm_ft_image(), axes=0)), **kwargs)
Exemplo n.º 16
0
def compacf(acfall,noiseall,Nr,dns,bstride,ti,tInd):
    bstride=bstride.squeeze()
    assert bstride.size==1 #TODO

    Nlag = acfall.shape[2]
    acf  =      zeros((Nr,Nlag),complex64) #NOT empty, note complex64 is single complex float
    spec =      empty((Nr,2*Nlag-1),complex128)
    try:
        acf_noise = zeros((noiseall.shape[3],Nlag),complex64)
        spec_noise= zeros(2*Nlag-1,complex128)
    except AttributeError:
        acf_noise = None
        spec_noise= 0.

    for i in range(tInd[ti]-1,tInd[ti]+1):
        acf += (acfall[i,bstride,:,:,0] + 1j*acfall[i,bstride,:,:,1]).T
        if acf_noise is not None: #must be is not None
            acf_noise += (noiseall[i,bstride,:,:,0] + 1j*noiseall[i,bstride,:,:,1]).T

    acf = acf/dns/(i-(tInd[ti]-1)+1) #NOT /=
    if acf_noise is not None: #must be is not None
        acf_noise = acf_noise/dns / (i-(tInd[ti]-1)+1)
#%% spectrum noise
    if acf_noise is not None:
        for i in range(Nlag):
            spec_noise += fftshift(fft(append(conj(acf_noise[i,1:][::-1]),acf_noise[i,:])))


        spec_noise = spec_noise / Nlag
#%% spectrum from ACF
    for i in range(Nr):
        spec[i,:] = fftshift(fft(append(conj(acf[i,1:][::-1]), acf[i,:])))-spec_noise


    return spec,acf
Exemplo n.º 17
0
def acf2psd(acfall,noiseall,Nr,dns):
    """
    acf all:  Nlag x Nslantrange x real/comp

    """
    assert acfall.ndim in (3,2)

    Nlag = acfall.shape[0]
    spec = empty((Nr,2*Nlag-1),complex128)

    if acfall.ndim == 3: # last dim real,cplx
        acf = (acfall[...,0] + 1j*acfall[...,1]).T / dns / 2.
    elif acfall.ndim == 2 and iscomplex(acfall[0,0]):
        acf = acfall / dns / 2.
    else:
        raise TypeError('is this really ACF? I expect complex 2-D matrix')

    try:
        acf_noise = (noiseall[...,0] + 1j*noiseall[...,1]).T / dns / 2.
    except TypeError:
        acf_noise= None
        spec_noise= 0.
#%% spectrum noise
    if acf_noise is not None:
        spec_noise = zeros(2*Nlag-1,complex128)
        for i in range(Nlag):
            spec_noise += fftshift(fft(append(conj(acf_noise[i,1:][::-1]),acf_noise[i,:])))
        #
        spec_noise = spec_noise / Nlag
#%% spectrum from ACF
    for i in range(Nr):
        spec[i,:] = fftshift(fft(append(conj(acf[i,1:][::-1]), acf[i,:])))-spec_noise

    return spec,acf
Exemplo n.º 18
0
    def fft_r2g(self, fr, shift_fg=False):
        """
        FFT of array ``fr`` given in real space.
        """
        ndim, shape = fr.ndim, fr.shape

        if ndim == 1:
            fr = np.reshape(fr, self.shape)
            return self.fft_r2g(fr, shift_fg=shift_fg).flatten()

        elif ndim == 3:
            assert self.size == np.prod(shape[-3:])
            fg = fftn(fr)
            if shift_fg: fg = fftshift(fg)

        elif ndim > 3:
            assert self.size == np.prod(shape[-3:])
            axes = np.arange(ndim)[-3:]
            fg = fftn(fr, axes=axes)
            if shift_fg: fg = fftshift(fg, axes=axes)

        else:
            raise NotImplementedError("ndim < 3 are not supported")

        return fg / self.size
Exemplo n.º 19
0
def laplacian_filter(in_file, in_mask=None, out_file=None):
    import numpy as np
    import nibabel as nb
    import os.path as op
    from math import pi
    from numpy.fft import fftn, ifftn, fftshift, ifftshift

    if out_file is None:
        fname, fext = op.splitext(op.basename(in_file))
        if fext == '.gz':
            fname, _ = op.splitext(fname)
        out_file = op.abspath('./%s_smooth.nii.gz' % fname)

    im = nb.load(in_file)
    data = im.get_data()

    if in_mask is not None:
        mask = nb.load(in_mask).get_data()
        mask[mask > 0] = 1.0
        mask[mask <= 0] = 0.0
        data *= mask

    dataft = fftshift(fftn(data))
    x = np.linspace(0, 2 * pi, dataft.shape[0])[:, None, None]
    y = np.linspace(0, 2 * pi, dataft.shape[1])[None, :, None]
    z = np.linspace(0, 2 * pi, dataft.shape[2])[None, None, :]
    lapfilt = 2.0 * np.squeeze((np.cos(x) + np.cos(y) + np.cos(z))) - 5.0
    dataft *= fftshift(lapfilt)
    imfilt = np.real(ifftn(ifftshift(dataft)))

    nb.Nifti1Image(imfilt.astype(np.float32), im.get_affine(),
                   im.get_header()).to_filename(out_file)
    return out_file
Exemplo n.º 20
0
def _configure(infiles, z, df):
    conf.infiles = infiles
    img_hdr = fits.getheader(conf.infiles[0])
    conf.nx = img_hdr['naxis1']
    conf.ny = img_hdr['naxis2']
    conf.nf = MWA_FREQ_EOR_ALL_80KHZ.size
    conf.dx = np.abs(img_hdr['cdelt1']) * np.pi / 180
    conf.dy = np.abs(img_hdr['cdelt2']) * np.pi / 180
    conf.df = df
    conf.du = 1 / (conf.nx * conf.dx)
    conf.dv = 1 / (conf.ny * conf.dy)
    conf.deta = 1 / (conf.nf * conf.df)
    conf.freq = MWA_FREQ_EOR_ALL_80KHZ
    conf.u = fftshift(fftfreq(conf.nx, conf.dx))
    conf.v = fftshift(fftfreq(conf.ny, conf.dy))
    conf.eta = fftshift(fftfreq(conf.nf, conf.df))
    conf.z = z
    conf.cosmo_d = Cosmo.comoving_transverse_distance(conf.z).value
    conf.cosmo_e = np.sqrt(Cosmo.Om0 * (1 + conf.z) ** 3 + Cosmo.Ok0 *
                           (1 + conf.z) ** 2 + Cosmo.Ode0)
    conf.cosmo_h0 = Cosmo.H0.value * 1e3
    conf.cosmo_c = const.si.c.value
    conf.kx = conf.u * 2 * np.pi / conf.cosmo_d
    conf.ky = conf.v * 2 * np.pi / conf.cosmo_d
    conf.dkx = conf.du * 2 * np.pi / conf.cosmo_d
    conf.dky = conf.dv * 2 * np.pi / conf.cosmo_d
    conf.k_perp = np.sqrt(conf.kx ** 2 + conf.ky[np.newaxis, ...].T ** 2)
    conf.k_par = conf.eta * 2 * np.pi * conf.cosmo_h0 * _F21 * \
        conf.cosmo_e / (conf.cosmo_c * (1 + conf.z) ** 2)
Exemplo n.º 21
0
def plot_pixel_effect():
    fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))
    #fig = plt.figure()
    #ax = fig.add_subplot(111)
    out = fft(ifftshift(f_full))
    freqs = fftfreq(len(f_full), d=0.01) # spacing, Ang
    sfreqs = fftshift(freqs)
    taper = gauss_taper(freqs, sigma=0.0496) #Ang, corresponds to 2.89 km/s at 5150A.
    tout = out * taper

    for ax in axs[:, 0]:
        ax.plot(sfreqs, fftshift(tout) / tout[0])
        ax.plot(sfreqs, fftshift(taper))
        ax.plot(sfreqs, 0.0395 * np.sinc(0.0395 * sfreqs))
        ax.plot(sfreqs, 0.0472 * np.sinc(0.0472 * sfreqs))

    for ax in axs[:, 1]:
        ax.plot(sfreqs, 10 * np.log10(np.abs(fftshift(tout) / tout[0])))
        ax.plot(sfreqs, 10 * np.log10(np.abs(fftshift(taper))))
        ax.plot(sfreqs, 10 * np.log10(np.abs(0.0395 * np.sinc(0.0395 * sfreqs))))
        ax.plot(sfreqs, 10 * np.log10(np.abs(0.0472 * np.sinc(0.0472 * sfreqs))))

    axs[0, 0].set_ylabel("Norm amp")
    axs[1, 0].set_ylabel("Norm amp")
    axs[0, 1].set_ylabel("dB")
    axs[1, 1].set_ylabel("dB")
    for ax in axs.flatten():
        ax.set_xlabel(r"cycles/$\lambda$")
    plt.show()
Exemplo n.º 22
0
 def sample_mps(self,window,temp_rate_Hz=10,zeropad=True):
     '''
     Return samples of modulation power spectrum
     '''
     
     ft, tf, sf = self._sample_modspec(window,temp_rate_Hz,
                                       zeropad=zeropad)
     return fftshift(abs(ft)**2), fftshift(tf), fftshift(sf)
Exemplo n.º 23
0
def GetPulseSpectrum(krotov):
	"""
	"""
	
	dw = 2 * pi * fft.fftshift(fft.fftfreq(len(krotov.ControlVector), krotov.TimeGridResolution))
	pulseSpectrum = fft.fftshift(fft.fft(krotov.ControlVector))

	return dw, pulseSpectrum
    def __build_wavenumbers__(self):
        k_1d = fftshift(np.array(range(0, self.num_points_x))*
                                               ((2*np.pi)/self.length_x))
        l_1d = fftshift(np.array(range(0, self.num_points_y))*
                                               ((2*np.pi)/self.length_y))

        self.kmax = max(k_1d)
        self.lmax = max(l_1d)
        self.k, self.l = np.meshgrid(k_1d, l_1d)
Exemplo n.º 25
0
    def test_kost_comp_abs(self):
        ft_image = fft2(self.image)
        ft_mask_padded = fft2(self.inert_mask_padded)

        ft_result = fftshift(ft_image) * fftshift(ft_mask_padded)

        result = ifftshift(ifft2(ft_result))

        assert_array_almost_equal(abs(result), self.image)
Exemplo n.º 26
0
    def test_our_comp_shifted_abs(self):
        # Now, our computation
        ft_image = fft2(self.image)
        ft_mask = fft2(self.inert_mask, self.image.shape)
        ft_res_ft = fftshift(ft_image) * fftshift(ft_mask)

        result = ifft2(ifftshift(ft_res_ft))

        assert_array_equal(abs(result), self.image)
Exemplo n.º 27
0
def get_mps(t, freq, spec):
    "Computes the MPS of a spectrogram (idealy a log-spectrogram) or other REAL time-freq representation"
    mps = fftshift(fft2(spec))
    amps = np.real(mps * np.conj(mps))
    nf = mps.shape[0]
    nt = mps.shape[1]
    wfreq = fftshift(fftfreq(nf, d=freq[1] - freq[0]))
    wt = fftshift(fftfreq(nt, d=t[1] - t[0]))
    return wt, wfreq, mps, amps
Exemplo n.º 28
0
 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(fft.fftshift(x), y)
     assert_array_almost_equal(fft.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(fft.fftshift(x), y)
     assert_array_almost_equal(fft.ifftshift(y), x)
Exemplo n.º 29
0
def fir_to_frp(fir,tbins=None):
    '''Transform a fir (time domain fr filter) to a fringe rate profile.
       fir: array of fringe rate profile. 
       tbins: Corresponding time bins of filter. If None, doesnt return ffringe rates.
    '''
    fir = ifftshift(fir, axes=-1)
    frp = fft(fir, axis=-1)
    frp = fftshift(frp, axes=-1)
    if tbins is not None: return frp, fftshift(fftfreq(tbins.size, tbins[1]-tbins[0]))
    else: return frp
Exemplo n.º 30
0
 def get_k(self):
     """
     """
     azisz = self.get_info('azimuth_size')
     azidk = self.get_info('azimuth_dk')
     ransz = self.get_info('range_size')
     randk = self.get_info('range_dk')
     k = (fftshift(fftfreq(azisz))*azisz*azidk,
          fftshift(fftfreq(ransz))*ransz*randk)
     return k
Exemplo n.º 31
0
				elementRadial = np.exp(-1 * np.power( np.log(normalizedRadius/ (centerFrequency / 0.5)),2) / (2 * np.log(sigmaF) * np.log(sigmaF)) )
				theta = math.atan2(-y,x)
				deltaSin = math.sin(theta) * math.cos(centerAngle) - math.cos(theta) * math.sin(centerAngle)
				deltaCosine = math.cos(theta) * math.cos(centerAngle) + math.sin(theta) * math.sin(centerAngle)

				deltaTheta = abs(math.atan2(deltaSin, deltaCosine))

				elementAngular = np.exp((-1 * deltaTheta * deltaTheta) / (2 * thetaStd * thetaStd))

				kernel[i, j] = elementAngular * elementRadial
				if(kernel[i,j] < 0.001):
					kernel[i,j] = 0
		wavelength = wavelength * wavelengthIncrement
	
		kernel = fft.fftshift(kernel)
		convolved = imageFFT * kernel

		s1 = np.array(kernel.shape)
		s2 = np.array(imageFFT.shape)

		size = s1 + s2 - 1


		fsize = 2 ** np.ceil(np.log2(size)).astype(int)
		fslice = tuple([slice(0, int(sz)) for sz in size])

		convolved = fft.ifft2(convolved)[fslice]
		
		evens = np.real(convolved)
		odds = np.imag(convolved)
Exemplo n.º 32
0
def simul_psd_wfm(Cn2,
                  h,
                  seeing,
                  L0,
                  zenith=0.,
                  plot=False,
                  npsflin=1,
                  dim=1280,
                  three_lgs_mode=False,
                  verbose=True):
    """ Batch de simulation de PSF WFM MUSE avec impact de NGS.

    Parameters
    ----------
    Cn2        = pondération du profil
    h          = altitude des couches (en m)
    seeing     = seeing @ zenith  (en arcsec @ 500nm)
    L0         = Grande echelle (en m)
    zenith     = (en degré)
    npsflin    = nombre de point (lineaire) dans le champ pour l'estimation
    des PSF (1 = au centre, 2 = au 4 coins, 3 = 9 PSF etc ...)
    dim        = Final dimension of the PSD

    """
    # STEP 0 : Définition des conditions
    # =============================================

    # Step 0.1 : turbulence
    # ---------
    Cn2 = np.array(Cn2)
    Cn2 /= Cn2.sum()

    h = np.array(h)
    vent = np.full_like(h, 12.5)

    # FIXME: currently set to IDL values for reproducability
    np.random.seed(12345)
    # arg_v = (np.random.rand(h.shape[0]) - 0.5) * np.pi  # wind dir.  [rad]
    arg_v = np.array([0.628163, -0.326497])  # from IDL

    # Step 0.2 : Systeme
    # ---------
    Dpup = 8.  # en m (diametre du telescope)
    # oc = 0.14          # normalisée [de 0 --> 1]
    altDM = 1.  # en m
    hsodium = 90000.  # en m

    # lambdalgs = 0.589  # en µm
    lambdaref = 0.5  # en µm
    nact = 24.  # nombre lineaire d'actionneurs
    nsspup = nact  # nombre lineaire d'actionneurs

    Fsamp = 1000.  # frequence d'échantillonnage [Hz]
    delay = 2.5  # retard en ms (lecture CCD + calcul)

    seplgs = 63.  # separation (en rayon) des LGS [arcsec]
    bruitLGS2 = 1.0  # radians de phase bord a bord de sspup @ lambdalgs

    if three_lgs_mode:
        if verbose:
            logger.info('Using three lasers mode')
        poslgs = np.array([[1, 1], [-1, -1], [-1, 1]], dtype=float).T
    else:
        poslgs = np.array([[1, 1], [-1, -1], [-1, 1], [1, -1]], dtype=float).T

    poslgs *= seplgs  # *cos(pi/4) # position sur une grille cartesienne
    law = "LSE"  # type de lois : lse ou mmse
    recons_cn2 = 1  # a priori sur Cn2 => ici GLAO
    recons_h = altDM  # a priori sur h   => ici GLAO

    # Step 0.3 : Direction d'estimation
    dirperf = direction_perf(npsflin, plot=plot, lgs=poslgs)

    # Step 0.4 : Paremetres numériques
    # ---------
    Dimpup = 40  # Taille de la pupille en pixel pour zone de correction
    # coefL0 = 1         # pour gerer les "L0 numériques"

    # Step 0.5 : Mise en oeuvre
    # ---------
    r0ref = seeing2r01(seeing, lambdaref, zenith)  # passage seeing --> r0
    hz = h / np.cos(np.deg2rad(zenith))  # altitude dans la direction de visée
    dilat = (hsodium - hz) / hsodium  # dilatation pour prendre en compte
    hz_lgs = hz / dilat  # la LGS
    hz_lgs -= altDM  # on prend en compte la conjugaison negative du DM

    # Step 0.6 : Summarize of parameters
    # ---------
    logger.debug('r0 0.5um (zenith)        = %.2f',
                 seeing2r01(seeing, lambdaref, 0))
    logger.debug('r0 0.5um (line of sight) = %.2f', r0ref)
    logger.debug('Seeing   (line of sight) = %.2f', 0.987 * 0.5 / r0ref / 4.85)
    logger.debug('hbarre   (zenith)        = %.2f',
                 np.sum(h**(5 / 3) * Cn2)**(3 / 5))
    logger.debug('hbarre   (line of sight) = %.2f',
                 np.sum(hz**(5 / 3) * Cn2)**(3 / 5))
    logger.debug('vbarre                   = %.2f',
                 np.sum(vent**(5 / 3) * Cn2)**(3 / 5))

    # ========================================================================

    # longueur physique d'un ecran de ^hase issue de la PSD
    # => important pour les normalisations
    # L = dim / Dimpup * Dpup

    pitch = Dpup / nact  # pitch: inter-actuator distance [m]
    fc = 1 / (2 * pitch)  # pItch frequency (1/2a)  [m^{-1}]

    # STEP 1 : Simulation des PSF LGS (tilt inclus)
    # ===============================================
    # cube de DSP pour chaque direction d'interet - ZONE DE CORRECTION ONLY
    dsp = dsp4muse(Dpup, Dimpup, Dimpup * 2, Cn2, h, L0, r0ref, recons_cn2,
                   recons_h, vent, arg_v, law, nsspup, nact, Fsamp, delay,
                   bruitLGS2, lambdaref, poslgs, dirperf)

    # STEP 2: Calcul DSP fitting
    # ===============================================
    dspa = fftshift(psd_fit(dim, 2 * Dpup, r0ref, L0, fc))
    dspf = np.resize(dspa, (dsp.shape[0], dim, dim))

    # Finale
    sl = slice(dim // 2 - Dimpup, dim // 2 + Dimpup)
    dspf[:, sl, sl] = np.maximum(dspa[sl, sl], fftshift(dsp, axes=(1, 2)))

    return dspf * (lambdaref * 1000 / (2 * np.pi))**2
Exemplo n.º 33
0
    def plot(self,log=False,colorbar=True,title='',powerOfL=0,pngFile=None,show=True,zoomUptoL=None,\
             showMask=False, yrange = None, showBinsFromFile = None,drawCirclesAtL=None,\
             drawVerticalLinesAtL = None, valueRange=None, colorbarLabel=None):
        """
        @brief Display the power spectrum
        """
        #modLMap = self.modLMap
        #modLMap[np.where(modLMap ==0)] = 1.
        p = self.powerMap.copy()

        p[:] *= (self.modLMap[:] + 1.)**powerOfL
        p = fftshift(p)

        if showBinsFromFile:
            binLower, binUpper, binCenter = readBinningFile(showBinsFromFile)
            theta = np.arange(0, 2. * np.pi + 0.05, 0.05)

            for i in xrange(len(binLower)):
                x, y = binUpper[i] * np.cos(theta), binUpper[i] * np.sin(theta)
                pylab.plot(x, y, 'k')

        if drawCirclesAtL != None:
            for ell in drawCirclesAtL:
                theta = np.arange(0, 2. * np.pi + 0.05, 0.05)
                x, y = ell * np.cos(theta), ell * np.sin(theta)
                pylab.plot(x, y, 'k')
                if len(drawCirclesAtL) < 5:
                    pylab.text(ell*np.cos(np.pi/4.),ell*np.sin(np.pi/4.),\
                               '%d'%np.int(ell),rotation=-45,horizontalalignment = 'center',\
                               verticalalignment='bottom',fontsize=8)

        if drawVerticalLinesAtL != None:
            for ell in drawVerticalLinesAtL:
                pylab.axvline(ell)

        if log:
            p = np.log10(np.abs(p))

        if yrange != None:
            p[np.where(p < yrange[0])] = yrange[0]
            p[np.where(p > yrange[1])] = yrange[1]
        vmin = p.min()
        vmax = p.max()
        if valueRange != None:
            vmin = valueRange[0]
            vmax = valueRange[1]

        im = pylab.imshow(p,origin="down",extent=[np.min(self.lx),np.max(self.lx),\
        np.min(self.ly),np.max(self.ly)],aspect='equal',vmin=vmin,vmax=vmax, interpolation='nearest')
        pylab.title(title, fontsize=8)
        if colorbar:
            cb = pylab.colorbar()
            if colorbarLabel != None:
                cb.set_label(colorbarLabel)
        pylab.xlabel(r'$\ell_x$', fontsize=15)
        pylab.ylabel(r'$\ell_y$', fontsize=15)

        if showMask:
            im2 =  pylab.imshow(fftshift(self.kMask.copy()),\
                                origin="down",\
                                extent=[np.min(self.lx),\
                                        np.max(self.lx),\
                                         np.min(self.ly),\
                                         np.max(self.ly)],\
                                aspect='equal')
            pylab.xlabel(r'$\ell_x$', fontsize=15)
            pylab.ylabel(r'$\ell_y$', fontsize=15)
            if colorbar:
                pylab.colorbar()

        if zoomUptoL != None:
            im.axes.set_xlim(-zoomUptoL, zoomUptoL)
            im.axes.set_ylim(-zoomUptoL, zoomUptoL)
            if showMask:
                im2.axes.set_xlim(-zoomUptoL, zoomUptoL)
                im2.axes.set_ylim(-zoomUptoL, zoomUptoL)

        if show:
            pylab.show()
        if pngFile != None:
            pylab.savefig(pngFile)
Exemplo n.º 34
0
    def compute_pspec(self,
                      beam_correct=False,
                      apodize_kernel=None,
                      alpha=0.3,
                      beta=0.0,
                      use_pyfftw=False,
                      threads=1,
                      **pyfftw_kwargs):
        '''
        Compute the 2D power spectrum.

        The quantity calculated here is the same as Equation 3 in Lazarian &
        Esquivel (2003), but the inputted arrays are not in the same form as
        described. We can, however, adjust for the use of normalized Centroids
        and the linewidth.

        An unnormalized centroid can be constructed by multiplying the centroid
        array by the moment0. Velocity dispersion is the square of the
        linewidth subtracted by the square of the normalized centroid.

        Parameters
        ----------
        beam_correct : bool, optional
            If a beam object was given, divide the 2D FFT by the beam response.
        apodize_kernel : None or 'splitcosinebell', 'hanning', 'tukey', 'cosinebell', 'tophat'
            If None, no apodization kernel is applied. Otherwise, the type of
            apodizing kernel is given.
        alpha : float, optional
            alpha shape parameter of the apodization kernel. See
            `~turbustat.apodizing_kernel` for more information.
        beta : float, optional
            beta shape parameter of the apodization kernel. See
            `~turbustat.apodizing_kernel` for more information.
        use_pyfftw : bool, optional
            Enable to use pyfftw, if it is installed.
        threads : int, optional
            Number of threads to use in FFT when using pyfftw.
        pyfftw_kwargs : Passed to
            `~turbustat.statistics.rfft_to_fft.rfft_to_fft`. See
            `here <http://hgomersall.github.io/pyFFTW/pyfftw/builders/builders.html>`__
            for a list of accepted kwargs.

        '''

        if apodize_kernel is not None:
            apod_kernel = self.apodizing_kernel(kernel_type=apodize_kernel,
                                                alpha=alpha,
                                                beta=beta)
            term1_data = self.centroid * self.moment0 * apod_kernel
            term2_data = self.linewidth**2 + self.centroid**2 * apod_kernel
            mom0_data = self.moment0 * apod_kernel

        else:
            term1_data = self.centroid * self.moment0
            term2_data = self.linewidth**2 + self.centroid**2
            mom0_data = self.moment0

        if pyfftw_kwargs.get('threads') is not None:
            pyfftw_kwargs.pop('threads')

        term1 = rfft_to_fft(term1_data,
                            use_pyfftw=use_pyfftw,
                            threads=threads,
                            **pyfftw_kwargs)

        fft_mom0 = rfft_to_fft(mom0_data,
                               use_pyfftw=use_pyfftw,
                               threads=threads,
                               **pyfftw_kwargs)

        # Account for normalization in the line width.
        term2 = np.nanmean(term2_data)

        mvc_fft = term1 - term2 * fft_mom0

        # Shift to the center
        mvc_fft = fftshift(mvc_fft)

        if beam_correct:
            if not hasattr(self, '_beam'):
                raise AttributeError("Beam correction cannot be applied since"
                                     " no beam object was given.")

            beam_kern = self._beam.as_kernel(self._ang_size,
                                             y_size=self.centroid.shape[0],
                                             x_size=self.centroid.shape[1])

            beam_fft = fftshift(rfft_to_fft(beam_kern.array))

            self._beam_pow = np.abs(beam_fft**2)

        self._ps2D = np.abs(mvc_fft)**2.

        if beam_correct:
            self._ps2D /= self._beam_pow
kxymax = 1 / (2 * deltaxy)
deltakxy = 1 / (xymax - xymin)
kx = ky = np.arange(kxymin, kxymax, deltakxy)  # not used

# create 2D function

f = function2D(X, Y)
X0 = 0  #translation in x
Y0 = 0  #translation in y
f.setcenter(X0, Y0)
ftype = 'square'  #change ftype to choose between 'circle', 'annulus','square','gaussian','sine',deltas
f.functiontype(ftype, 0.5)
Z = f.data  #Z are the values of the function

# calculate 2D fft (translated to the center using fftshift. ifftshift is used to remove phase errors)
ft = fftshift(fft2(ifftshift(Z)))

# %% create figures
#plot 2D function
fig1 = plt.figure(figsize=(9, 9))

plt.title(f.title)
#plt.title("2D function (Real part)")

plt.imshow(np.real(Z),
           interpolation='none',
           cmap=cm.RdYlGn,
           origin='lower',
           extent=[xymin, xymax, xymin, xymax],
           vmax=np.real(Z).max(),
           vmin=-np.real(Z).max())
Exemplo n.º 36
0
    def updateNoise(self):
        """Updates the noise sample. Does not change any of the noise parameters 
            but choses a new random sample given the previously set parameters.
        """

        if not(self.noiseType in ['binary','Binary','normal','Normal','uniform','Uniform']):
            if (self.noiseType in ['image', 'Image']) and (self.imageComponent in ['amplitude','Amplitude']):
                self.noiseTex = numpy.random.uniform(0,1,int(self._size**2))
                self.noiseTex = numpy.reshape(self.noiseTex,(int(self._size),int(self._size)))
                if self.filter in ['Butterworth','butterworth']:
                    self.noiseTex = fftshift(self._filter(self.noiseTex))
                elif self.filter in ['Gabor','gabor']:
                    self.noiseTex = fftshift(self._gabor(self.noiseTex))
                elif self.filter in ['Isotropic','isotropic']:
                    self.noiseTex = fftshift(self._isotropic(self.noiseTex))
                self.noiseTex[0][0] = 0
                In = self.noiseTex * exp(1j*self.noisePh)
                Im = numpy.real(ifft2(In))
            else:
                Ph = numpy.random.uniform(0,2*numpy.pi,int(self._size**2))
                Ph = numpy.reshape(Ph,(int(self._size),int(self._size)))
                In = self.noiseTex * exp(1j*Ph)
                Im = numpy.real(ifft2(In))
                Im = ifftshift(Im)
            gsd = filters.getRMScontrast(Im)
            factor = gsd*self.noiseClip
            numpy.clip(Im, -factor, factor, Im)
            self.tex = Im / factor
        elif self.noiseType in ['normal','Normal']:
            self.noiseTex = numpy.random.randn(int(self._sideLength[1]),int(self._sideLength[0])) / self.noiseClip
        elif self.noiseType in ['uniform','Uniform']:
            self.noiseTex = 2.0 * numpy.random.rand(int(self._sideLength[1]),int(self._sideLength[0])) - 1.0
        else:
            numpy.random.shuffle(self.noiseTex)  # pick random noise sample by shuffleing values
            self.noiseTex = numpy.reshape(self.noiseTex,(int(self._sideLength[1]),int(self._sideLength[0])))
        if self.noiseType in ['binary','Binary','normal','Normal','uniform','Uniform']:
            if self.filter in ['butterworth', 'Butterworth', 'Gabor','gabor','Isotropic','isotropic']:
                if self.units == 'pix':
                    if self._size[0] == self._size[1]:
                        baseImage = imresize(self.noiseTex, (int(self._size[0]),int(self._size[1])), interp='nearest')
                    else:
                        msg = ('NoiseStim can only apply filters to square noise images')
                        raise ValueError(msg)
                else: 
                    baseImage = imresize(self.noiseTex, (int(self._size),int(self._size)), interp='nearest')
                baseImage = numpy.array(baseImage).astype(
                        numpy.float32) * 0.0078431372549019607 - 1.0
                FT = fft2(baseImage)
                spectrum = numpy.absolute(fftshift(FT))
                angle = numpy.angle(FT)
                if self.filter in ['butterworth','Butterworth']:
                    spectrum = fftshift(self._filter(spectrum))
                elif self.filter in ['isotropic','Isotropic']:
                    spectrum = fftshift(self._isotropic(spectrum))
                elif self.filter in ['gabor','Gabor']:
                    spectrum = fftshift(self._gabor(spectrum))
                spectrum[0][0] = 0 # set DC to zero
                FT = spectrum * exp(1j*angle)
                
                Im = numpy.real(ifft2(FT))
                gsd = filters.getRMScontrast(Im)
                factor = gsd*self.noiseClip
                numpy.clip(Im, -factor, factor, Im)
                self.tex = Im / factor
            else:
                if not(self.noiseType in ['image','Image']):
                    self.tex = self.noiseTex
Exemplo n.º 37
0
    flsig4 = (bpf1(data))
    flsig5 = (bpf2(data))
    flsig6 = (bpf3(data))

    plt.title("segmented signal")
    plt.plot(flsig4, color='green')
    plt.plot(flsig5, color='blue')
    plt.plot(flsig6, color='red')
    plt.show()

    datafft4 = fft_plot(flsig4, "fft :: song 1 no shift")
    datafft5 = fft_plot(flsig5, "fft :: song 2 no shift")
    datafft6 = fft_plot(flsig6, "fft :: song 3 no shift")

    plt.title("segmented signals :: Fourier Transform")
    freq = fft.fftshift(fft.fftfreq(datafft4.shape[-1]))
    plt.plot(freq, np.abs(datafft4), color='green')
    plt.plot(freq, np.abs(datafft5), color='blue')
    plt.plot(freq, np.abs(datafft6), color='red')
    plt.show()

    flsig4 = lpf(flsig4 * w1)
    flsig5 = lpf(flsig5 * w2)
    flsig6 = lpf(flsig6 * w3)

    plt.title("segmented signal")
    plt.plot(flsig4, color='green')
    plt.plot(flsig5, color='blue')
    plt.plot(flsig6, color='red')
    plt.show()
Exemplo n.º 38
0
 def test_inverse(self):
     for n in [1, 4, 9, 100, 211]:
         x = np.random.random((n,))
         assert_array_almost_equal(fft.ifftshift(fft.fftshift(x)), x)
import numpy as np
from numpy import pi
from numpy.fft import fft
from numpy.fft import ifft
from numpy.fft import fftshift
from numpy.fft import ifftshift
import matplotlib.pyplot as plt

from skimage.data import shepp_logan_phantom
from skimage.transform import resize

from scipy.signal import convolve

FFT = lambda x: fftshift(fft(ifftshift(x)))
IFFT = lambda x: fftshift(ifft(ifftshift(x)))

EPS = 1e-18

## 4) Sptial 1D Convolution vs. Fourier Multiplication
N = 100
M = 36

X = np.random.randn(N, 1)
Y = np.random.randn(M, 1)

if (N > M):
    K = int(max(64, 2**int(np.log2(2*N))))
else:
    K = int(max(64, 2**int(np.log2(2*M))))

X_ = np.zeros(K)
Exemplo n.º 40
0
def bt_spectrum(time_series):
  R = xcorr(time_series, scale='biased')
  return N.abs(fliplr(fftshift(fft(R))))
Exemplo n.º 41
0
def time_gate(ntwk,
              start=None,
              stop=None,
              center=None,
              span=None,
              mode='bandpass',
              window=('kaiser', 6),
              media=None,
              boundary='reflect',
              return_all=False):
    '''
    Time-gate one-port s-parameters.
    
    The gate can be defined with start/stop times, or by 
    center/span. all times are in units of nanoseconds. common 
    windows are:
     * ('kaiser', 6)
     * 6 # integers are interpreted as kaiser beta-values
     * 'hamming'
     * 'boxcar'  # a staightup rect
     
    If no parameters are passed this will try to auto-gate the largest
    peak. 

    Parameters
    ------------
    start : number, or None
        start of time gate, (ns). 
    stop : number, or None
        stop of time gate (ns). 
    center : number, or None
        center of time gate, (ns). If None, and span is given, 
        the gate will be centered on the peak.
    span : number, or None
        span of time gate, (ns).  If None span will be half of the 
        distance to the second tallest peak
    mode: ['bandpass','bandstop']
        mode of gate 
    boundary:  {'reflect', 'constant', 'nearest', 'mirror', 'wrap'},
        passed to `scipy.ndimage.filters.convolve1d`
    window : string, float, or tuple 
        passed to `window` arg of `scipy.signal.get_window`
    
    Notes
    ------
    You cant gate things that are 'behind' strong reflections. This 
    is due to the multiple reflections that occur. 
    
    If `center!=0`, then the ntwk's time response is shifted 
    to t=0, gated, then shifted back to where it was. This is 
    done in frequency domain using `ntwk.delay()`. If the media being
    gated is dispersive (ie waveguide), then the gate `span` will be 
    span at t=0, which is different.
    
    If you need to time-gate an N-port network, then you should 
    gate each s-parameter independently. 
    
    Returns
    --------
    ntwk : Network
        copy of ntwk with time-gated s-parameters

    .. warning::
        Depending on sharpness of the gate, the  band edges may be 
        inaccurate, due to properties of FFT. We do not re-normalize
        anything.


    '''
    if ntwk.nports > 1:
        raise ValueError(
            'Time-gating only works on one-ports. try taking ntwk.s11 or ntwk.s21 first'
        )

    if start is not None and stop is not None:
        start *= 1e-9
        stop *= 1e-9
        span = abs(stop - start)
        center = (stop + start) / 2.

    else:
        if center is None:
            # they didnt provide center, so find the peak
            n = ntwk.s_time_mag.argmax()
            center = ntwk.frequency.t_ns[n]

        if span is None:
            span = detect_span(ntwk)

        center *= 1e-9
        span *= 1e-9
        start = center - span / 2.
        stop = center + span / 2.

    # find start/stop gate indecies
    t = ntwk.frequency.t
    start_idx = find_nearest_index(t, start)
    stop_idx = find_nearest_index(t, stop)

    # create window
    window_width = abs(stop_idx - start_idx)
    window = signal.get_window(window, window_width)

    # create the gate by padding the window with zeros
    gate = npy.r_[npy.zeros(start_idx), window, npy.zeros(len(t) - stop_idx)]

    #FFT the gate, so we have it's frequency response, aka kernel
    kernel = fft.ifftshift(fft.fft(fft.fftshift(gate, axes=0), axis=0))
    kernel = abs(kernel).flatten()  # take mag and flatten
    kernel = kernel / sum(kernel)  # normalize kernel

    out = ntwk.copy()

    # conditionally delay ntwk, to center at t=0, this is
    # equivalent to gating at center.  (this is probably very inefficient)
    if center != 0:
        out = out.delay(-center * 1e9, 'ns', port=0, media=media)

    # waste of code to handle convolve1d suck
    re = out.s_re[:, 0, 0]
    im = out.s_im[:, 0, 0]
    s = convolve1d(re,kernel, mode=boundary)+\
     1j*convolve1d(im,kernel, mode=boundary)
    out.s[:, 0, 0] = s
    # conditionally  un-delay ntwk
    if center != 0:
        out = out.delay(center * 1e9, 'ns', port=0, media=media)

    if mode == 'bandstop':
        out = ntwk - out
    elif mode == 'bandpass':
        pass
    else:
        raise ValueError('mode should be \'bandpass\' or \'bandstop\'')

    if return_all:
        # compute the gate ntwk and add delay
        gate_ntwk = out.s11.copy()
        gate_ntwk.s = kernel
        gate_ntwk = gate_ntwk.delay(center * 1e9, 'ns', media=media)

        return {'gated_ntwk': out, 'gate': gate_ntwk}
    else:
        return out
Exemplo n.º 42
0
def periodogram(time_series):
  Z = fliplr(fftshift(fft(time_series)))
  return N.abs(Z)*N.abs(Z)/time_series.size
Exemplo n.º 43
0
plt.legend(["datos", "lineal"])

v2 = plt.subplot(2,1,2)
v2.scatter(x1,y1)
y =  interp.interp1d(x1,y1, kind = "cubic")
x = np.linspace(0,6,1000)
v2.plot(x,y(x), c="r")
plt.legend(["datos", "cubica"])
plt.savefig("interp.png")



n=100
x= np.linspace(0,2*3.14,n)
y = np.sin(x) +np.random.rand(n)
yo = f.fftshift( f.fft(y) )
xo = f.fftshift( f.fftfreq(n) )

plt.figure()
v1 =plt.subplot(4,1,1)
v1.plot(xo,abs(yo),label="fourier")
plt.legend()

v2 =plt.subplot(4,1,2)
v2.plot(x,y,label="funcion")
plt.legend()

yo[abs(xo) > 0.01] = 0
#delta = np.where(abs(xo) > 0)

v3 =plt.subplot(4,1,3)
Exemplo n.º 44
0
def _calcpr_raar(F, C_s, plan, D_s=None, rho_0=None, r_factor=None, *args, **kwargs):
    """_calcpr_raar(F, C_s, plan, D_s=None, rho_0=None, r_factor=None, *args, **kwargs) -> None
    Relaxed alternating averaged reflections algorithm
    Detail: A. V. Martin et al., Optics Express 20, 16650 (2012)

    Parameters
    ----------
    F        : numpy.2darray
        target modulus
    C_s      : numpy.2darray
        support in real space
    plan     : Plan / list of Plans object (Plan)
        plan of PR
    D_s      : numpy.2darray (default : None)
        mask in reciprocal space
    rho_0    : numpy.2darray (default : None)
        initial guess of the density map
    r_factor : list (default : None)
        history of R factor
    args     : options
    kwargs   : options
    """
    # Initialize
    if rho_0 is None:
        rho_0 = _init_phase(plan.shape)
        rho_0 *= np.max(np.abs(ifft2(F)))
    elif rho_0 == "phase":
        rho_0 = _init_phase(plan.shape)
        rho_0 *= np.max(np.abs(ifft2(F)))
    elif rho_0 == "amplitude":
        rho_0 = _init_phase(plan.shape)
        rho_0 = ifft2(F*rho_0)
    elif rho_0 == "auto":
        rho_0 = ifft2(F**2)
    elif rho_0 == "auto, amplitude":
        rho_0 = _init_phase(plan.shape)
        rho_0 = ifft2(F**2 * rho_0)
    elif rho_0 == "auto, phase":
        rho_0 = _init_phase(plan.shape)
        rho_0 = rho_0 * ifft2(F**2)

    if r_factor is None:
        r_factor = []
    _F = np.abs(fftshift(F))

    _D_s = D_s
    if D_s is not None:
        _D_s = fftshift(D_s)

    rho_i = 1.*rho_0
    rho_f = np.zeros(F.shape, dtype=np.complex64)
    beta = plan.kwargs.get('beta')
    if beta is None or beta <= 0:
        beta = 0.85
    gamma_s = plan.kwargs.get("gamma_s")
    if gamma_s is None or gamma_s > 0:
        gamma_s = - 1. / beta
    gamma_m = plan.kwargs.get("gamma_m")
    if gamma_m is None or gamma_m < 0:
        gamma_m = 1. / beta

    # Define FFT functions
    func = FFT_FUNC.get(plan.fft_type)
    ifunc = IFFT_FUNC.get(plan.fft_type)

    # Check use of mask and validity of the parameters
    updmask_use = plan.kwargs.get('updmask_use', False)
    updmask_N = plan.kwargs.get('updmask_N')
    if updmask_use is None or type(updmask_use) != bool:
        updmask_use = False
    elif updmask_N is None or type(updmask_N) != int or updmask_N <= 0:
        updmask_use = False
    
    ratio = plan.kwargs.get('updmask_ratio')
    if ratio is None or ratio <= 0:
        ratio = -1
    
    _init_C_s = kwargs.get("init_C_s", None)
    width = 1.5
    if C_s is None:
        C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)
    if _init_C_s is not None and _init_C_s == True:
        C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)

    # The known error function for Liu's process.
    err = plan.kwargs.get('err')
    if err is not None and type(err) not in [np.ndarray, list]:
        raise TypeError('"err" has an invalid type.')
    intensity = plan.kwargs.get('intensity')
    if intensity is not None and type(intensity) != bool:
        raise TypeError('"intensity" must be boolean.')

    # alpha = plan.N
    # d_alpha = - (plan.N-1./plan.N)/9.
    # updoss_N = int(plan.N/10)
    # _qx = np.linspace(-1., 1.-2./plan.shape[0], plan.shape[0])
    # _qy = np.linspace(-1., 1.-2./plan.shape[1], plan.shape[1])
    # _qxx, _qyy = np.meshgrid(_qx, _qy)
    # _qrr = np.sqrt(_qxx**2 + _qyy**2)
    # del _qxx, _qyy, _qx, _qy

    _num = 0 if plan.kwargs.get('num') is None else plan.kwargs.get('num')

    # Main loop
    width = 1.5
    # _W = np.exp(-0.5*(_qrr / alpha)**2)
    for ii in range(plan.N):
        rho_f = func(rho_i, plan.x_gpu, plan.xf_gpu, plan.cufft_plan) # rho(n) -> G(n)
        r_factor.append(_calc_r_factor(rho_f, _F))
        rho_f = _projection_I(rho_f, _F, plan.f_const, _D_s, err, intensity, **kwargs) # G(n) -> G'(n)

        A = 2. * beta * _projection_er(ifunc(rho_f, plan.x_gpu, plan.xf_gpu, plan.cufft_plan), C_s, plan.rho_const)
        B = (1 - 2. * beta) * ifunc(rho_f, plan.x_gpu, plan.xf_gpu, plan.cufft_plan)
        C = - beta * _projection_er(rho_i, C_s, plan.rho_const)
        rho_i = beta * rho_i + A + B + C
        
        # rho_i = _projection_hio(ifunc(rho_f, plan.x_gpu, plan.xf_gpu, plan.cufft_plan), C_s, plan.rho_const, rho_i, beta) # G'(n) -> rho(n+1)
        # buff = func(rho_i, plan.x_gpu, plan.xf_gpu, plan.cufft_plan)
        # buff = np.real(ifunc(buff, plan.x_gpu, plan.xf_gpu, plan.cufft_plan)) # take real part of density
        # buff = np.real(ifunc(buff*_W, plan.x_gpu, plan.xf_gpu, plan.cufft_plan)) # take real part of density
        # rho_i = rho_i*C_s + buff*(1-C_s)
        # if np.mod(ii+1, updoss_N) == 0:
        #     alpha -= d_alpha
            # _W = np.exp(-0.5*(_qrr / alpha)**2)
        if updmask_use:
            if np.mod(ii+1, updmask_N) == 0 and ratio > 0: # Update the mask
                width = width-0.03 if width >= 1.5 else 1.5
                C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)
        if plan.kwargs.get('save') is True:
            _savefig(np.abs(rho_i), C_s, rho_f, r_factor, plan.pr_mode, ii+_num)

    plan.set(rho_i, r_factor, C_s)
Exemplo n.º 45
0
    def buildNoise(self):
        """build a new noise sample. Required to act on changes to any noise parameters or texRes.
        """

        if self.units == 'pix':
            if not (self.noiseType in ['Binary','binary','Normal','normal','uniform','Uniform']):
                mysize = numpy.max(self.size)
            else:
                mysize = self.size
            sampleSize = self.noiseElementSize
            mysf = self.__dict__['noiseBaseSf']*mysize
            lowsf = self.noiseFilterLower*numpy.max(mysize) # filter can only be applied to square images anyway
            upsf = self.noiseFilterUpper*numpy.max(mysize)
        else:
            mysize = self.texRes
            pixSize = self.size/self.texRes
            sampleSize = self.noiseElementSize/pixSize
            mysf = self.size[0]*self.noiseBaseSf
            lowsf = self.size[0]*self.noiseFilterLower
            upsf = self.size[0]*self.noiseFilterUpper
       
        self._size = mysize  # store for use by updateNoise()
        self._sf = mysf
        self._lowsf = lowsf
        self._upsf = upsf
        if self.noiseType in ['binary','Binary','normal','Normal','uniform','Uniform']:
            self._sideLength = numpy.round(mysize/sampleSize)  # dummy side length for use when unpacking noise samples in updateNoise()
            self._sideLength.astype(int)
            if ((self._sideLength[0] < 2) and (self._sideLength[1] < 2)):
                msg=('Noise sample size '
                     'must result in more than '
                     '1 sample per image dimension.')
                raise ValueError(msg)
            totalSamples = self._sideLength[0]*self._sideLength[1]
            if self.noiseType in ['binary','Binary']:
                self.noiseTex=numpy.append(numpy.ones(int(numpy.round(totalSamples/2.0))),-1*numpy.ones(int(numpy.round(totalSamples/2.0))))
        elif self.noiseType in ['White','white','filtered','Filtered','isotropic','Isotropic','Gabor','gabor']:
            self.noiseTex = numpy.ones((int(mysize),int(mysize)))
            self.noiseTex = fftshift(self.noiseTex)
        elif self.noiseType in ['Image','image']:
            if not(self.noiseImage in ['None','none']):  
                im = Image.open(self.noiseImage)
                im = im.transpose(Image.FLIP_TOP_BOTTOM)
                im = im.convert("L")  # FORCE TO LUMINANCE
                im = imresize(im, (int(self._size),int(self._size)), interp='bilinear')
                intensity = numpy.array(im).astype(
                        numpy.float32) * 0.0078431372549019607 - 1.0
                if self.imageComponent in ['phase', 'Phase']:
                    self.noiseTex = numpy.absolute(fftshift(fft2(intensity))) # fftshift here is undone later
                elif self.imageComponent in ['amplitude', 'Amplitude']:
                    self.noisePh = numpy.angle((fft2(intensity))) # fftshift here is undone later
                    self.noiseTex = numpy.random.uniform(0,1,int(self._size**2))
                    self.noiseTex = numpy.reshape(self.noiseTex,(int(self._size),int(self._size)))
                else:
                    raise ValueError("Unknown value for imageComponent in noiseStim")
            else:
                self.noiseTex = numpy.ones((int(mysize),int(mysize)))  # if image is 'None' will make white noise as temporary measure
        else:
            msg = ('Noise type not recognised. Valid types are Binary, Uniform, Normal,'
                    'White, Filtered, Gabor, Isotropic or Image')
            raise ValueError(msg)
        if not(self.noiseType in ['binary','Binary','normal','Normal','uniform','Uniform']):
            if (self.noiseType in ['filtered','Filtered']) or (self.filter in ['butterworth', 'Butterworth']):
                self.noiseTex=self._filter(self.noiseTex)
            elif (self.noiseType in ['Isotropic','isotropic']) or (self.filter in ['isotropic', 'Isopropic']):
                self.noiseTex = self._isotropic(self.noiseTex)
            elif (self.noiseType in ['Gabor','gabor']) or (self.filter in ['gabor', 'Gabor']):
                self.noiseTex = self._gabor(self.noiseTex)
            self.noiseTex = fftshift(self.noiseTex)
            self.noiseTex[0][0] = 0 # Set DC to zero
  
        self._needBuild = False # prevent noise from being re-built at next draw() unless a parameter is changed in the mean time.
        self.updateNoise()  # now choose the initial random sample.
Exemplo n.º 46
0
def blr_probe3(N, rs_rad, fs_rad1, fs_rad2):
    divs = 60
    rs_mask = sector_mask((N, N), (N / 2, N / 2), rs_rad * N, (0, 360))
    rs_mask = rs_mask / norm(rs_mask, 1)

    fs_mask = np.zeros_like(rs_mask, dtype=np.float32)

    for i in np.arange(0, divs, 3):
        fs_mask += sector_mask((N, N), (N / 2, N / 2), fs_rad1 * N,
                               (360.0 / divs * i, 360.0 / divs * (i + 1)))

    # fs_mask1 = sector_mask((N,N),(N/2,N/2),fs_rad1*N,(0,360))
    fs_mask3 = np.logical_not(
        sector_mask((N, N), (N / 2, N / 2), fs_rad2 * N, (0, 360)))
    fs_mask = (fs_mask.astype(np.int)) * fs_mask3.astype(np.int)
    fs_mask = fs_mask / norm(fs_mask, 1)
    # riplot(rs_mask)
    riplot(fs_mask)

    fs_mask = fftshift(fs_mask)
    phase = np.ones_like(
        fs_mask
    )  # fftshift(nd.gaussian_filter(fftshift(np.pi*np.random.uniform(size=(N,N))),2))
    psi_f = fs_mask * np.exp(2j * phase)
    riplot(fftshift(psi_f))

    for i in range(50):
        # print i
        psi = ifft2(psi_f, norm='ortho')
        #        plotcx(psi)
        #    applot(psi,'psi')
        psir = psi.real
        psii = psi.imag
        #        psir = nd.gaussian_filter(psi.real,5)
        #        psii = nd.gaussian_filter(psi.imag,5)
        psi = rs_mask * (psir + 1j * psii)
        psi = psi / norm(psi)
        #        plotcx(psi)

        psi_f = fft2(psi, norm='ortho')
        #        plotcx(psi_f)
        #        applot(psi_f,'psi_f')
        #        riplot(fs_mask,'fs_mask')
        #        plotcx(fftshift(psi_f))
        #    psi_fangle = fftshift(nd.gaussian_filter(fftshift(np.angle(psi_f)),1))
        psi_fangle = np.angle(psi_f)
        psi_f = fs_mask * np.exp(1j * psi_fangle)
        psi_f = psi_f / norm(psi_f)
    # plotcx(psi_f)

    psi = ifft2(psi_f, norm='ortho')
    #        plotcx(psi)
    #    applot(psi,'psi')
    #    psir = psi.real
    #    psii = psi.imag
    #        psir = nd.gaussian_filter(psi.real,5)
    #        psii = nd.gaussian_filter(psi.imag,5)
    #    psi = rs_mask * np.exp(1j*np.angle(psi))
    #    psi = psi/norm(psi)
    #        plotcx(psi)

    #    psi_f = fft2(psi,norm='ortho')

    #    from skimage.restoration import unwrap_phase
    #    psi = ifft2(psi_f,norm='ortho')
    # plotcx(psi_f)
    # applot(psi)

    #    psia = nd.gaussian_filter(np.abs(psi),5)
    #    psip = nd.gaussian_filter(np.angle(psi),5)
    #    psi2 = psia * np.exp(1j*psip)
    ##    plotcx(psi2)
    #    angles = np.digitize(np.angle(psi2),np.arange(10)*np.pi/10) * np.pi/10
    #    psi3 = np.abs(psi2) * np.exp(1j*angles)
    #    plotcx(psi3)

    # plotcx(psi)
    #    psi_fabs = np.abs(psi_f)
    #
    #    psi_fangle = unwrap_phase(np.angle(psi_f))
    #    psi_fu = psi_fabs * np.exp(1j*psi_fangle)
    # applot(fftshift(psi_f))
    return np.real(psi).astype(np.float32), np.imag(psi).astype(np.float32)
Exemplo n.º 47
0
 def pass_through(u, noisef):
     U = fftshift(fft(u), axis=-1)
     U = U + U - noise_f
     u = ifft(fftshift(U, axis=-1))
     return u
Exemplo n.º 48
0
def main():
    from matplotlib.pyplot import semilogx, plot, show, xlim, ylim, figure, legend, subplot, bar
    from numpy.fft import fft, fftfreq, fftshift, ifft
    from numpy import log10, linspace, interp, angle, array, concatenate

    N = 2048 * 2 * 2
    fs = 44100.
    Nchannels = 20
    low_freq = 20.

    impulse = zeros(N)
    impulse[N / 2] = 1
    f = 1000.
    #impulse = sin(2*pi*f*arange(0, N/fs, 1./fs))

    #[ERBforward, ERBfeedback] = MakeERBFilters(fs, Nchannels, low_freq)
    #y = ERBFilterBank(ERBforward, ERBfeedback, impulse)

    BandsPerOctave = 3
    Nbands = NOCTAVE * BandsPerOctave

    [B, A, fi, fl, fh] = octave_filters(Nbands, BandsPerOctave)
    y, zfs = octave_filter_bank(B, A, impulse)
    #print "Filter lengths without decimation"
    #for b, a in zip(B, A):
    #	print len(b), len(a)

    response = 20. * log10(abs(fft(y)))
    freqScale = fftfreq(N, 1. / fs)

    figure()
    subplot(211)

    for i in range(0, response.shape[0]):
        semilogx(freqScale[0:N / 2], response[i, 0:N / 2])

    xlim(fs / 2000, fs)
    ylim(-70, 10)

    subplot(212)
    m = 0
    for f in fi:
        p = 10. * log10((y[m]**2).mean())
        m += 1
        semilogx(f, p, 'ko')

    Ndec = 3
    fc = 0.5
    # other possibilities
    #(bdec, adec) = ellip(Ndec, 0.05, 30, fc)
    #print bdec
    #(bdec, adec) = cheby1(Ndec, 0.05, fc)
    #(bdec, adec) = butter(Ndec, fc)
    (bdec, adec) = iirdesign(0.48,
                             0.50,
                             0.05,
                             70,
                             analog=0,
                             ftype='ellip',
                             output='ba')
    #bdec = firwin(30, fc)
    #adec = [1.]

    figure()
    subplot(211)

    response = 20. * log10(abs(fft(impulse)))
    plot(fftshift(freqScale), fftshift(response), label="impulse")

    y = lfilter(bdec, adec, impulse)
    response = 20. * log10(abs(fft(y)))
    plot(fftshift(freqScale), fftshift(response), label="lowpass")

    ydec = y[::2].repeat(2)
    response = 20. * log10(abs(fft(ydec)))
    plot(fftshift(freqScale),
         fftshift(response),
         label="lowpass + dec2 + repeat2")

    ydec2 = interp(range(0, len(y)), range(0, len(y), 2), y[::2])
    response = 20. * log10(abs(fft(ydec2)))
    plot(fftshift(freqScale),
         fftshift(response),
         label="lowpass + dec2 + interp2")

    ydec3 = y[::2]
    response = 20. * log10(abs(fft(ydec3)))
    freqScale2 = fftfreq(N / 2, 2. / fs)
    plot(freqScale2, fftshift(response), label="lowpass + dec2")

    legend(loc="lower left")

    subplot(212)
    plot(range(0, len(impulse)), impulse, label="impulse")
    plot(range(0, len(impulse)), y, label="lowpass")
    plot(range(0, len(impulse)), ydec, label="lowpass + dec2 + repeat2")
    plot(range(0, len(impulse)), ydec2, label="lowpass + dec2 + interp2")
    plot(range(0, len(impulse), 2), ydec3, label="lowpass + dec2")
    legend()

    [boct, aoct, fi, flow,
     fhigh] = octave_filters_oneoctave(Nbands, BandsPerOctave)
    y, dec, zfs = octave_filter_bank_decimation(bdec, adec, boct, aoct,
                                                impulse)
    #print "Filter lengths with decimation"
    #print len(bdec), len(adec)
    #for b, a in zip(boct, aoct):
    #	print len(b), len(a)

    figure()
    subplot(211)

    for yone, d in zip(y, dec):
        response = 20. * log10(abs(fft(yone)) * d)
        freqScale = fftfreq(N / d, 1. / (fs / d))
        semilogx(freqScale[0:N / (2 * d)], response[0:N / (2 * d)])

    xlim(fs / 2000, fs)
    ylim(-70, 10)

    subplot(212)
    m = 0
    for i in range(0, NOCTAVE):
        for f in fi:
            p = 10. * log10((y[m]**2).mean())
            semilogx(f / dec[m], p, 'ko')
            m += 1

    [boct, aoct, fi, flow,
     fhigh] = octave_filters_oneoctave(Nbands, BandsPerOctave)
    y1, dec, zfs = octave_filter_bank_decimation(bdec, adec, boct, aoct,
                                                 impulse[0:N / 2])
    y2, dec, zfs = octave_filter_bank_decimation(bdec,
                                                 adec,
                                                 boct,
                                                 aoct,
                                                 impulse[N / 2:],
                                                 zis=zfs)

    y = []
    for y1one, y2one in zip(y1, y2):
        y += [concatenate((y1one, y2one))]

    figure()
    subplot(211)

    for yone, d in zip(y, dec):
        response = 20. * log10(abs(fft(yone)) * d)
        freqScale = fftfreq(N / d, 1. / (fs / d))
        semilogx(freqScale[0:N / (2 * d)], response[0:N / (2 * d)])

    xlim(fs / 2000, fs)
    ylim(-70, 10)

    subplot(212)
    m = 0
    for i in range(0, NOCTAVE):
        for f in fi:
            p = 10. * log10((y[m]**2).mean())
            semilogx(f / dec[m], p, 'ko')
            m += 1

    generate_filters_params()

    show()
Exemplo n.º 49
0
def main():

    # Read Image in grayscale and show
    img = cv2.imread("input.jpg", 0)
    cv2.imwrite("orig.png", img)

    # --------------------------------------------------------------------------
    # Create Filter
    #
    # TODO: 3 Marks: Create sharpen filter from the lecture, but with a
    # Gaussian filter form the averaging instead of the mean filter. For the
    # Gaussian filter, use a kernel with size 31x31 with sigma 5. For the unit
    # impulse set the multiplier to be 2.

    # To get you started, here is a 1D Gaussian filter of size 31 and sigma=5
    filter1D = cv2.getGaussianKernel(31, 5)

    kernel = TODO

    # --------------------------------------------------------------------------

    # Filter with FFT
    #
    # --------------------------------------------------------------------------
    # TODO: 1 Mark: Pad filter with zeros to have the same size as the image,
    # but with the filter in the center. This creates a larger filter, that
    # effectively does the same thing as the original image.

    kernel_padded = TODO

    # --------------------------------------------------------------------------

    # Shift filter image to have origin on 0,0. This one is done for you. The
    # exact theory behind this was not explained in class so you may skip this
    # part.
    kernel_padded_shifted = fftshift(kernel_padded)

    # --------------------------------------------------------------------------
    # TODO: 1 Mark: Move all signal to Fourier space (DFT).

    img_fft = TODO
    kernel_fft = TODO

    # --------------------------------------------------------------------------

    # Display signals in Fourier Space
    # I put some visualization here to help debugging :-)
    cv2.imwrite("orig_fft.png",
                np.minimum(1e-5 * np.abs(fftshift(img_fft)), 1.0) * 255.)
    cv2.imwrite("filt_fft.png",
                np.minimum(1e-1 * np.abs(fftshift(kernel_fft)), 1.0) * 255.)

    # --------------------------------------------------------------------------
    # TODO: 1 Mark: Do filtering in Fourier space
    img_filtered_fft = TODO

    # --------------------------------------------------------------------------
    # TODO: 1 Mark: Bring back to Spatial domain (Inverse DFT)
    # TODO: 2 Marks: Throw away the imaginary part and clip between 0 and 255
    # to make it a real image.

    img_sharpened = TODO
    cv2.imwrite("res_fft.png", img_sharpened.astype(np.uint8))

    # --------------------------------------------------------------------------

    # ----------------------------------------------------------------------
    # Filter with OpenCV
    # TODO: 1 Mark: Use padded filter and cyclic padding (wrap) to get exact results
    # TOOD: 1 Mark: Clip image for display

    img_sharpened = TODO

    # --------------------------------------------------------------------------

    cv2.imwrite("res_opencv.png", img_sharpened.astype(np.uint8))

    cv2.waitKey(-1)
Exemplo n.º 50
0
def fftRatio(convolved, kernel):
    nf = len(convolved)
    convolved_pad = np.pad(convolved, (nf / 2, nf / 2), mode='constant')
    kernel_pad = np.pad(kernel, (nf / 2, nf / 2), mode='constant')
    return fft.fftshift(fft.fft(convolved_pad) / fft.fft(kernel_pad))
[p,p] = np.shape(A0)
mask = np.zeros([p,p],dtype=complex)


for x in range(p):
    for y in range(p):
        u = x-p/2+1
        v = y-p/2+1
        try:
            mask[x,y] = complex(u,v)/np.sqrt(u**2+v**2)
        except ZeroDivisionError:
            mask[x,y] = 0


A = A0-A180
A_ft = fftshift(fft2(A))
#h = mat2gray(abs(A_ft))
#cv2.imshow('FFT',h)

B_ft = A_ft*mask
B = ifft2(ifftshift(B_ft))
B = abs(B)

k = A+B*complex(0,1)
k1 = abs(k)
h = mat2gray(k1)*255
cv2.imwrite('hilbert.bmp',h)


Exemplo n.º 52
0
####################################################################################
# Plotting the magnitude 2D-FFT on a vertical log scales shows something unexpected:
# there appears to be peaks at the corners and no information at the center.
# This is because the output for the ‘fft2’ function flips the frequency axes so
# that low frequencies are at the ends, and the highest frequency is in the middle.
fig, axis = plt.subplots(figsize=(5, 5))
_ = px.plot_utils.plot_map(axis,
                           np.abs(fft_image_raw),
                           cmap=plt.cm.OrRd,
                           clim=[0, 3E+3])
axis.set_title('FFT2 of image')

####################################################################################
# To correct this, use the ‘fftshift’ command.
# fftshift brings the lowest frequency components of the FFT back to the center of the plot
fft_image_raw = npf.fftshift(fft_image_raw)
fft_abs_image_raw = np.abs(fft_image_raw)


def crop_center(image, cent_size=128):
    return image[image.shape[0] // 2 - cent_size // 2:image.shape[0] // 2 +
                 cent_size // 2, image.shape[1] // 2 -
                 cent_size // 2:image.shape[1] // 2 + cent_size // 2]


# After the fftshift, the FFT looks right
fig, axes = plt.subplots(ncols=2, figsize=(10, 5))
for axis, img, title in zip(
        axes,
    [fft_abs_image_raw, crop_center(fft_abs_image_raw)],
    ['FFT after fftshift-ing', 'Zoomed view around origin']):
Exemplo n.º 53
0
def vortex(mp, im, idm):
    """
    Differential model used to compute ctrl Jacobian for vortex coronagraph.

    Specialized compact model used to compute the DM response matrix, aka the
    control Jacobian for a vortex coronagraph. Can include an apodizer, making
    it an apodized vortex coronagraph (AVC). Does not include unknown
    aberrations of the full, "truth" model. This model propagates the
    first-order Taylor expansion of the phase from the poke of each actuator
    of the deformable mirror.

    Parameters
    ----------
    mp : ModelParameters
        Structure containing optical model parameters

    Returns
    -------
    Gzdl : numpy ndarray
        Complex-valued, 2-D array containing the Jacobian for the
        specified Zernike mode, DM number, and wavelength.

    """
    modvar = falco.config.Object()  # Initialize the new structure
    modvar.sbpIndex = mp.jac.sbp_inds[im]
    modvar.zernIndex = mp.jac.zern_inds[im]

    wvl = mp.sbp_centers[modvar.sbpIndex]
    mirrorFac = 2.  # Phase change is twice the DM surface height.
    NdmPad = int(mp.compact.NdmPad)

    if mp.flagRotation:
        NrelayFactor = 1
    else:
        NrelayFactor = 0  # zero out the number of relays

    # Minimum FPM resolution for Jacobian calculations (in pixels per lambda/D)
    minPadFacVortex = 8

    # Get FPM charge
    if type(mp.F3.VortexCharge) == np.ndarray:
        # Passing an array for mp.F3.VortexCharge with
        # corresponding wavelengths mp.F3.VortexCharge_lambdas
        # represents a chromatic vortex FPM
        if mp.F3.VortexCharge.size == 1:
            charge = mp.F3.VortexCharge
        else:
            np.interp(wvl, mp.F3.VortexCharge_lambdas, mp.F3.VortexCharge,
                      'linear', 'extrap')
    elif type(mp.F3.VortexCharge) == int or type(mp.F3.VortexCharge) == float:
        # single value indicates fully achromatic mask
        charge = mp.F3.VortexCharge
    else:
        raise TypeError(
            "mp.F3.VortexCharge must be an int, float, or numpy ndarray.")
    """Input E-fields"""
    Ein = np.squeeze(mp.P1.compact.E[:, :, modvar.sbpIndex])

    # Apply a Zernike (in amplitude) at input pupil
    # Used only for Zernike sensitivity control, which requires the perfect
    # E-field of the differential Zernike term.
    if not modvar.zernIndex == 1:
        indsZnoll = modvar.zernIndex  # Just send in 1 Zernike mode
        zernMat = np.squeeze(
            falco.zern.gen_norm_zern_maps(mp.P1.compact.Nbeam, mp.centering,
                                          indsZnoll))
        zernMat = pad_crop(zernMat, mp.P1.compact.Narr)
        Ein = Ein*zernMat*(2*np.pi/wvl) * \
            mp.jac.Zcoef[mp.jac.zerns == modvar.zernIndex]
    """ Masks and DM surfaces """
    pupil = pad_crop(mp.P1.compact.mask, NdmPad)
    Ein = pad_crop(Ein, NdmPad)

    # Re-image the apodizer from pupil P3 back to pupil P2.
    if (mp.flagApod):
        apodReimaged = pad_crop(mp.P3.compact.mask, NdmPad)
        apodReimaged = fp.relay(apodReimaged, NrelayFactor * mp.Nrelay2to3,
                                mp.centering)
    else:
        apodReimaged = np.ones((NdmPad, NdmPad))

    # Compute the DM surfaces for the current DM commands
    if any(mp.dm_ind == 1):
        DM1surf = pad_crop(mp.dm1.compact.surfM, NdmPad)
        # DM1surf = falco.dm.gen_surf_from_act(mp.dm1, mp.dm1.compact.dx, NdmPad)
    else:
        DM1surf = np.zeros((NdmPad, NdmPad))
    if any(mp.dm_ind == 2):
        DM2surf = pad_crop(mp.dm2.compact.surfM, NdmPad)
        # DM2surf = falco.dm.gen_surf_from_act(mp.dm2, mp.dm2.compact.dx, NdmPad)
    else:
        DM2surf = np.zeros((NdmPad, NdmPad))

    if (mp.flagDM1stop):
        DM1stop = pad_crop(mp.dm1.compact.mask, NdmPad)
    else:
        DM1stop = np.ones((NdmPad, NdmPad))
    if (mp.flagDM2stop):
        DM2stop = pad_crop(mp.dm2.compact.mask, NdmPad)
    else:
        DM2stop = np.ones((NdmPad, NdmPad))

    # This block is for BMC surface error testing
    if (mp.flagDMwfe):
        if any(mp.dm_ind == 1):
            Edm1WFE = np.exp(
                2 * np.pi * 1j / wvl *
                pad_crop(mp.dm1.compact.wfe, NdmPad, 'extrapval', 0))
        else:
            Edm1WFE = np.ones((NdmPad, NdmPad))
        if any(mp.dm_ind == 2):
            Edm2WFE = np.exp(
                2 * np.pi * 1j / wvl *
                pad_crop(mp.dm2.compact.wfe, NdmPad, 'extrapval', 0))
        else:
            Edm2WFE = np.ones((NdmPad, NdmPad))
    else:
        Edm1WFE = np.ones((NdmPad, NdmPad))
        Edm2WFE = np.ones((NdmPad, NdmPad))
    """Propagation"""
    # Define pupil P1 and Propagate to pupil P2
    EP1 = pupil * Ein  # E-field at pupil plane P1
    EP2 = fp.relay(EP1, NrelayFactor * mp.Nrelay1to2, mp.centering)

    # Propagate from P2 to DM1, and apply DM1 surface and aperture stop
    if not (abs(mp.d_P2_dm1) == 0):  # E-field arriving at DM1
        Edm1 = fp.ptp(EP2, mp.P2.compact.dx * NdmPad, wvl, mp.d_P2_dm1)
    else:
        Edm1 = EP2
    Edm1out = Edm1 * Edm1WFE * DM1stop * np.exp(
        mirrorFac * 2 * np.pi * 1j * DM1surf / wvl)
    """ ---------- DM1 ---------- """
    if idm == 1:
        Gzdl = np.zeros((mp.Fend.corr.Npix, mp.dm1.Nele), dtype=complex)

        # Array size for planes P3, F3, and P4
        Nfft1 = int(2**falco.util.nextpow2(
            np.max(
                np.array([
                    mp.dm1.compact.NdmPad,
                    minPadFacVortex * mp.dm1.compact.Nbox
                ]))))  # Don't crop--but do pad if necessary.

        # Generate vortex FPM with fftshift already applied
        fftshiftVortex = fftshift(
            falco.mask.falco_gen_vortex_mask(charge, Nfft1))

        # Two array sizes (at same resolution) of influence functions for MFT and angular spectrum
        NboxPad1AS = int(
            mp.dm1.compact.NboxAS
        )  # array size for FFT-AS propagations from DM1->DM2->DM1
        mp.dm1.compact.xy_box_lowerLeft_AS = mp.dm1.compact.xy_box_lowerLeft - (
            mp.dm1.compact.NboxAS - mp.dm1.compact.Nbox
        ) / 2.  # Adjust the sub-array location of the influence function for the added zero padding

        if any(mp.dm_ind == 2):
            DM2surf = pad_crop(DM2surf, mp.dm1.compact.NdmPad)
        else:
            DM2surf = np.zeros((mp.dm1.compact.NdmPad, mp.dm1.compact.NdmPad))
        if (mp.flagDM2stop):
            DM2stop = pad_crop(DM2stop, mp.dm1.compact.NdmPad)
        else:
            DM2stop = np.ones((mp.dm1.compact.NdmPad, mp.dm1.compact.NdmPad))
        apodReimaged = pad_crop(apodReimaged, mp.dm1.compact.NdmPad)

        Edm1pad = pad_crop(Edm1out, mp.dm1.compact.NdmPad
                           )  # Pad or crop for expected sub-array indexing
        Edm2WFEpad = pad_crop(Edm2WFE, mp.dm1.compact.NdmPad
                              )  # Pad or crop for expected sub-array indexing

        # Propagate each actuator from DM1 through the optical system
        Gindex = 0  # initialize index counter
        for iact in mp.dm1.act_ele:
            # Compute only for influence functions that are not zeroed out
            if np.sum(np.abs(mp.dm1.compact.inf_datacube[:, :, iact])) > 1e-12:

                # x- and y- coordinate indices of the padded influence function in the full padded pupil
                x_box_AS_ind = np.arange(
                    mp.dm1.compact.xy_box_lowerLeft_AS[0, iact],
                    mp.dm1.compact.xy_box_lowerLeft_AS[0, iact] + NboxPad1AS,
                    dtype=int)  # x-indices in pupil arrays for the box
                y_box_AS_ind = np.arange(
                    mp.dm1.compact.xy_box_lowerLeft_AS[1, iact],
                    mp.dm1.compact.xy_box_lowerLeft_AS[1, iact] + NboxPad1AS,
                    dtype=int)  # y-indices in pupil arrays for the box
                indBoxAS = np.ix_(y_box_AS_ind, x_box_AS_ind)
                # x- and y- coordinates of the UN-padded influence function in the full padded pupil
                x_box = mp.dm1.compact.x_pupPad[
                    x_box_AS_ind]  # full pupil x-coordinates of the box
                y_box = mp.dm1.compact.y_pupPad[
                    y_box_AS_ind]  # full pupil y-coordinates of the box

                # Propagate from DM1 to DM2, and then back to P2
                dEbox = (mirrorFac * 2 * np.pi * 1j / wvl) * pad_crop(
                    (mp.dm1.VtoH.reshape(mp.dm1.Nact**2)[iact]) * np.squeeze(
                        mp.dm1.compact.inf_datacube[:, :, iact]), NboxPad1AS
                )  # Pad influence function at DM1 for angular spectrum propagation.
                dEbox = fp.ptp(
                    dEbox * Edm1pad[indBoxAS], mp.P2.compact.dx * NboxPad1AS,
                    wvl, mp.d_dm1_dm2
                )  # forward propagate to DM2 and apply DM2 E-field
                dEP2box = fp.ptp(
                    dEbox * Edm2WFEpad[indBoxAS] * DM2stop[indBoxAS] * np.exp(
                        mirrorFac * 2 * np.pi * 1j / wvl * DM2surf[indBoxAS]),
                    mp.P2.compact.dx * NboxPad1AS, wvl,
                    -1 * (mp.d_dm1_dm2 + mp.d_P2_dm1))  # back-propagate to DM1
                #                dEbox = fp.ptp_inf_func(dEbox*Edm1pad[np.ix_(y_box_AS_ind,x_box_AS_ind)], mp.P2.compact.dx*NboxPad1AS,wvl, mp.d_dm1_dm2, mp.dm1.dm_spacing, mp.propMethodPTP) # forward propagate to DM2 and apply DM2 E-field
                #                dEP2box = fp.ptp_inf_func(dEbox.*Edm2WFEpad[np.ix_(y_box_AS_ind,x_box_AS_ind)]*DM2stop(y_box_AS_ind,x_box_AS_ind).*exp(mirrorFac*2*np.pi*1j/wvl*DM2surf(y_box_AS_ind,x_box_AS_ind)), mp.P2.compact.dx*NboxPad1AS,wvl,-1*(mp.d_dm1_dm2 + mp.d_P2_dm1), mp.dm1.dm_spacing, mp.propMethodPTP ) # back-propagate to DM1
                #
                # To simulate going forward to the next pupil plane (with the apodizer) most efficiently,
                # First, back-propagate the apodizer (by rotating 180-degrees) to the previous pupil.
                # Second, negate the coordinates of the box used.
                dEP2boxEff = apodReimaged[
                    indBoxAS] * dEP2box  # Apply 180deg-rotated apodizer mask.
                # dEP3box = np.rot90(dEP2box,k=2*mp.Nrelay2to3) # Forward propagate the cropped box by rotating 180 degrees mp.Nrelay2to3 times.
                # # Negate and reverse coordinate values to effectively rotate by 180 degrees. No change if 360 degree rotation.

                # Re-insert the window around the influence function back into the full beam array.
                EP2eff = np.zeros(
                    (mp.dm1.compact.NdmPad, mp.dm1.compact.NdmPad),
                    dtype=complex)
                EP2eff[indBoxAS] = dEP2boxEff

                # Forward propagate from P2 (effective) to P3
                EP3 = fp.relay(EP2eff, NrelayFactor * mp.Nrelay2to3,
                               mp.centering)

                # Pad pupil P3 for FFT
                EP3pad = pad_crop(EP3, Nfft1)

                # FFT from P3 to Fend.and apply vortex
                EF3 = fftshiftVortex * fft2(fftshift(EP3pad)) / Nfft1

                # FFT from Vortex FPM to Lyot Plane
                EP4 = fftshift(fft2(EF3)) / Nfft1
                EP4 = fp.relay(
                    EP4, NrelayFactor * mp.Nrelay3to4 - 1,
                    mp.centering)  # Add more re-imaging relays if necessary
                if (Nfft1 > mp.P4.compact.Narr):
                    EP4 = mp.P4.compact.croppedMask * pad_crop(
                        EP4, mp.P4.compact.Narr
                    )  # Crop EP4 and then apply Lyot stop
                else:
                    EP4 = pad_crop(
                        mp.P4.compact.croppedMask,
                        Nfft1) * EP4  # Crop the Lyot stop and then apply it.
                    pass

                # MFT to camera
                EP4 = fp.relay(
                    EP4, NrelayFactor * mp.NrelayFend, mp.centering
                )  # Rotate the final image 180 degrees if necessary
                EFend = fp.mft_p2f(EP4, mp.fl, wvl, mp.P4.compact.dx,
                                   mp.Fend.dxi, mp.Fend.Nxi, mp.Fend.deta,
                                   mp.Fend.Neta, mp.centering)

                Gzdl[:, Gindex] = EFend[mp.Fend.corr.maskBool] / np.sqrt(
                    mp.Fend.compact.I00[modvar.sbpIndex])

            Gindex += 1
    """ ---------- DM2 ---------- """
    if idm == 2:
        Gzdl = np.zeros((mp.Fend.corr.Npix, mp.dm2.Nele), dtype=complex)

        # Array size for planes P3, F3, and P4
        Nfft2 = int(2**falco.util.nextpow2(
            np.max(
                np.array([
                    mp.dm2.compact.NdmPad,
                    minPadFacVortex * mp.dm2.compact.Nbox
                ]))))  # Don't crop--but do pad if necessary.

        # Generate vortex FPM with fftshift already applied
        fftshiftVortex = fftshift(
            falco.mask.falco_gen_vortex_mask(charge, Nfft2))

        # Two array sizes (at same resolution) of influence functions for MFT and angular spectrum
        NboxPad2AS = int(mp.dm2.compact.NboxAS)
        mp.dm2.compact.xy_box_lowerLeft_AS = mp.dm2.compact.xy_box_lowerLeft - (
            NboxPad2AS - mp.dm2.compact.Nbox
        ) / 2  # Account for the padding of the influence function boxes

        apodReimaged = pad_crop(apodReimaged, mp.dm2.compact.NdmPad)
        DM2stopPad = pad_crop(DM2stop, mp.dm2.compact.NdmPad)
        Edm2WFEpad = pad_crop(Edm2WFE, mp.dm2.compact.NdmPad)

        # Propagate full field to DM2 before back-propagating in small boxes
        Edm2inc = pad_crop(
            fp.ptp(Edm1out, mp.compact.NdmPad * mp.P2.compact.dx, wvl,
                   mp.d_dm1_dm2),
            mp.dm2.compact.NdmPad)  # E-field incident upon DM2
        Edm2inc = pad_crop(Edm2inc, mp.dm2.compact.NdmPad)
        Edm2 = DM2stopPad * Edm2WFEpad * Edm2inc * np.exp(
            mirrorFac * 2 * np.pi * 1j / wvl *
            pad_crop(DM2surf, mp.dm2.compact.NdmPad)
        )  # Initial E-field at DM2 including its own phase contribution

        # Propagate each actuator from DM2 through the rest of the optical system
        Gindex = 0  # initialize index counter
        for iact in mp.dm2.act_ele:
            # Only compute for acutators specified for use or for influence functions that are not zeroed out
            if np.sum(np.abs(mp.dm2.compact.inf_datacube[:, :, iact])) > 1e-12:

                # x- and y- coordinates of the padded influence function in the full padded pupil
                x_box_AS_ind = np.arange(
                    mp.dm2.compact.xy_box_lowerLeft_AS[0, iact],
                    mp.dm2.compact.xy_box_lowerLeft_AS[0, iact] + NboxPad2AS,
                    dtype=int)  # x-indices in pupil arrays for the box
                y_box_AS_ind = np.arange(
                    mp.dm2.compact.xy_box_lowerLeft_AS[1, iact],
                    mp.dm2.compact.xy_box_lowerLeft_AS[1, iact] + NboxPad2AS,
                    dtype=int)  # y-indices in pupil arrays for the box
                indBoxAS = np.ix_(y_box_AS_ind, x_box_AS_ind)
                #               # x- and y- coordinates of the UN-padded influence function in the full padded pupil
                #                x_box = mp.dm2.compact.x_pupPad[x_box_AS_ind] # full pupil x-coordinates of the box
                #                y_box = mp.dm2.compact.y_pupPad[y_box_AS_ind] # full pupil y-coordinates of the box

                dEbox = (mp.dm2.VtoH.reshape(mp.dm2.Nact**2)[iact]) * (
                    mirrorFac * 2 * np.pi * 1j / wvl) * pad_crop(
                        np.squeeze(mp.dm2.compact.inf_datacube[:, :, iact]),
                        NboxPad2AS)  # the padded influence function at DM2
                dEP2box = fp.ptp(
                    dEbox * Edm2[indBoxAS], mp.P2.compact.dx * NboxPad2AS, wvl,
                    -1 *
                    (mp.d_dm1_dm2 + mp.d_P2_dm1))  # back-propagate to pupil P2
                #                dEP2box = ptp_inf_func(dEbox.*Edm2(y_box_AS_ind,x_box_AS_ind), mp.P2.compact.dx*NboxPad2AS,wvl,-1*(mp.d_dm1_dm2 + mp.d_P2_dm1), mp.dm2.dm_spacing, mp.propMethodPTP); # back-propagate to pupil P2

                # To simulate going forward to the next pupil plane (with the apodizer) most efficiently,
                # First, back-propagate the apodizer (by rotating 180-degrees) to the previous pupil.
                # Second, negate the coordinates of the box used.
                dEP2boxEff = apodReimaged[indBoxAS] * dEP2box
                #                dEP3box = np.rot90(dEP2box,k=2*mp.Nrelay2to3) # Forward propagate the cropped box by rotating 180 degrees mp.Nrelay2to3 times.
                #                # Negate and rotate coordinates to effectively rotate by 180 degrees. No change if 360 degree rotation.
                #                if np.mod(mp.Nrelay2to3,2)==1:
                #                    x_box = -1*x_box[::-1]
                #                    y_box = -1*y_box[::-1]

                EP2eff = np.zeros(
                    (mp.dm2.compact.NdmPad, mp.dm2.compact.NdmPad),
                    dtype=complex)
                EP2eff[indBoxAS] = dEP2boxEff

                # Forward propagate from P2 (effective) to P3
                EP3 = fp.relay(EP2eff, NrelayFactor * mp.Nrelay2to3,
                               mp.centering)

                # Pad pupil P3 for FFT
                EP3pad = pad_crop(EP3, Nfft2)

                # FFT from P3 to Fend.and apply vortex
                EF3 = fftshiftVortex * fft2(fftshift(EP3pad)) / Nfft2

                # FFT from Vortex FPM to Lyot Plane
                EP4 = fftshift(fft2(EF3)) / Nfft2
                EP4 = fp.relay(EP4, NrelayFactor * mp.Nrelay3to4 - 1,
                               mp.centering)

                if (Nfft2 > mp.P4.compact.Narr):
                    EP4 = mp.P4.compact.croppedMask * pad_crop(
                        EP4, mp.P4.compact.Narr)
                else:
                    EP4 = pad_crop(mp.P4.compact.croppedMask, Nfft2) * EP4

                # MFT to detector
                EP4 = fp.relay(EP4, NrelayFactor * mp.NrelayFend, mp.centering)
                EFend = fp.mft_p2f(EP4, mp.fl, wvl, mp.P4.compact.dx,
                                   mp.Fend.dxi, mp.Fend.Nxi, mp.Fend.deta,
                                   mp.Fend.Neta, mp.centering)

                Gzdl[:, Gindex] = EFend[mp.Fend.corr.maskBool] / \
                    np.sqrt(mp.Fend.compact.I00[modvar.sbpIndex])

            Gindex += 1

    return Gzdl
Exemplo n.º 54
0
 def noise_func_freq(self, int_fwm, sim_wind):
     self.noise = self.noise_func(int_fwm)
     noise_freq = fftshift(fft(self.noise), axes=-1)
     return noise_freq
Exemplo n.º 55
0
    def interpolate_subband(self, nfi, df, f0, full_output=False):
        '''
        interpolates a sub-band between fMin and fMax by 
        taking a windowed FFT at a bandwidth twice the
        requested bandwidth, extrapolating and interpolating 
        the delay-transform transform, and FT-ing back. 
        '''
        change_nfi = False
        fMin = f0 - nfi / 2 * df
        if fMin < self.fAxis.min():
            fMin = self.fAxis.min()
            change_nfi = True
        fMax = f0 + (nfi / 2 - 1) * df
        if fMax > self.fAxis.max():
            fMax = self.fAxis.max()
            change_nfi = True
        if change_nfi:
            nfi = int(np.round(fMax / df - fMin / df))
            f0 = fMin + nfi / 2 * df
        fAxis_interp = f0 + np.arange(-nfi / 2, nfi / 2) * df
        tAxis_interp = fft.fftshift(fft.fftfreq(nfi, df))
        b = fMax - fMin
        select_max = np.min([self.fAxis.max(), f0 + b])
        select_min = np.max([self.fAxis.min(), f0 - b])
        selection = np.logical_and(self.fAxis >= select_min,
                                   self.fAxis <= select_max)
        nf = len(self.fAxis[selection])
        if np.mod(nf, 2) == 1:
            nf += 1
            maxind = np.where(selection)[0].max()
            if maxind < len(selection) - 1:
                selection[maxind + 1] = True
            else:
                minind = np.where(selection)[0].min()
                if minind > 0:
                    selection[minind - 1] = True
                else:
                    nf -= 2
                    selection[maxind] = False

        sub_band = self.gainFrequency[selection]
        sub_fAxis = self.fAxis[selection]
        window = signal.blackmanharris(nf)
        delay_band = fft.fftshift(fft.ifft(fft.fftshift(sub_band * window)))
        sub_tAxis = fft.fftshift(
            fft.fftfreq(len(sub_band), self.fAxis[1] - self.fAxis[0]))
        maxTime = sub_tAxis.max()
        minTimeExt = maxTime * 1. / 3.
        maxTimeExt = maxTime * 2. / 3.
        ext_select = np.logical_and(sub_tAxis <= maxTimeExt,
                                    sub_tAxis >= minTimeExt)
        ext_poly = np.polyfit(sub_tAxis[ext_select],
                              np.log10(np.abs(delay_band[ext_select])), 1)
        interp_func_abs = interp.interp1d(sub_tAxis,
                                          np.log10(np.abs(delay_band)))
        interp_func_arg = interp.interp1d(sub_tAxis, np.angle(delay_band))
        band_interp = np.zeros(nfi, dtype=complex)
        select_interp = np.logical_and(tAxis_interp >= 0,
                                       tAxis_interp < maxTimeExt)
        band_interp[select_interp] = 10**(interp_func_abs(
            tAxis_interp[select_interp])) * np.exp(
                1j * interp_func_arg(tAxis_interp[select_interp]))
        select_ext = tAxis_interp >= maxTimeExt
        band_interp[select_ext] = 10**(tAxis_interp[select_ext] * ext_poly[0] +
                                       ext_poly[1])
        #band_interp[select_ext]=0.
        window_interp_func = interp.interp1d(
            sub_fAxis, signal.blackmanharris(len(sub_band)))
        wFactor = 1. / ((fAxis_interp.max() - fAxis_interp.min()) /
                        (sub_fAxis.max() - sub_fAxis.min()))
        if DEBUG:
            print(wFactor)
        band_interp_f = fft.fftshift(fft.fft(
            fft.fftshift(band_interp))) * wFactor
        window_corr = window_interp_func(fAxis_interp)
        #band_interp_f/=window_corr
        if full_output:
            return sub_tAxis, delay_band, sub_fAxis, sub_band, tAxis_interp, band_interp, fAxis_interp, band_interp_f
        else:
            return fAxis_interp, band_interp_f
Exemplo n.º 56
0
    def compute_pspec(self,
                      beam_correct=False,
                      apodize_kernel=None,
                      alpha=0.3,
                      beta=0.0,
                      use_pyfftw=False,
                      threads=1,
                      **pyfftw_kwargs):
        '''
        Compute the 2D power spectrum.

        Parameters
        ----------
        beam_correct : bool, optional
            If a beam object was given, divide the 2D FFT by the beam response.
        apodize_kernel : None or 'splitcosinebell', 'hanning', 'tukey', 'cosinebell', 'tophat'
            If None, no apodization kernel is applied. Otherwise, the type of
            apodizing kernel is given.
        alpha : float, optional
            alpha shape parameter of the apodization kernel. See
            `~turbustat.apodizing_kernel` for more information.
        beta : float, optional
            beta shape parameter of the apodization kernel. See
            `~turbustat.apodizing_kernel` for more information.
        use_pyfftw : bool, optional
            Enable to use pyfftw, if it is installed.
        threads : int, optional
            Number of threads to use in FFT when using pyfftw.
        pyfftw_kwargs : Passed to
            `~turbustat.statistics.rfft_to_fft.rfft_to_fft`. See
            `here <http://hgomersall.github.io/pyFFTW/pyfftw/builders/builders.html>`__
            for a list of accepted kwargs.
        '''

        if apodize_kernel is not None:
            apod_kernel = self.apodizing_kernel(kernel_type=apodize_kernel,
                                                alpha=alpha,
                                                beta=beta)
            data = self.data * apod_kernel
        else:
            data = self.data

        if pyfftw_kwargs.get('threads') is not None:
            pyfftw_kwargs.pop('threads')

        fft = fftshift(
            rfft_to_fft(data,
                        use_pyfftw=use_pyfftw,
                        threads=threads,
                        **pyfftw_kwargs))

        if beam_correct:
            if not hasattr(self, '_beam'):
                raise AttributeError("Beam correction cannot be applied since"
                                     " no beam object was given.")

            beam_kern = self._beam.as_kernel(self._wcs.wcs.cdelt[0] * u.deg,
                                             y_size=self.data.shape[1],
                                             x_size=self.data.shape[2])

            beam_fft = fftshift(rfft_to_fft(beam_kern.array))

            self._beam_pow = np.abs(beam_fft**2)

        self._ps2D = np.power(fft, 2.).sum(axis=0)

        if beam_correct:
            self._ps2D /= self._beam_pow
Exemplo n.º 57
0
    def read_files(self,
                   fileName,
                   fileType,
                   fMin=None,
                   fMax=None,
                   windowFunction=None,
                   comment='',
                   filterNegative=False,
                   extrapolateBand=False,
                   changeZ=False,
                   z0=100,
                   z1=100):
        if DEBUG:
            print fileType
        assert fileType in FILETYPES
        if (windowFunction is None):
            windowFunction = 'blackman-harris'
        self.windowFunction = windowFunction
        if (fileType == 'CST_TimeTrace' or fileType == 'Nicolas'):
            if fileType == 'CST_TimeTrace':
                [inputTrace, outputTrace,
                 _], self.metaData = readCSTTimeTrace(fileName,
                                                      comment=comment)
            elif fileType == 'Nicolas':
                [inputTrace, outputTrace] = readNicholasTimeTrace(fileName)
            if np.mod(len(inputTrace), 2) == 1:
                inputTrace = np.vstack([inputTrace[0, :], inputTrace])
                inputTrace[0, 0] -= (inputTrace[2, 0] - inputTrace[1, 0])
                outputTrace = np.vstack([outputTrace[0, :], outputTrace])
                outputTrace[0, 0] -= (outputTrace[2, 0] - outputTrace[1, 0])
            #plt.plot(inputTrace[:,0],inputTrace[:,1])
            #plt.plot(outputTrace[:,0],outputTrace[:,1])
            #plt.show()
            self.fAxis = fft.fftshift(
                fft.fftfreq(
                    len(inputTrace) * 2, inputTrace[1, 0] - inputTrace[0, 0]))
            self.gainFrequency = fftRatio(outputTrace[:, 1], inputTrace[:, 1])

        elif (fileType == 'CST_S11'):
            self.fAxis, self.gainFrequency, self.metaData = readCSTS11(
                fileName, comment=comment)
        elif (fileType == 'VNAHP_S11'):
            self.fAxis, self.gainFrequency, self.metaData = readVNAHP(
                fileName, comment=comment)
        elif (fileType == 'S11_CSV'):
            self.fAxis, self.gainFrequency, self.metaData = readCSV(
                fileName, comment=comment)
        elif (fileType == 'S11_S1P'):
            self.fAxis, self.gainFrequency, self.metaData = readS1P(
                fileName, comment=comment)
        elif (fileType == 'ANRITSU_CSV'):
            self.fAxis, self.gainFrequency, self.metaData = readAnritsu(
                fileName, comment=comment)
        if (fMin is None):
            fMin = self.fAxis.min()
        if (fMax is None):
            fMax = self.fAxis.max()
        if (extrapolateBand):
            if DEBUG:
                print(self.fAxis.min())
                print(self.fAxis.max())
            if (fMin < self.fAxis.min()):
                fitSelection = self.fAxis < self.fAxis.min() + .01
                pReal = np.polyfit(self.fAxis[fitSelection],
                                   np.real(self.gainFrequency[fitSelection]),
                                   1)
                pImag = np.polyfit(self.fAxis[fitSelection],
                                   np.imag(self.gainFrequency[fitSelection]),
                                   1)
                fLow = np.arange(self.fAxis.min(), fMin,
                                 self.fAxis[0] - self.fAxis[1])
                self.fAxis = np.hstack([fLow[::-1], self.fAxis])
                self.gainFrequency = np.hstack([
                    pReal[0] * fLow[::-1] + pReal[1] + 1j *
                    (pImag[0] * fLow[::-1] + pImag[1]), self.gainFrequency
                ])
                #plt.plot(self.fAxis[fitSelection],np.real(self.gainFrequency[fitSelection]),ls='none',marker='o')
                #plt.plot(self.fAxis[fitSelection],self.fAxis[fitSelection]*pReal[0]+pReal[1],ls='--',color='r')
                #plt.plot(fLow[::-1],fLow[::-1]*pReal[0]+pReal[1],color='k')
                #plt.show()
            if (fMax > self.fAxis.max()):
                fitSelection = self.fAxis > self.fAxis.max() - .01
                pReal = np.polyfit(self.fAxis[fitSelection],
                                   np.real(self.gainFrequency[fitSelection]),
                                   1)
                pImag = np.polyfit(self.fAxis[fitSelection],
                                   np.imag(self.gainFrequency[fitSelection]),
                                   1)
                fHigh = np.arange(self.fAxis.max(), fMax,
                                  self.fAxis[1] - self.fAxis[0])
                self.fAxis = np.hstack([self.fAxis, fHigh])
                self.gainFrequency = np.hstack([
                    self.gainFrequency, pReal[0] * fHigh + pReal[1] + 1j *
                    (pImag[0] * fHigh + pImag[1])
                ])

        selection = np.logical_and(self.fAxis >= fMin, self.fAxis <= fMax)
        nf = len(np.where(selection)[0])
        if np.mod(nf, 2) == 1:
            nf += 1
            maxind = np.where(selection)[0].max()
            if maxind < len(selection) - 1:
                selection[maxind + 1] = True
            else:
                minind = np.where(selection)[0].min()
                if minind > 0:
                    selection[minind - 1] = True
                else:
                    nf -= 2
                    selection[maxind] = False

        self.fAxis = self.fAxis[selection]
        self.gainFrequency = self.gainFrequency[selection]
        if (windowFunction == 'blackman-harris'):
            wF = signal.blackmanharris(len(self.fAxis))
            wF /= np.sqrt(np.mean(wF**2.))
        else:
            wF = np.ones(len(self.fAxis))
        self.tAxis = fft.fftshift(
            fft.fftfreq(len(self.fAxis), self.fAxis[1] - self.fAxis[0]))
        if (filterNegative):
            gainDelay = fft.fftshift(fft.ifft(fft.fftshift(
                self.gainFrequency)))
            gainDelay[self.tAxis < 0.] = 0.
            self.gainFrequency = fft.fftshift(fft.fft(fft.fftshift(gainDelay)))
        self.gainDelay = fft.fftshift(
            fft.ifft(fft.fftshift(self.gainFrequency * wF)))
        if changeZ:
            self.change_impedance(z0, z1)
Exemplo n.º 58
0
def psd_to_psf(psd,
               pup,
               D,
               lbda,
               phase_static=None,
               samp=None,
               FoV=None,
               return_all=False):
    """Computation of a PSF from a residual phase PSD and a pupil shape.

    Programme pour prendre en compte la multi-analyse les geometries
    d'etoiles et la postion de la galaxie.

    FUNCTION psd_to_psf, dsp, pup, local_L, osamp

    PSD: 2D array with PSD values (in nm² per freq² at the PSF wavelength)
    pup: 2D array representing the pupill
    Samp: final PSF sampling (number of pixel in the diffraction). Min = 2 !
    FoV  : PSF FoV (in arcsec)
    lbda : PSF wavelength in m
    D = pupil diameter
    phase_static in nm

    """
    dim = psd.shape[0]
    npup = pup.shape[0]
    sampnum = dim / npup  # numerical sampling related to PSD vs pup dimension
    L = D * sampnum  # Physical size of the PSD

    if dim < 2 * npup:
        logger.info("the PSD horizon must be at least two time larger than "
                    "the pupil diameter")

    # from PSD to structure function
    convnm = 2 * np.pi / (lbda * 1e9)  # nm to rad
    bg = ifft2(fftshift(psd * convnm**2)) * (psd.size / L**2)

    # creation of the structure function
    Dphi = 2 * (bg[0, 0].real - bg.real)
    Dphi = fftshift(Dphi)

    # Extraction of the pupil part of the structure function
    sampin = samp if samp is not None else sampnum
    if samp < 2:
        logger.info('PSF should be at least nyquist sampled')

    # even dimension of the num psd
    dimnum = int(np.fix(dim * (sampin / sampnum) / 2)) * 2
    sampout = dimnum / npup  # real sampling

    if samp <= sampnum:
        ns = sampout * npup / 2
        sl = slice(int(dim / 2 - ns), int(dim / 2 + ns))
        Dphi2 = Dphi[sl, sl]
    else:
        Dphi2 = np.zeros(dimnum,
                         dimnum) + (Dphi[0, 0] + Dphi[dim - 1, dim - 1] +
                                    Dphi[0, dim - 1] + Dphi[dim - 1, 0]) / 4
        sl = slice(int(dimnum / 2 - dim / 2), int(dimnum / 2 + dim / 2))
        Dphi2[sl, sl] = Dphi
        logger.warning('Sampling > Dim DSP / Dim pup => extrapolation !!! '
                       'We recommmend to increase the PSD size')

    logger.debug(
        'input sampling: %.2f, output sampling: %.2f, max num sampling: %.2f',
        sampin, sampout, sampnum)

    # increasing the FoV PSF means oversampling the pupil
    FoVnum = (lbda / (sampnum * D)) * dim / (4.85 * 1.e-6)
    if FoV is None:
        FoV = FoVnum
    overFoV = FoV / FoVnum

    if not np.allclose(FoV, FoVnum):
        dimover = int(np.fix(dimnum * overFoV / 2)) * 2
        xxover = np.arange(dimover) / dimover * dimnum
        Dphi2 = np.maximum(interpolate(Dphi2, xxover, method='cubic'), 0)

        npupover = int(np.fix(npup * overFoV / 2)) * 2
        xxpupover = np.arange(npupover) / npupover * npup
        pupover = np.maximum(interpolate(pup, xxpupover, method='cubic'), 0)
    else:
        dimover = dimnum
        npupover = npup
        pupover = pup

    if phase_static is not None:
        npups = phase_static.shape[0]
        if npups != npup:
            logger.info(
                "pup and static phase must have the same number of pixels")
        if not np.allclose(FoV, FoVnum):
            phase_static = np.maximum(
                interpolate(phase_static, xxpupover, method='cubic'), 0)

    logger.debug('input FoV: %.2f, output FoV: %.2f, Num FoV: %.2f', FoV,
                 FoVnum * dimover / dimnum, FoVnum)

    if FoV > 2 * FoVnum:
        logger.warning(': Potential alisiang issue .. I recommend to create '
                       'initial PSD and pupil with a larger numbert of pixel')

    # creation of a diff limited OTF (pupil autocorrelation)
    tab = np.zeros((dimover, dimover), dtype=complex)
    if phase_static is not None:
        pupover = pupover * np.exp(1j * phase_static * 2 * np.pi / lbda)
    tab[:npupover, :npupover] = pupover

    dlFTO = fft2(np.abs(ifft2(tab))**2)
    dlFTO = fftshift(np.abs(dlFTO) / pup.sum())

    # creation of A OTF (aoFTO = np.exp(-Dphi2 / 2))
    Dphi2 *= -0.5
    np.exp(Dphi2, out=Dphi2)

    # Computation of final OTF
    sysFTO = fftshift(Dphi2 * dlFTO)

    # Computation of final PSF
    sysPSF = np.real(fftshift(ifft2(sysFTO)))
    sysPSF /= sysPSF.sum()  # normalisation to 1

    if return_all:
        FoV = FoVnum * dimover / dim
        return sysPSF, sampout, FoV
    else:
        return sysPSF
Exemplo n.º 59
0
import cv2
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
from numpy.fft import fftshift, ifftshift, fftn, ifftn

matplotlib.rcParams['font.size'] = 8.0
np.random.seed(19680801)

img = cv2.imread('p2.jpg', 0)
dim = range(img.ndim)

k = fftshift(fftn(ifftshift(img, axes=dim), s=None, axes=dim), axes=dim)
k /= np.sqrt(np.prod(np.take(img.shape, dim)))
k = np.real(k)
magnitude_spectrum = 20 * np.log(np.abs(k) + 1)

images = []

fig, axs = plt.subplots(1, 2)

for j in range(2):
    axs[j].set_yticklabels([])
    axs[j].set_xticklabels([])

data = [img, magnitude_spectrum]

images.append(axs[0].imshow(data[0], cmap='gray'))
axs[0].set_title('Input Image')

images.append(axs[1].imshow(data[1], cmap='gray'))
Exemplo n.º 60
0
def _calcpr_er(F, C_s, plan, D_s=None, rho_0=None, r_factor=None, *args, **kwargs):
    """_calcpr_er(F, C_s, plan, D_s=None, rho_0=None, r_factor=None, *args, **kwargs) -> None
    Error reduction algorithm
    Detail: J. R. Fienup, Appl. Opt. 21, 2758 (1982)

    Parameters
    ----------
    F        : numpy.2darray
        target modulus
    C_s      : numpy.2darray
        support in real space
    plan     : Plan / list of Plans object (Plan)
        plan of PR
    D_s      : numpy.2darray (default : None)
        mask in reciprocal space
    rho_0    : numpy.2darray (default : None)
        initial guess of the density map
    r_factor : list (default : None)
        history of R factor
    args     : options
    kwargs   : options
    """

    # Initialize
    if rho_0 is None:
        rho_0 = _init_phase(plan.shape)
        rho_0 *= np.max(np.abs(ifft2(F)))
    elif rho_0 == "phase":
        rho_0 = _init_phase(plan.shape)
        rho_0 *= np.max(np.abs(ifft2(F)))
    elif rho_0 == "amplitude":
        rho_0 = _init_phase(plan.shape)
        rho_0 = ifft2(F * rho_0)
    elif rho_0 == "auto":
        rho_0 = ifft2(F**2)
    elif rho_0 == "auto, amplitude":
        rho_0 = _init_phase(plan.shape)
        rho_0 = ifft2(F**2 * rho_0)
    elif rho_0 == "auto, phase":
        rho_0 = _init_phase(plan.shape)
        rho_0 = rho_0 * ifft2(F**2)
        
    if r_factor is None:
        r_factor = []
    _F = np.abs(fftshift(F))
    
    _D_s = D_s
    if D_s is not None:
        _D_s = fftshift(D_s)

    rho_i = 1.*rho_0
    rho_f = np.zeros(F.shape, dtype=np.complex64)

    # Define FFT functions
    func = FFT_FUNC.get(plan.fft_type)
    ifunc = IFFT_FUNC.get(plan.fft_type)

    # Check use of mask and validity of the parameters
    updmask_use = plan.kwargs.get('updmask_use', False)
    updmask_N = plan.kwargs.get('updmask_N')
    if updmask_use is None or type(updmask_use) != bool:
        updmask_use = False
    elif updmask_N is None or type(updmask_N) != int or updmask_N <= 0:
        updmask_use = False

    ratio = plan.kwargs.get('updmask_ratio')
    if ratio is None or ratio <= 0:
        ratio = -1
    
    _init_C_s = kwargs.get("init_C_s", None)
    width = 1.5
    if C_s is None:
        C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)
    if _init_C_s is not None and _init_C_s == True:
        C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)

    # The known error function for Liu's process.
    err = plan.kwargs.get('err')
    if err is not None and type(err) not in [np.ndarray, list]:
        raise TypeError('"err" has an invalid type.')
    intensity = plan.kwargs.get('intensity')
    if intensity is not None and type(intensity) != bool:
        raise TypeError('"intensity" must be boolean.')

    _num = 0 if plan.kwargs.get('num') is None else plan.kwargs.get('num')

    # Main loop
    for ii in range(plan.N):
        rho_f = func(rho_i, plan.x_gpu, plan.xf_gpu, plan.cufft_plan) # rho(n) -> G(n)
        r_factor.append(_calc_r_factor(rho_f, _F))
        rho_f = _projection_I(rho_f, _F, plan.f_const, _D_s, err, intensity, **kwargs) # G(n) -> G'(n)
        rho_i = _projection_er(ifunc(rho_f, plan.x_gpu, plan.xf_gpu, plan.cufft_plan), C_s, plan.rho_const) # G'(n) -> rho(n+1)
        if updmask_use:
            if np.mod(ii+1, updmask_N) == 0 and ratio > 0: # Update the mask
                width = width-0.03 if width >= 1.5 else 1.5
                C_s = _updmask(np.abs(rho_i), C_s, plan.rho_filter, width, ratio)
        if plan.kwargs.get('save') is True:
            _savefig(np.abs(rho_i), C_s, rho_f, r_factor, plan.pr_mode, ii+_num)
    plan.set(rho_i, r_factor, C_s)