Exemple #1
0
##Ly=#10 #(m)
##dy=np.pi/68#0.004#0.008 #(m)
##Ny=2000#Ly/dy
##Ly=dy*Ny
#---------------ETAPA PREVIA: IFFT respecto a 'w'---------------------
#---------------------------------------------------------------------
#S0=np.fft.ifft(Sr_f,axis=1)
#cmap="plasma"
#fig, ax = plt.subplots()
#im=ax.imshow(20*np.log10(abs(S0)),cmap,origin='lower',extent=[0,rr_r*Nf,-Ls/2,Ls/2],aspect='auto')
#x3=Lista_pos
#y3=Sr_f.T[0]
#a,b=dF.plotFFTc_rk(x3,y3,x_unit='cm')
# Dibujar el range profile
dF.rangeProfile(BW,
                Sr_f[5],
                name_title='Range Profile - [xo,yo]=[%i,%i]' % (Rt_x, Rt_y))
#dF.crangeProfile(rr_x,Sr_f.T[10])

#%%---------------PRIMERA ETAPA: FFT respecto a 'u'---------------------
#                  s(u,w) --> s(ku,w)
#---------------------------------------------------------------------
#S1_a=np.array([np.fft.fft(Sr_f[:,j]) for j in range(len(Lista_f))]).T
# Primero se aplicara un zero padding en cross range
zpad = 256
Np_n = zpad
rows = int((zpad - len(Sr_f)) / 2)
S0 = np.pad(Sr_f, [[rows, rows], [0, 0]], 'constant', constant_values=0)
#-----OJO!-----------------------------------------------------------------------
#[(0, 3), (0, 1)]
#         ^^^^^^------ padding for second dimension
def RMA_Algorithm(data1):
    """ Ejecuta el algoritmo RMA"""
    # Lectura de parametros
    global dec_x, dec_y
    Sr_f = data1['Sr_f'].copy()
    dp = data1['dp']
    fi = data1['fi']
    fs = data1['fs']
    R_max = data1['R_max']
    Lista_f = np.linspace(fi, fs, Nf) # Vector de frecuencias

    # Grafica el perfil de rango para una posicion del riel(Posicion '0')
    if show:
        dF.rangeProfile(fi,BW,Sr_f[int(len(Sr_f)/2)],name_title='Perfil de rango \n(Al principio)')

    # Hamming Windows
    Sr_f *= np.hamming(len(Sr_f[0])) # Multiply rows x hamming windows 
    Sr_f = (Sr_f.T*np.hamming(len(Sr_f))).T # Multiply columns x hamming windows
        
    #----------------ETAPA PREVIA: Range Compression----------------------
    #                       s(x,w) --> s(x,r)
    #---------------------------------------------------------------------
    if show:
        # a) IFFT (eje de rango)
        ifft_len = 10*len(Sr_f[0])
        S0 = np.fft.ifft(Sr_f, ifft_len, axis=1) # axis 0 representa las filas(axis 1 a las columnas), lo cual quiere decir q se sumaran todas las filas manteniendo constante las columnas
        # S0 = np.fft.fftshift(S0,axes=(1)) # to center spectrum
        
        dF.plotImage(S0.T, x_min=-Ls/2, x_max=Ls/2, y_min=0, y_max=R_max,xlabel_name='Azimut(m)',
                     ylabel_name='Rango(m)', title_name='Compresión en Rango',unit_bar='',
                     origin_n='lower')
    
    #----------PRIMERA ETAPA: FFT respecto al eje del riel 'x'----------
    #                       s(x,w) --> s(kx,kr)
    #                           Sr_f -> S1
    #---------------------------------------------------------------------

    # a) Zero padding en cross range
    zpad = int(W/dp) # Initial length of padded signal
    dec_x = int(np.ceil(zpad/Npx)) # Hallando el factor de decimacion en x
    if zpad > len(Sr_f):
        # Reajuste del Nª de elementos para la decimacion en x
        if zpad % Npx != 0:
            ad = dec_x*Npx-zpad # To have a hole multiple of dec
            zpad += ad # Final length of padded signal
        rows = int(zpad - len(Sr_f)) # Length of zeros
    else: rows = 0
    S1 = np.pad(Sr_f, [[0, rows], [0, 0]], 'constant', constant_values=0) # Aplica zero padding a ambos extremos de la matriz
    
    # b) FFT (eje de azimuth)
    S1 = np.fft.fft(S1,axis=0) # axis 0 representa las filas(axis 1 a las columnas), lo cual quiere decir q se sumaran todas las filas manteniendo constante las columnas
    S1 = np.fft.fftshift(S1,axes=(0)) # to center spectrum
    
    # c) Grafica despues del FFT
    kr=4*np.pi*Lista_f/c # Numeros de onda dependientes de la frecuencia
    kx=np.fft.fftfreq(len(S1))*2*np.pi/dp
    kx=np.fft.fftshift(kx)
    if show:
        dF.plotImage(S1.T, x_min=kx.min()-(kx[1]-kx[0])/2, x_max=kx.max()+(kx[1]-kx[0])/2, y_min=kr.min()-(kr[1]-kr[0])/2, y_max=kr.max()+(kr[1]-kr[0])/2,xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)', title_name='1D-FFT\n(Dirección de azimut)', origin_n='lower',unit_bar='dB',log=True)

    # d) Recortando las zonas donde no hay mucha señal(-60dB del maximo) 
    # Hallando las zonas que cumplen la condicion de los -60dB
    if show:
        S1_test = S1.copy()
        mask = 20*np.log10(S1_test)>=20*np.log10(S1_test.max())-60 
        S1_test[~mask] = 0
        
        dF.plotImage(S1_test.T, x_min=kx.min()-(kx[1]-kx[0])/2, x_max=kx.max()+(kx[1]-kx[0])/2, y_min=kr.min()-(kr[1]-kr[0])/2, y_max=kr.max()+(kr[1]-kr[0])/2,xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)', title_name='1D-FFT\n(Test de magnitud)', origin_n='lower',unit_bar='dB',log=True)
    
    """# Función para hallar ni a partir de yi
    def set_y(yi,Nt,yo,yf): # yi deseado, numero de valores de y, y inicial, y final
        Yit = (Nt-1)*(yi-yo)/(yf-yo) # float
        ni = int(np.floor(round(Yit,5)))
        return ni

    #ky_inf = set_y(400,len(ky_it),ky_it[0],ky_it[-1])
    #ky_sup = set_y(50,len(ky_it),ky_it[0],ky_it[-1])
    kx_inf = set_y(-400,len(kx),kx[0],kx[-1]) # Desde kx=-400
    kx_sup = set_y(400,len(kx),kx[0],kx[-1]) # Hasta kx=400
    
    kx = kx[kx_inf+2:kx_sup] # Correccion manual para la decimacion en x
    #ky_it = ky_it[:] 
    S1 = S1[kx_inf+2:kx_sup,:] 
    
    # Reajusta el Nº de elementos para la decimacion en "x"
    dec_x = int(np.ceil(len(kx)/Npx)) # Hallando el factor de decimacion en x
    adx = Npx*dec_x-len(kx) # Cantidad de valores a agregar
    if show:    
        dF.plotImage(S1.T, x_min=kx.min()-(kx[1]-kx[0])/2, x_max=kx.max()+(kx[1]-kx[0])/2, y_min=kr.min()-(kr[1]-kr[0])/2, y_max=kr.max()+(kr[1]-kr[0])/2,xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)', title_name='1D-FFT\n(Dirección de azimut - Recortado)', origin_n='lower',unit_bar='dB',log=True)
    """
    #----------------SEGUNDA ETAPA: Matched Filter----------------------
    #                  s(kx,kr) --> sm(kx,kr)
    #                       S1  ->  S1_m
    #-------------------------------------------------------------------

    # a) Matched Filter
    krr, kxx= np.meshgrid(kr,kx)
    ky = np.sqrt(krr**2-kxx**2)
    
    Xc1 = - Rmax/2 #(yi+H/2) # Factor de correccion debido a la FFT en "y"
    Xc2 = -Ls/2 # Factor de correccion debido a la FFT en "x"
    Xc3 = 0 #-4 
    
    mask = np.isnan(ky) # Obtiene las posiciones de los números complejos

    phi_m = -kxx*(Xc2+Xc3)-Xc1*ky#+Xc1*krr
    S1 *= np.exp(1j*phi_m) # matrix
    S1[mask] = 0+0j
    
    # c) Grafica despues del Matched Filter
    if show:
        dF.plotImage(S1.T, x_min=kx.min()-(kx[1]-kx[0])/2, x_max=kx.max()+(kx[1]-kx[0])/2, y_min=kr.min()-(kr[1]-kr[0])/2, y_max=kr.max()+(kr[1]-kr[0])/2, xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)', title_name='Matched Filter', origin_n='lower',unit_bar='')

    # d) Range and azimuth compression
    if show:
        S1_n = S1/(np.sqrt(np.sum(abs(S1)**2)))
        ifft_len = np.array([len(S1_n),10*len(S1_n[0])])
        S1_1 = np.fft.fftshift(S1_n, axes=(0))
        S1_1 = np.fft.ifft2(S1_1,ifft_len)
        S1_1 = np.fft.fftshift(S1_1, axes=(0,1))
        vmin=0
        vmax=5
        dF.plotImage(S1_1.T, x_min=-Ls/2, x_max=Ls/2, y_min=0, y_max=R_max,xlabel_name='Azimut(m)',
                     ylabel_name='Rango(m)', title_name='Compresión en Rango y Azimut\n(Despues del Matched Filter)',
                     origin_n='lower',log=True,unit_bar='(dB)')#,vmin=vmin,vmax=vmax)
    
    #----------------TERCERA ETAPA: Stolt Interpolation-------------------
    #                  F(kxmn,kymn) --> F(kx,ky)
    #                       S1_m  -->  S2
    #---------------------------------------------------------------------
    # a) Redefinicion de los ejes
    dk_r = (kr[1]-kr[0])
    
    # b) Interpolación STOLT
    ky_min = np.min(ky[~(np.isnan(ky))])
    ky_max = np.max(ky[~(np.isnan(ky))])
    ky_it = np.arange(ky_min,ky_max,dk_r) # Puntos de interpolacion en el eje ky
    
    # Reajusta el Nº de elementos para la decimacion en "y"
    dec_y = int(np.ceil(len(ky_it)/Npy)) # Hallando el factor de decimacion en y
    if len(ky_it) % Npy != 0:
        ady = dec_y*Npy-len(ky_it)
        ky_it = np.append(ky_it,[ky_it[-1]+dk_r*(i+1) for i in range(ady)])
        
    # Interpolacion y decimacion optimizada
    indx = int(len(S1)/dec_x) # Longitud despues de la decimacion en el eje X 
    indy = int(len(ky_it)/(dec_y)) # Longitud despues de la decimacion en el eje Y
    S2 = np.zeros((indx,indy), dtype=complex) # Matriz interpolada y decimada

    ky_it2 = np.reshape(ky_it,(dec_y,int(len(ky_it)/dec_y)))
    
    for i in range(dec_x):
        for k in range(indx):
            # Se redefinen ky y S1 eliminando los terminos nan
            ky_aux2 = ky[k+indx*i]
            S1_aux2 = S1[k+indx*i]
            S1_aux2 = S1_aux2[~np.isnan(ky_aux2)]            
            ky_aux2 = ky_aux2[~np.isnan(ky_aux2)]
            
            if ky_aux2.size>1:
                interp_fn1 = sc.interpolate.interp1d(ky_aux2, S1_aux2.real, bounds_error=False, fill_value=0,kind='cubic')
                interp_fn2 = sc.interpolate.interp1d(ky_aux2, S1_aux2.imag, bounds_error=False, fill_value=0,kind='cubic')
    
                for z in range(dec_y):
                    if ky_it2[z].max()>=ky_aux2.min() and ky_it2[z].min()<=ky_aux2.max():
                        if ky_it2[z].min()<=ky_aux2.min(): 
                            start = z
                        if ky_it2[z].max()>=ky_aux2.max(): 
                            end = z
                            break
                ky_it3 = np.reshape(ky_it2[start:end+1,:],-1)
                aux = interp_fn1(ky_it3)+1j*interp_fn2(ky_it3)
                S2[k] += aux.reshape((int(len(ky_it3)/indy),indy)).sum(axis=0)
                
    S2 /= dec_x*dec_y
    
    # Nuevos valores del eje "kx"
    Nkx = int(len(kx)/dec_x)
    kx_n = (np.arange(Nkx)-Nkx/2)*(kx[1]-kx[0])

    # Nuevos valores del eje "ky"
    Nky = int(len(ky_it)/dec_y)
    ky_n = np.arange(Nky)*(ky_it[1]-ky_it[0])+ky_it.min()


    # d) Grafica despues de la interpolación
    if show:
        dF.plotImage(S2.T, x_min=kx_n.min(), x_max=kx_n.max(), y_min=ky_n.min(), y_max=ky_n.max(), xlabel_name='kx(1/m)',
                 ylabel_name='ky(1/m)', title_name='Interpolación STOLT\n(Decimado)', unit_bar='(dB)', log=True)
    
    #--------CUARTA ETAPA_previa: 1D-IFFT(range compression)--------------------
    #                  F(kx,ky) --> f(kx,y)
    #----------------------------------------------------------
    if show:
        # a) 1D-IFFT
        ifft_len = 1*np.array(np.shape(S2))
        S3_1 = np.fft.ifft(S2,axis=1)
        S3_1 = np.fft.fftshift(S3_1, axes=(1))
        
        # b) Definicion de parametros para las graficas
        #Nx = ifft_len[0]
        Ny = ifft_len[1]
        #dk_x = (kx_n[1]-kx_n[0])
        dk_y = (ky_n[1]-ky_n[0])
        
        # x = (np.arange(Nx)-Nx/2)*(2*np.pi/dk_x/Nx)
        y = (np.arange(Ny)-(Ny-1)/2)*(2*np.pi/dk_y/(Ny-1))-Xc1
        
        # d) Grafica despues de la interpolación
        dF.plotImage(S3_1.T, x_min=kx_n.min(), x_max=kx_n.max(), y_min=y.min(), y_max=y.max(), xlabel_name='kx(1/m)',
                     ylabel_name='y(m)', title_name='Compresión en rango', unit_bar='')
    
    #-----------------CUARTA ETAPA: 2D-IFFT--------------------
    #                  F(kx,ky) --> f(x,y)
    #                     S2  -->  Sf
    #----------------------------------------------------------
    # a) 2D-IFFT
    ifft_len = np.array([1*len(S2),1*len(S2[0])])#np.array(np.shape(S3)) #: Uncomment si no quiere interpolar  
    S3 = np.fft.ifftshift(S2, axes=(0)) # De-centra el eje kx
    S3 = np.fft.ifft2(S3, ifft_len)
    S3 = np.fft.fftshift(S3, axes=(0,1)) # Centra en el origen
    
    # b) Definicion de parametros para las graficas
    Nx = ifft_len[0]
    Ny = ifft_len[1]
    dk_x = (kx_n[1]-kx_n[0])
    dk_y = (ky_n[1]-ky_n[0])
    
    x = np.linspace(-np.pi/dk_x,np.pi/dk_x,Nx)-Xc3
    y = np.linspace(-np.pi/dk_y,np.pi/dk_y,Ny)-Xc1
    
    # Compensacion de fase 
    y2,x2 = np.meshgrid(y,x)
    kx_c = 0 #10*np.pi #(kx_n[-1]-kx_n[0])/2 # considerar solo cuando no se hace fftshift en x
    ky_c = (kr.max()-kr.min())/2 #4*np.pi + 1.37/5 #ky_n[0]-2*np.pi/0.55-2*np.pi/2#ky_n[int(len(ky_n)/2)] #4*np.pi
    kyo = 0 #-0.57
    S3 *= np.exp(-1j*kx_c*x2+1j*(ky_c*y2+kyo)) 
    
    # Normalizando la salida 
    S3 /= np.sqrt(np.sum(abs(S3)**2))
    
    if show:
        # GRAFICA DEL PERFIL DE RANGO(Magnitud) 
        fig, ax = plt.subplots()
        ax.plot(y, 20*np.log10(abs(S3[int(len(S3)/2)])),'k')
        ax.set(xlabel='Rango(m)',ylabel='Intensidad(dB)', title='Perfil de rango\n(Después de la Interpolación)')
        ax.grid()
        plt.show()
        # GRAFICA DEL PERFIL DE FASE(Eje del rango) 
        fig, ax = plt.subplots()
        ax.plot(y, np.angle(S3[int(len(S3)/2)]),'k')
        ax.set(xlabel='Rango(m)',ylabel='Fase(rad)', title='Perfil de fase\n(Después de la Interpolación)')
        ax.grid()
        plt.show()
        # GRAFICA DEL PERFIL DE Fase(Eje de cross range)
        fig, ax = plt.subplots()
        ax.plot(x, np.angle(S3.T[int(len(S3[0])/2)]),'k')
        ax.set(xlabel='Rango(m)',ylabel='Fase(rad)', title='Perfil de fase - cr\n(Después de la Interpolación)')
        ax.grid()
        plt.show()
    
    return {'Sf':S3,'x':x,'y':y}
