##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}
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}