コード例 #1
0
def plot_image(data2):
    """ Grafica la magnitud de la imagen"""
    # a) Definicion y lectura de parametros
    Im = data2['Im'].copy()
    x = data2['x']
    y = data2['y']

    dx = x[1] - x[0]
    dy = y[1] - y[0]
    # R_max = data2['R_max']
    Nx = len(Im[0])
    Ny = len(Im)

    if show:
        # b) Truncacion de la imagen(Eje Y) _ usarlo solo en las pruebas
        # Función para hallar ni a partir de yi
        def set_y(yi):
            return (Ny - 1) * (yi - y[0]) / (y[-1] - y[0])  # float

        y1, y2 = y.min(), y.max(
        )  #max(0,y.min()),min(R_max,y.max()) # Nuevos valores limites de y=[y1,y2]
        n1 = int(np.floor(round(set_y(y1), 5)))  # n1 = f(y1)
        n2 = int(np.ceil(round(set_y(y2), 5)))  # n2 = f(y2)
        # Se uso primero round, floor y ceil, para asegurarse de q n1, n2 no salga de los limites permitidos
        Im_n = Im.T[n1:n2, ]

        # c) Truncacion de la imagen(Eje X)
        # Función para hallar ni a partir de xi
        def set_x(xi):
            return (Nx - 1) * (xi - x[0]) / (x[-1] - x[0])  # float

        x1, x2 = x.min(), x.max(
        )  #max(0,y.min()),min(R_max,y.max()) # Nuevos valores limites de y=[y1,y2]
        n3 = int(np.floor(round(set_x(x1), 5)))  # n1 = f(y1)
        n4 = int(np.ceil(round(set_x(x2), 5)))  # n2 = f(y2)
        # Se uso primero round, floor y ceil, para asegurarse de q n1, n2 no salga de los limites permitidos

    # c) Grafica final(magnitud)
    cmap = "plasma"
    vmin = -100  #dB
    vmax = -20
    dF.plotImage(Im,
                 cmap=cmap,
                 xlabel_name='Azimut(m)',
                 ylabel_name='Rango(m)',
                 title_name='Resultado Algoritmo Range Migration',
                 x_min=x[0] - dx / 2,
                 x_max=x[-1] + dx / 2,
                 y_min=y[0] - dy / 2,
                 y_max=y[-1] + dy / 2,
                 unit_bar='(dB)',
                 log=True,
                 vmin=vmin,
                 vmax=vmax)

    return 'Ok!'
コード例 #2
0
def get_SAR_data():
    """ Obtiene el histórico de fase ya sea simulado o real"""
    # Cálculo de parámetros
    It, Rt = sp.get_scalar_data2(
    )  # Coordenadas(m) y magnitud del target respectivamente
    dp = Ls / (Np - 1)  # Paso del riel(m)
    fi = fc - BW / 2  # Frecuencia inferior(GHz)
    fs = fc + BW / 2  # Frecuencia superior(GHz)

    # Cálculo de las resoluciones
    rr_r = c / (2 * BW)  # Resolución en rango
    rr_a = c / (2 * Ls * fc)  # Resolución en azimuth(Angulo)

    #-----------------VERIFICACIÓN DE CONDICIONES------------------------
    # Rango máximo
    R_max = Nf * c / (2 * BW)
    # Paso del riel máximo
    dx_max = c / (fc * 4 * np.sin(theta * np.pi / 180)
                  )  # Theta en grados sexagesimales

    print("------------------------------------------------------")
    print("--------------INFORMACIÓN IMPORTANTE------------------")
    print("------------------------------------------------------")
    print("- Resolución en rango(m) : ", rr_r)
    print("- Resolución en azimuth(rad): ", rr_a)
    print("------------------------------------------------------")
    print("- Rango máximo permitido(m): ", R_max)
    print("------------------------------------------------------")
    print("______¿Se cumplen las siguientes condiciones?_________")
    print("Rango máximo del target <= rango máximo?: ",
          Rt.T[1].max() <= R_max)  # Ponerle un try-except
    print("Paso del riel <= paso máximo?: ",
          dp <= dx_max)  # Evita el aliasing en el eje de azimuth
    print("------------------------------------------------------")

    #----------------OBTENCIÓN DEL HISTÓRICO DE FASE---------------------
    Ski = Sd.get_phaseH(prm, It, Rt)
    #np.save("RawData_prueba1",Ski)
    #Ski = np.load("RawData_prueba1.npy")

    #-----------------GRÁFICA DEL HISTÓRICO DE FASE-----------------------
    if show:
        dF.plotImage(Ski,
                     x_min=fi,
                     x_max=fs,
                     y_min=-Ls / 2,
                     y_max=Ls / 2,
                     xlabel_name='Frecuencia(GHz)',
                     ylabel_name='Posición del riel(m)',
                     title_name='Histórico de Fase',
                     unit_bar='',
                     origin_n='upper')  #, log=True)

    return {'Ski': Ski, 'dp': dp, 'fi': fi, 'fs': fs, 'R_max': R_max}