Exemple #3
0
def FDBP_Algorithm(data1):
    """ Ejecuta el algoritmo Frequency Domain Back Projection"""
    # Lectura de parametros
    Ski = data1['Ski'].copy()
    df = data1['df']
    fi = data1['fi']
    rr_r = data1['rr_r']
    Lista_pos = np.linspace(-Ls/2, Ls/2, Np)

    # Grafica el perfil de rango para una posicion del riel(Posicion intermedia)
    if show:
        dF.rangeProfile(fi,BW,Ski[int(len(Ski)/2)],name_title='Perfil de rango\n(Magnitud)')

    # Hamming Windows
    S1 *= np.hamming(len(Ski[0])) # Multiply rows x hamming windows
    S1 = (S1.T*np.hamming(len(S1))).T # Multiply columns x hamming windows

    #----------PRIMERA ETAPA: 1D-IFFT respecto al eje de la 'f'-----------
    #---------------------------------------------------------------------
    # a) Agregar un factor de fase debido al delay de los cables
    S2 = S1*np.vander([np.exp(-1j*4*np.pi/c*Ro*df)]*Np,Nf,increasing=True) # Vandermonde matrix

    # b) Efectuar un zero padding en el eje de la 'f'
    zpad = 3*int(rr_r*(Nf-1)/dy)+1 # Dimension final despues del zero padding (depende del espaciado de la grilla, para tener mejor interpolacion), se le agrego el 3 de mas para una grilla igual a la resolucion y para identificar correctamente los targets
    col = int(zpad - len(S1[0])) # Length of zeros
    S3 = np.pad(S2, [[0, 0], [0, col]], 'constant', constant_values=0) # Aplica zero padding a ambos extremos de la matriz

    # c) Efectuar la IFFT
    S4 = np.fft.ifft(S3,axis=1)

    # GRAFICA
    if show:
        dkn = 4*np.pi*df/0.3
        rn = (np.arange(zpad))*2*np.pi/dkn/(zpad-1)
        fn = 20*np.log10(abs(S4[int(len(S4)/2)]))

        fig, ax= plt.subplots()
        ax.plot(rn,fn,'k')
        ax.set(xlabel='Rango(m)',ylabel='Intensidad(dB)', title='Perfil de rango')
        ax.grid()
        plt.show()

    #------------------SEGUNDA ETAPA: Interpolacion-----------------------
    # --------------------------------------------------------------------
    # a) Definicion del dominio de interpolacion
    dkn = 4*np.pi*df/0.3
    rn = (np.arange(zpad))*2*np.pi/dkn/(zpad-1)

    # b) Declaracion de las coordenadas de la imagen a reconstruir
    x_c=np.arange(-Lx/2,Lx/2+dx,dx)
    y_c=np.arange(0,Ly+dy,dy)
    r_c=np.array([(i,j) for j in y_c for i in x_c])

    # Funcion para calcular la distancia entre una posición del riel y todos las coordenadas de la imagen
    def distance_nk(r_n,x_k): # vector de coordenadas de la imagen, punto del riel "k"
        d=((r_n[:,0]-x_k)**2+(r_n[:,1])**2)**0.5
        return d

    # Funcion de interpolacion
    def interp(k,dist): # k: posicion del riel, vector de distancias entre 'n' y 'k'
        fr=sc.interp1d(rn,S4[k].real,kind='linear',bounds_error=False, fill_value=S4[k,-1].real) # Interpolacion al punto mas cercano
        fi=sc.interp1d(rn,S4[k].imag,kind='linear',bounds_error=False, fill_value=S4[k,-1].imag) # Fuera de la frontera se completa con el valor de la frontera
        return fr(dist) +1j*fi(dist)

    # c) Interpolacion y suma coherente
    S5=np.zeros(len(r_c),dtype=complex)
    for kr S5 range(Np):
        Rnk = distance_nk(r_c,Lista_pos[kr]) # Vector de distancias entre una posicion del riel y todos los puntos de la imagen
        Ke = np.exp(1j*4*np.pi/c*fi*(Rnk-Ro)) # Factor de fase
        Fnk = interp(kr,Rnk) # Valor interpolado en cada punto "n" de la grilla
        S5 += Fnk*Ke # Valor final en cada punto de la grilla
def RMA_Algorithm(data1):
    """ Ejecuta el algoritmo RMA"""
    # Lectura de parametros
    global dec_x, dec_y
    Ski = data1['Ski'].copy()
    dp = data1['dp']
    fi = data1['fi']
    fs = data1['fs']
    R_max = data1['R_max']
    Lista_f = np.linspace(fi, fs, Nf)  # Vector de frecuencias

    # Grafica el perfil de rango para una posicion del riel(Posicion '0')
    if show:
        dF.rangeProfile(fi,
                        BW,
                        Ski[int(len(Ski) / 2)],
                        name_title='Perfil de rango \n(Al principio)')

    # Hamming Windows
    S1 = Ski * np.hamming(len(Ski[0]))  # Multiply rows x hamming windows
    S1 = (S1.T * np.hamming(len(S1))).T  # Multiply columns x hamming windows

    #----------------ETAPA PREVIA: Range Compression----------------------
    #                       s(x,w) --> s(x,r)
    #---------------------------------------------------------------------
    if show:
        # a) IFFT (eje de rango)
        ifft_len = 10 * len(Ski[0])
        S0 = np.fft.ifft(
            S1, ifft_len, axis=1
        )  # axis 0 representa las filas(axis 1 a las columnas), lo cual quiere decir q se sumaran todas las filas manteniendo constante las columnas
        # S0 = np.fft.fftshift(S0,axes=(1)) # to center spectrum

        dF.plotImage(S0.T,
                     x_min=-Ls / 2,
                     x_max=Ls / 2,
                     y_min=0,
                     y_max=R_max,
                     xlabel_name='Azimut(m)',
                     ylabel_name='Rango(m)',
                     title_name='Compresión en Rango al HF',
                     unit_bar='dB',
                     log=True,
                     origin_n='lower')

    #----------PRIMERA ETAPA: FFT respecto al eje del riel 'x'----------
    #                       s(x,w) --> s(kx,kr)
    #                           Ski -> S1
    #---------------------------------------------------------------------

    # a) Zero padding en cross range
    zpad = int(Lx / dp)  # Initial length of padded signal
    if zpad > len(Ski):
        # Reajuste del Nª de elementos para la decimacion en x
        #if zpad%dec_x!=0:
        #    ad = dec_x-(zpad%dec_x) # To have a hole multiple of dec
        #    zpad += ad # Final length of padded signal
        rows = int(zpad - len(Ski))  # Length of zeros
    else:
        rows = 0
    S2 = np.pad(
        S1, [[0, rows], [0, 0]], 'constant',
        constant_values=0)  # Aplica zero padding a ambos extremos de la matriz

    # b) FFT (eje de azimuth)
    S3 = np.fft.fft(
        S2, axis=0
    )  # axis 0 representa las filas(axis 1 a las columnas), lo cual quiere decir q se sumaran todas las filas manteniendo constante las columnas
    S3 = np.fft.fftshift(S3, axes=(0))  # to center spectrum

    # c) Grafica despues del FFT
    kr = 4 * np.pi * Lista_f / c  # Numeros de onda dependientes de la frecuencia
    kx = np.fft.fftfreq(len(S1)) * 2 * np.pi / dp
    kx = np.fft.fftshift(kx)
    if show:
        dF.plotImage(S3.T,
                     x_min=kx.min() - (kx[1] - kx[0]) / 2,
                     x_max=kx.max() + (kx[1] - kx[0]) / 2,
                     y_min=kr.min() - (kr[1] - kr[0]) / 2,
                     y_max=kr.max() + (kr[1] - kr[0]) / 2,
                     xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)',
                     title_name='1D-FFT\n(Dirección de azimut)',
                     origin_n='lower',
                     unit_bar='dB',
                     log=True)

    # d) Recortando las zonas donde no hay mucha señal(-60dB del maximo)
    # Hallando las zonas que cumplen la condicion de los -60dB
    if show:
        S3_test = S3.copy()
        mask = 20 * np.log10(S3_test) >= 20 * np.log10(S3_test.max()) - 60
        S3_test[~mask] = 0

        dF.plotImage(S3_test.T,
                     x_min=kx.min() - (kx[1] - kx[0]) / 2,
                     x_max=kx.max() + (kx[1] - kx[0]) / 2,
                     y_min=kr.min() - (kr[1] - kr[0]) / 2,
                     y_max=kr.max() + (kr[1] - kr[0]) / 2,
                     xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)',
                     title_name='1D-FFT\n(Test de magnitud)',
                     origin_n='lower',
                     unit_bar='dB',
                     log=True)

    # Función para hallar ni a partir de yi
    def set_y(yi, Nt, yo,
              yf):  # yi deseado, numero de valores de y, y inicial, y final
        Yit = (Nt - 1) * (yi - yo) / (yf - yo)  # float
        ni = int(np.floor(round(Yit, 5)))
        return ni

    #ky_inf = set_y(400,len(ky_it),ky_it[0],ky_it[-1])
    #ky_sup = set_y(50,len(ky_it),ky_it[0],ky_it[-1])
    kx_inf = set_y(-400, len(kx), kx[0], kx[-1])  # Desde kx=-400
    kx_sup = set_y(400, len(kx), kx[0], kx[-1])  # Hasta kx=400

    kx = kx[kx_inf + 2:kx_sup]  # Correccion manual para la decimacion en x
    #ky_it = ky_it[:]
    S3 = S3[kx_inf + 2:kx_sup, :]

    # Reajusta el Nº de elementos para la decimacion en "x"

    dec_x = int(np.ceil(len(kx) /
                        Fkx))  # Hallando el factor de decimacion en x
    adx = Fkx * dec_x - len(kx)  # Cantidad de valores a agregar
    if show:
        dF.plotImage(S3.T,
                     x_min=kx.min() - (kx[1] - kx[0]) / 2,
                     x_max=kx.max() + (kx[1] - kx[0]) / 2,
                     y_min=kr.min() - (kr[1] - kr[0]) / 2,
                     y_max=kr.max() + (kr[1] - kr[0]) / 2,
                     xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)',
                     title_name='1D-FFT\n(Dirección de azimut - Recortado)',
                     origin_n='lower',
                     unit_bar='(dB)',
                     log=True)

    # Range Compression
    if show:
        S3_n = S3 / (np.sqrt(np.sum(abs(S3)**2)))
        ifft_len = 10 * len(S3_n[0])  #np.array([len(S3_n),10*len(S3_n[0])])
        S3_1 = np.fft.ifft(S3_n, ifft_len, axis=1)
        vmin = 0
        vmax = 5
        dF.plotImage(
            S3_1.T,
            x_min=kx.min() - (kx[1] - kx[0]) / 2,
            x_max=kx.max() + (kx[1] - kx[0]) / 2,
            y_min=0,
            y_max=R_max,
            xlabel_name='kx(1/m)',
            ylabel_name='Rango(m)',
            title_name='Compresión en Rango y Azimut\n(Despues del FFT)',
            origin_n='lower',
            log=True,
            unit_bar='(dB)')  #,vmin=vmin,vmax=vmax)

    #----------------SEGUNDA ETAPA: Matched Filter----------------------
    #                  s(kx,kr) --> sm(kx,kr)
    #                       S3  ->  S4
    #-------------------------------------------------------------------

    # a) Matched Filter
    krr, kxx = np.meshgrid(kr, kx)
    Xc1 = -Ly / 2  # Factor de correccion debido a la FFT en "y"
    Xc2 = -Ls / 2  # Factor de correccion debido a la FFT en "x"
    Xc3 = 0  #-4

    mask = np.isnan(
        np.sqrt(krr**2 -
                kxx**2))  # Obtiene las posiciones de los números complejos

    phi_m = -kxx * (Xc2 + Xc3) - Xc1 * np.sqrt(krr**2 - kxx**2)  #+Xc1*krr
    S4 = S3 * np.exp(1j * phi_m)  # matrix
    S4[mask] = 0 + 0j

    # c) Grafica despues del Matched Filter
    if show:
        dF.plotImage(S4.T,
                     x_min=kx.min() - (kx[1] - kx[0]) / 2,
                     x_max=kx.max() + (kx[1] - kx[0]) / 2,
                     y_min=kr.min() - (kr[1] - kr[0]) / 2,
                     y_max=kr.max() + (kr[1] - kr[0]) / 2,
                     xlabel_name='kx(1/m)',
                     ylabel_name='kr(1/m)',
                     title_name='Matched Filter',
                     origin_n='lower',
                     unit_bar='(dB)',
                     log=True)

    # d) Range and azimuth compression
    if show:
        S4_n = S4 / (np.sqrt(np.sum(abs(S4)**2)))
        ifft_len = 10 * len(S4_n[0])  #np.array([len(S4_n),10*len(S4_n[0])])
        S4_1 = np.fft.fftshift(S4_n, axes=(0))
        S4_1 = np.fft.ifft(S4_1, ifft_len, axis=1)
        S4_1 = np.fft.fftshift(S4_1, axes=(0, 1))
        vmin = 0
        vmax = 5
        dF.plotImage(
            S4_1.T,
            x_min=kx.min() - (kx[1] - kx[0]) / 2,
            x_max=kx.max() + (kx[1] - kx[0]) / 2,
            y_min=0,
            y_max=R_max,
            xlabel_name='kx(1/m)',
            ylabel_name='Rango(m)',
            title_name=
            'Compresión en Rango y Azimut\n(Despues del Matched Filter)',
            origin_n='lower',
            log=True,
            unit_bar='(dB)')  #,vmin=vmin,vmax=vmax)

    #----------------TERCERA ETAPA: Stolt Interpolation-------------------
    #                  F(kxmn,kymn) --> F(kx,ky)
    #                       S4  -->  S5
    #---------------------------------------------------------------------
    # a) Redefinicion de los ejes
    #kx = kx # vector
    ky = np.sqrt(
        krr**2 -
        kxx**2)  # Genera una matriz, para cada valor de kx [0,....len(ku)-1]
    dk_r = (kr[1] - kr[0])
    #mask = np.isnan(ky)
    #ky[mask] = 0

    # b) Interpolación STOLT
    ky_min = np.min(ky[~(np.isnan(ky))])
    ky_max = np.max(ky[~(np.isnan(ky))])
    ky_it = np.arange(ky_min, ky_max,
                      dk_r)  # Puntos de interpolacion en el eje ky

    # Reajusta el Nº de elementos para la decimacion en "y"
    dec_y = int(np.floor(len(ky_it) /
                         Fky))  # Hallando el factor de decimacion en y
    if len(ky_it) % Fky != 0:
        #ad = dec_y-(len(ky_it)%dec_y)
        ady = len(ky_it) % Fky  #Fky*dec_y-len(ky_it)
        ky_it = ky_it[ady:]
        #ky_it = np.linspace(ky_min,ky_max,len(ky_it)+ady) # Puntos finales de interpolacion eje ky

    # Interpolacion 1D lineal
    S5 = np.zeros((len(kx), len(ky_it)), dtype=np.complex)

    for i in range(len(kx)):
        interp_fn1 = sc.interpolate.interp1d(ky[i],
                                             S1.real[i],
                                             bounds_error=False,
                                             fill_value=0)  #, kind='cubic')
        interp_fn2 = sc.interpolate.interp1d(ky[i],
                                             S1.imag[i],
                                             bounds_error=False,
                                             fill_value=0)  #, kind='cubic')
        S5[i] = interp_fn1(ky_it) + 1j * interp_fn2(ky_it)

    S5[np.isnan(S5)] = 0 + 0j

    if show:
        dF.plotImage(S5.T,
                     x_min=kx.min(),
                     x_max=kx.max(),
                     y_min=ky_it.min(),
                     y_max=ky_it.max(),
                     xlabel_name='kx(1/m)',
                     ylabel_name='ky(1/m)',
                     title_name='Interpolación STOLT\n(Sin decimar)',
                     unit_bar='(dB)',
                     log=True)

    # c) Decimacion(Continuacion)
    # - En el eje "kx"
    S6 = np.zeros([int(len(S5) / dec_x), len(S5[0])], dtype=complex)
    ind1 = int(len(S5) / dec_x)

    for i in range(dec_x):
        S6 += S5[:ind1]
        S5 = S5[ind1:]
    S6 /= dec_x

    # Nuevos valores del eje "kx"
    Nkx = len(S6)
    kx_n = np.fft.fftshift(np.fft.fftfreq(Nkx) * Nkx * (kx[1] - kx[0]))
    #kx_n = (np.arange(Nkx)-(Nkx-1)/2)*(kx[1]-kx[0])

    # - En el eje "y"
    S6_aux = S6.T
    S7 = np.zeros([int(len(S6_aux) / dec_y), len(S6_aux[0])], dtype=complex)
    ind2 = int(len(S6_aux) / dec_y)

    for i in range(dec_y):
        S7 += S6_aux[:ind2]
        S6_aux = S6_aux[ind2:]
    S7 = S7.T
    S7 /= dec_y

    # Nuevos valores del eje "ky"
    Nky = len(S7[0])
    ky_n = np.arange(Nky) * (ky_it[1] - ky_it[0]) + ky_it.min()

    # d) Grafica despues de la interpolación
    if show:
        dF.plotImage(S7.T,
                     x_min=kx_n.min(),
                     x_max=kx_n.max(),
                     y_min=ky_n.min(),
                     y_max=ky_n.max(),
                     xlabel_name='kx(1/m)',
                     ylabel_name='ky(1/m)',
                     title_name='Interpolación STOLT\n(Decimado)',
                     unit_bar='(dB)',
                     log=True)

    #--------CUARTA ETAPA_previa: 1D-IFFT(range compression)--------------------
    #                  F(kx,ky) --> f(kx,y)
    #----------------------------------------------------------
    if show:
        # a) 1D-IFFT
        ifft_len = 1 * np.array(np.shape(S7))
        S7_1 = np.fft.ifft(S7, axis=1)
        S7_1 = np.fft.fftshift(S7_1, axes=(1))

        # b) Definicion de parametros para las graficas
        #Nx = ifft_len[0]
        Ny = ifft_len[1]
        #dk_x = (kx_n[1]-kx_n[0])
        dk_y = (ky_n[1] - ky_n[0])

        # x = (np.arange(Nx)-Nx/2)*(2*np.pi/dk_x/Nx)
        y = (np.arange(Ny) - (Ny - 1) / 2) * (2 * np.pi / dk_y /
                                              (Ny - 1)) - Xc1

        # d) Grafica despues de la interpolación
        dF.plotImage(
            S7_1.T,
            x_min=kx_n.min(),
            x_max=kx_n.max(),
            y_min=y.min(),
            y_max=y.max(),
            xlabel_name='kx(1/m)',
            ylabel_name='y(m)',
            title_name='Compresión en rango\n(Despues de la Interpolación)',
            unit_bar='')

    #-----------------CUARTA ETAPA: 2D-IFFT--------------------
    #                  F(kx,ky) --> f(x,y)
    #                     S2  -->  Sf
    #----------------------------------------------------------
    # a) 2D-IFFT
    ifft_len = np.array([
        1 * len(S7), 1 * len(S7[0])
    ])  #np.array(np.shape(S7)) #: Uncomment si no quiere interpolar
    S8 = np.fft.ifftshift(S3, axes=(0))  # De-centra el eje kx
    S8 = np.fft.ifft2(S8, ifft_len)
    S8 = np.fft.fftshift(S8, axes=(0, 1))  # Centra en el origen

    # b) Definicion de parametros para las graficas
    Nx = ifft_len[0]
    Ny = ifft_len[1]
    dk_x = (kx_n[1] - kx_n[0])
    dk_y = (ky_n[1] - ky_n[0])

    x = np.linspace(-np.pi / dk_x, np.pi / dk_x, Nx) - Xc3
    y = np.linspace(-np.pi / dk_y, np.pi / dk_y, Ny) - Xc1

    #x = np.fft.fftfreq(Nx+1)*2*np.pi/dk_x
    #x = np.fft.fftshift(x)-Xc3
    #y = np.fft.fftfreq(Ny)*2*np.pi/dk_y
    #y = np.fft.fftshift(y)-Xc1

    # Compensacion de fase
    y2, x2 = np.meshgrid(y, x)
    kx_c = 0  #10*np.pi #(kx_n[-1]-kx_n[0])/2 # considerar solo cuando no se hace fftshift en x
    ky_c = (
        kr.max() - kr.min()
    ) / 2  #4*np.pi + 1.37/5 #ky_n[0]-2*np.pi/0.55-2*np.pi/2#ky_n[int(len(ky_n)/2)] #4*np.pi
    kyo = 0  #-0.57
    S8 *= np.exp(-1j * kx_c * x2 + 1j * (ky_c * y2 + kyo))

    # Normalizando la salida
    I = S8 / (np.sqrt(np.sum(abs(S8)**2)))

    if show:
        # GRAFICA DEL PERFIL DE RANGO(Magnitud)
        fig, ax = plt.subplots()
        ax.plot(y, 20 * np.log10(abs(I[int(len(I) / 2)])), 'k')
        ax.set(xlabel='Rango(m)',
               ylabel='Intensidad(dB)',
               title='Perfil de rango\n(Después de la Interpolación)')
        ax.grid()
        plt.show()
        # GRAFICA DEL PERFIL DE FASE(Eje del rango)
        fig, ax = plt.subplots()
        ax.plot(y, np.angle(I[int(len(I) / 2)]), 'k')
        ax.set(xlabel='Rango(m)',
               ylabel='Fase(rad)',
               title='Perfil de fase\n(Después de la Interpolación)')
        ax.grid()
        plt.show()
        # GRAFICA DEL PERFIL DE Fase(Eje de cross range)
        fig, ax = plt.subplots()
        ax.plot(x, np.angle(I.T[int(len(I[0]) / 2)]), 'k')
        ax.set(xlabel='Rango(m)',
               ylabel='Fase(rad)',
               title='Perfil de fase - cr\n(Después de la Interpolación)')
        ax.grid()
        plt.show()

    return {'Im': I.T, 'x': x, 'y': y}