コード例 #3
0
def plot_image(data2):
    """ Grafica la magnitud de la imagen"""

    # a) Definicion y lectura de parametros
    Im = data2['Im']

    # b) Grafica final(magnitud)
    cmap="plasma"
    vmin = -100 #dB
    vmax = -20
    dF.plotImage(Im,cmap=cmap,xlabel_name='Azimut(m)',ylabel_name='Rango(m)', title_name='Resultado Algoritmo Back Projection',
                 x_min=-(Lx+dx)/2, x_max=(Lx+dx)/2, y_min=0-dy/2, y_max=Ly+dy/2,unit_bar='(dB)',log=True,vmin=vmin,
                 vmax=vmax)
    return Im
コード例 #4
0
def get_SAR_data():
    """ Obtiene el histórico de fase ya sea simulado o real"""
    # Cálculo de parámetros
    dp = Ls / (Np - 1)  # Paso del riel(m)
    df = BW / (Nf - 1)  # Paso en frecuencia del BW
    fi = fc - BW / 2  # Frecuencia inferior(GHz)
    fs = fc + BW / 2  # Frecuencia superior(GHz)

    # Rango máximo
    R_max = Nf * c / (2 * BW)
    # Paso del riel máximo
    dp_max = c / (fc * 4 * np.sin(theta * np.pi / 180)
                  )  # Theta en grados sexagesimales

    # Cálculo de las resoluciones
    rr_r = c / (2 * BW)  # Resolución en rango
    rr_a = c / (2 * Ls * fc)  # Resolución en azimuth

    #-----------------VERIFICACIÓN DE CONDICIONES------------------------
    print("------------------------------------------------------")
    print("--------------INFORMACIÓN IMPORTANTE------------------")
    print("------------------------------------------------------")
    print("- Resolución en rango(m) : ", rr_r)
    print("- Resolución en azimuth(rad): ", rr_a)
    print("------------------------------------------------------")
    print("- Rango máximo permitido(m): ", R_max)
    print("------------------------------------------------------")
    print("______¿Se cumplen las siguientes condiciones?_________")
    print("Rango máximo del target <= rango máximo?: ",
          R_max <= R_max)  # Ponerle un try-except
    print("Paso del riel <= paso máximo?: ",
          dp <= dp_max)  # Evita el aliasing en el eje de azimuth
    print("------------------------------------------------------")

    #----------------OBTENCIÓN DEL HISTÓRICO DE FASE----------------------
    Sr_f = np.array(list(dset))

    #-----------------GRÁFICA DEL HISTÓRICO DE FASE-----------------------
    dF.plotImage(Sr_f,
                 x_min=fi,
                 x_max=fs,
                 y_min=-Ls / 2,
                 y_max=Ls / 2,
                 xlabel_name='Frecuency(GHz)',
                 ylabel_name='Riel Position(m)',
                 title_name='Histórico de fase',
                 unit_bar='dBu',
                 origin_n='upper')

    return {'Sr_f': Sr_f, 'df': df, 'fi': fi, 'rr_r': rr_r}
コード例 #5
0
ファイル: RMA_prog1.py プロジェクト: LuisDLCP/Python_files
Lista_pos = data.getRiel_pos()  # Vector de posiciones del riel
Ri = data.getDist()  # Vector de distancias del riel al target

#--------------------PHASE HISTORICAL---------------------------
Sr_f = np.array([
    np.exp(-1j * 4 * np.pi * fi * ri / c) for ri in Ri for fi in Lista_f
])  # Create a vector with value for each fi y ri
Sr_f = np.reshape(Sr_f, (Np, Nf))  # Reshape the last vector Sr_f

# Grafica del historico de fase
plt.close('all')  # Cerrar todas las figuras previas
dF.plotImage(Sr_f,
             x_min=fi,
             x_max=fs,
             y_min=Ls / 2,
             y_max=-Ls / 2,
             xlabel_name='Frecuency(GHz)',
             ylabel_name='Riel Position(m)',
             title_name='Histórico de fase - [xo,yo]=[%i,%i]' % (Rt_x, Rt_y),
             unit_bar='dBu',
             origin_n='upper')

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#########################################################
#        PROCESAMIENTO Y GENERACION DE LA IMAGEN        #
#########################################################
#
start_time = time.clock()

#------------------PARAMETROS----------------------------
# Definiendo el area de la imagen
コード例 #6
0
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}
コード例 #7
0
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}