Ejemplo n.º 1
0
def raw_data_extraction(raw_output_file=None):

    ###################
    # INITIALIZATIONS #
    ###################
    # RAW DATA
    raw_file = tpio.RawFile(raw_output_file, 'r')
    raw_data = raw_file.get('raw_data*')
    raw_file.close()
    return raw_data
Ejemplo n.º 2
0
def raw_data_extraction(raw_output_file):

    ###################
    # INITIALIZATIONS #
    ###################
     # RAW DATA
    raw_file = tpio.RawFile(raw_output_file, 'r')
    raw_data = raw_file.get('raw_data*')
    #dop_ref = raw_file.get('dop_ref')
    #sr0 = raw_file.get('sr0')
    #azimuth = raw_file.get('azimuth')
    raw_file.close()
    #n_az
    return raw_data
Ejemplo n.º 3
0
def skim_process(cfg_file, raw_output_file):

    ###################
    # INITIALIZATIONS #
    ###################

    # CONFIGURATION FILE
    cfg = tpio.ConfigFile(cfg_file)
    info = utils.PrInfo(cfg.sim.verbosity, "processor")
    # Say hello
    info.msg(time.strftime("Starting: %Y-%m-%d %H:%M:%S", time.localtime()))
    # PROCESSING
    az_weighting = cfg.processing.az_weighting
    doppler_bw = cfg.processing.doppler_bw
    plot_format = cfg.processing.plot_format
    plot_tex = cfg.processing.plot_tex
    plot_save = cfg.processing.plot_save
    plot_path = cfg.processing.plot_path
    plot_raw = cfg.processing.plot_raw
    plot_rcmc_dopp = cfg.processing.plot_rcmc_dopp
    plot_rcmc_time = cfg.processing.plot_rcmc_time
    plot_image_valid = cfg.processing.plot_image_valid
    doppler_demod = cfg.processing.doppler_demod
    pp_file = os.path.join(cfg.sim.path, cfg.sim.pp_file)

    # radar
    f0 = cfg.radar.f0
    prf = cfg.radar.prf
    # num_ch = cfg.radar.num_ch
    alt = cfg.radar.alt
    v_ground = cfg.radar.v_ground

    # CALCULATE PARAMETERS
    l0 = const.c / f0
    if v_ground == 'auto':
        v_ground = geo.orbit_to_vel(alt, ground=True)
    rg_sampling = cfg.radar.Fs
    # Range freqency axis
    f_axis = np.linspace(0, rg_sampling, cfg.radar.n_rg)
    wavenum_scale = f_axis * 4 * np.pi / const.c * np.sin(
        np.radians(cfg.radar.inc_angle))

    # RAW DATA
    raw_file = tpio.RawFile(raw_output_file, 'r')
    raw_data = raw_file.get('raw_data*')
    info.msg("Raw data max: %f" % (np.max(np.abs(raw_data))))
    dop_ref = raw_file.get('dop_ref')
    sr0 = raw_file.get('sr0')
    azimuth = raw_file.get('azimuth')
    raw_file.close()
    #n_az

    # OTHER INITIALIZATIONS
    # Create plots directory
    plot_path = os.path.dirname(pp_file) + os.sep + plot_path
    if plot_save:
        if not os.path.exists(plot_path):
            os.makedirs(plot_path)

    ########################
    # PROCESSING MAIN LOOP #
    ########################

    # Optimize matrix sizes
    az_size_orig, rg_size_orig = raw_data[0].shape
    optsize = utils.optimize_fftsize(raw_data[0].shape)
    # optsize = [optsize[0], optsize[1]]
    data = np.zeros(optsize, dtype=complex)
    data[0:az_size_orig, 0:rg_size_orig] = raw_data[0]
    # Doppler demodulation according to geometric Doppler
    if doppler_demod:
        info.msg("Doppler demodulation")
        t_vec = (np.arange(optsize[0]) / prf).reshape((optsize[0], 1))
        data[:, 0:rg_size_orig] = (data[:, 0:rg_size_orig] * np.exp(
            (-2j * np.pi) * t_vec * dop_ref.reshape((1, rg_size_orig))))
    # Pulse pair
    info.msg("Range over-sampling")
    data_ovs = range_oversample(data)
    info.msg("Pulse-pair processing")
    dop_pp_avg, dop_pha_avg, coh = pulse_pair(
        data_ovs[0:az_size_orig, 0:2 * rg_size_orig], prf)
    krv, mean_int_profile, int_spe, phase_spec = rar_spectra(
        data_ovs[0:az_size_orig, 0:2 * rg_size_orig],
        2 * rg_sampling,
        rgsmth=8)
    kxv = krv * np.sin(np.radians(cfg.radar.inc_angle))
    range_spectrum(data[0:az_size_orig, 0:rg_size_orig], rg_sampling,
                   plot_path)
    info.msg("Mean DCA (pulse-pair average): %f Hz" % (np.mean(dop_pp_avg)))
    info.msg("Mean DCA (pulse-pair phase average): %f Hz" %
             (np.mean(dop_pha_avg)))
    info.msg("Mean coherence: %f " % (np.mean(coh)))

    # Unfocused SAR
    info.msg("Unfocused SAR")
    int_unfcs, data_ufcs = unfocused_sar(
        data_ovs[0:az_size_orig, 0:2 * rg_size_orig], cfg.processing.n_sar)
    krv2, sar_int_spec = sar_spectra(int_unfcs, 2 * rg_sampling, rgsmth=8)

    # Some delta-k on focused sar data
    info.msg("Unfocused SAR delta-k spectrum")
    dkr, dk_avg, dk_signal = sar_delta_k(data_ufcs, 2 * rg_sampling, dksmoth=8)
    dk_pulse_pairs, dk_omega = sar_delta_k_omega(dk_signal,
                                                 cfg.processing.n_sar / prf,
                                                 dksmoth=16)
    # For verification, comment out
    # dkr_sl, dk_avg_sl, dk_signal_sl = sar_delta_k_slow(data_ufcs, 2 * rg_sampling, dksmoth=8)
    # dk_pulse_pairs_sl, dk_omega_sl = sar_delta_k_omega(dk_signal_sl, cfg.processing.n_sar/prf, dksmoth=32)
    info.msg(
        time.strftime("Processing done [%Y-%m-%d %H:%M:%S]", time.localtime()))

    if plot_raw:
        plt.figure()
        plt.imshow(np.real(raw_data[0]),
                   vmin=-np.max(np.abs(raw_data[0])),
                   vmax=np.max(np.abs(raw_data[0])),
                   origin='lower',
                   aspect=np.float(raw_data[0].shape[1]) /
                   np.float(raw_data[0].shape[0]),
                   cmap='viridis')
        #plt.title()
        plt.xlabel("Range [samples]")
        plt.ylabel("Azimuth [samples")
        plt.savefig(plot_path + os.sep + 'plot_raw_real.%s' % plot_format,
                    dpi=150)
        plt.close()
        plt.figure()
        plt.imshow(np.abs(raw_data[0]),
                   vmin=0,
                   vmax=np.max(np.abs(raw_data[0])),
                   origin='lower',
                   aspect=np.float(raw_data[0].shape[1]) /
                   np.float(raw_data[0].shape[0]),
                   cmap='viridis')
        #plt.title()
        plt.xlabel("Range [samples]")
        plt.ylabel("Azimuth [samples")
        plt.savefig(plot_path + os.sep + 'plot_raw_abs.%s' % plot_format,
                    dpi=150)
        plt.close()

    plt.figure()
    plt.imshow(np.fft.fftshift(int_unfcs, axes=(0, )),
               origin='lower',
               aspect='auto',
               cmap='viridis')
    # plt.title()
    plt.xlabel("Range [samples]")
    plt.ylabel("Doppler [samples")
    plt.savefig(plot_path + os.sep + 'ufcs_int.%s' % plot_format, dpi=150)
    plt.close()

    plt.figure()
    plt.plot(mean_int_profile)
    plt.xlabel("Range samples [Pixels]")
    plt.ylabel("Intensity")
    plt.savefig(plot_path + os.sep + 'mean_int.%s' % plot_format)
    plt.close()

    plt.figure()
    plt.plot(np.fft.fftshift(kxv), np.fft.fftshift(int_spe))
    plt.ylim((int_spe[20:np.int(cfg.radar.n_rg) - 20].min() / 2,
              int_spe[20:np.int(cfg.radar.n_rg) - 20].max() * 1.5))
    plt.xlim((0, kxv.max()))
    plt.xlabel("$k_x$ [rad/m]")
    plt.ylabel("$S_I$")
    plt.savefig(plot_path + os.sep + 'int_spec.%s' % plot_format)
    plt.close()

    plt.figure()
    plt.plot(np.fft.fftshift(kxv), np.fft.fftshift(sar_int_spec))
    plt.ylim((sar_int_spec[20:np.int(cfg.radar.n_rg) - 20].min() / 2,
              sar_int_spec[20:np.int(cfg.radar.n_rg) - 20].max() * 1.5))
    plt.xlim((0, kxv.max()))
    plt.xlabel("$k_x$ [rad/m]")
    plt.ylabel("$S_I$")
    plt.savefig(plot_path + os.sep + 'sar_int_spec.%s' % plot_format)
    plt.close()

    plt.figure()
    plt.plot(np.fft.fftshift(kxv), np.fft.fftshift(phase_spec))
    plt.ylim((phase_spec[20:np.int(cfg.radar.n_rg) - 20].min() / 2,
              phase_spec[20:np.int(cfg.radar.n_rg) - 20].max() * 1.5))
    plt.xlabel("$k_x$ [rad/m]")
    plt.xlim((0, kxv.max()))
    plt.ylabel("$S_{Doppler}$")
    plt.savefig(plot_path + os.sep + 'pp_phase_spec.%s' % plot_format)

    plt.figure()
    dkx = dkr * np.sin(np.radians(cfg.radar.inc_angle))
    plt.plot(dkx, dk_avg)
    plt.ylim((dk_avg[20:dkx.size - 20].min() / 2,
              dk_avg[20:dkx.size - 20].max() * 1.5))
    plt.xlim((0.1, dkx.max()))
    plt.xlabel("$\Delta k_x$ [rad/m]")
    plt.ylabel("$S_I$")
    plt.savefig(plot_path + os.sep + 'sar_delta_k_spec.%s' % plot_format)
    plt.close()

    # plt.figure()
    # dkx_sl = dkr_sl * np.sin(np.radians(cfg.radar.inc_angle))
    # plt.plot(dkx_sl, dk_avg_sl)
    # plt.ylim((dk_avg_sl[20:dkx.size-20].min()/2,
    #           dk_avg_sl[20:dkx.size-20].max()*1.5))
    # plt.xlim((0, dkx.max()))
    # plt.xlabel("$\Delta k_x$ [rad/m]")
    # plt.ylabel("$S_I$")
    # plt.savefig(plot_path + os.sep + 'sar_delta_k_spec_slow.%s' % plot_format)
    # plt.close()

    plt.figure()
    # plt.plot(dkx, dk_omega[0], label="lag=1")
    plt.plot(dkx, dk_omega[1], label="lag=2")
    # plt.plot(dkx, dk_omega_sl[0] + 1, label="slow-lag=1")
    # plt.plot(dkx, dk_omega_sl[1] + 1, label="slow-lag=2")
    plt.plot(dkx, dk_omega[3], label="lag=4")
    # plt.plot(dkx, dk_omega[-1], label="lag=max")
    plt.ylim((-20, 20))
    #plt.ylim((dk_avg[20:dkx.size - 20].min() / 2,
    #          dk_avg[20:dkx.size - 20].max() * 1.5))
    plt.xlim((0.05, 0.8))
    plt.xlabel("$\Delta k_x$ [rad/m]")
    plt.ylabel("$\omega$ [rad/s]")
    plt.legend(loc=0)
    plt.savefig(plot_path + os.sep + 'sar_delta_k_omega.%s' % plot_format)
    plt.close()

    info.msg("Saving output to %s" % pp_file)
    np.savez(pp_file,
             dop_pp_avg=dop_pp_avg,
             dop_pha_avg=dop_pha_avg,
             coh=coh,
             ufcs_intensity=int_unfcs,
             mean_int_profile=mean_int_profile,
             int_spec=int_spe,
             sar_int_spec=sar_int_spec,
             ppphase_spec=phase_spec,
             kx=kxv,
             dk_spec=dk_avg,
             dk_omega=dk_omega,
             dkx=dkx)

    info.msg(time.strftime("All done [%Y-%m-%d %H:%M:%S]", time.localtime()))
Ejemplo n.º 4
0
def fastraw(cfg_file, output_file, ocean_file, reuse_ocean_file, errors_file, reuse_errors_file,
            plot_save=True):

    ###################
    # INITIALIZATIONS #
    ###################

    ## MPI SETUP
    comm = MPI.COMM_WORLD
    size, rank = comm.Get_size(), comm.Get_rank()

    ## WELCOME
    if rank == 0:
        print('-------------------------------------------------------------------')
        print(time.strftime("- OCEANSAR FAST RAW SAR GENERATOR: %Y-%m-%d %H:%M:%S", time.localtime()))
        print('-------------------------------------------------------------------')

    ## CONFIGURATION FILE
    # Note: variables are 'copied' to reduce code verbosity
    cfg = tpio.ConfigFile(cfg_file)

    # RAW
    wh_tol = cfg.srg.wh_tol
    nesz = cfg.srg.nesz
    use_hmtf = cfg.srg.use_hmtf
    scat_spec_enable = cfg.srg.scat_spec_enable
    scat_spec_mode = cfg.srg.scat_spec_mode
    scat_bragg_enable = cfg.srg.scat_bragg_enable
    scat_bragg_model = cfg.srg.scat_bragg_model
    scat_bragg_d = cfg.srg.scat_bragg_d
    scat_bragg_spec = cfg.srg.scat_bragg_spec
    scat_bragg_spread = cfg.srg.scat_bragg_spread

    # SAR
    inc_angle = np.deg2rad(cfg.sar.inc_angle)
    f0 = cfg.sar.f0
    pol = cfg.sar.pol
    squint_r = np.degrees(cfg.sar.squint)
    if pol == 'DP':
        do_hh = True
        do_vv = True
    elif pol == 'hh':
        do_hh = True
        do_vv = False
    else:
        do_hh = False
        do_vv = True

    prf = cfg.sar.prf
    num_ch = int(cfg.sar.num_ch)
    ant_l = cfg.sar.ant_L
    alt = cfg.sar.alt
    v_ground = cfg.sar.v_ground
    rg_bw = cfg.sar.rg_bw
    over_fs = cfg.sar.over_fs
    sigma_n_tx = cfg.sar.sigma_n_tx
    phase_n_tx = np.deg2rad(cfg.sar.phase_n_tx)
    sigma_beta_tx = cfg.sar.sigma_beta_tx
    phase_beta_tx = np.deg2rad(cfg.sar.phase_beta_tx)
    sigma_n_rx = cfg.sar.sigma_n_rx
    phase_n_rx = np.deg2rad(cfg.sar.phase_n_rx)
    sigma_beta_rx = cfg.sar.sigma_beta_rx
    phase_beta_rx = np.deg2rad(cfg.sar.phase_beta_rx)

    # OCEAN / OTHERS
    ocean_dt = cfg.ocean.dt

    add_point_target = False
    use_numba = True
    n_sinc_samples = 8
    sinc_ovs = 20
    chan_sinc_vec = raw.calc_sinc_vec(n_sinc_samples, sinc_ovs, Fs=over_fs)
    # OCEAN SURFACE

    print('Initializing ocean surface...')

    surface = OceanSurface()
    # Setup compute values
    compute = ['D', 'Diff', 'Diff2']
    if use_hmtf:
        compute.append('hMTF')

    # Try to reuse initialized surface
    if reuse_ocean_file:
        try:
            surface.load(ocean_file, compute)
        except RuntimeError:
            pass

    if (not reuse_ocean_file) or (not surface.initialized):

        if hasattr(cfg.ocean, 'use_buoy_data'):
            if cfg.ocean.use_buoy_data:
                bdataf = cfg.ocean.buoy_data_file
                date = datetime.datetime(np.int(cfg.ocean.year),
                                         np.int(cfg.ocean.month),
                                         np.int(cfg.ocean.day),
                                         np.int(cfg.ocean.hour),
                                         np.int(cfg.ocean.minute), 0)
                date, bdata = tpio.load_buoydata(bdataf, date)
                buoy_spec = tpio.BuoySpectra(bdata, heading=cfg.sar.heading, depth=cfg.ocean.depth)
                dirspectrum_func = buoy_spec.Sk2
                # Since the wind direction is included in the buoy data
                wind_dir = 0
            else:
                dirspectrum_func = None
                wind_dir = np.deg2rad(cfg.ocean.wind_dir)
        else:
            dirspectrum_func = None
            wind_dir = np.deg2rad(cfg.ocean.wind_dir)

        surface.init(cfg.ocean.Lx, cfg.ocean.Ly, cfg.ocean.dx,
                     cfg.ocean.dy, cfg.ocean.cutoff_wl,
                     cfg.ocean.spec_model, cfg.ocean.spread_model,
                     wind_dir,
                     cfg.ocean.wind_fetch, cfg.ocean.wind_U,
                     cfg.ocean.current_mag,
                     np.deg2rad(cfg.ocean.current_dir),
                     cfg.ocean.dir_swell_dir,
                     cfg.ocean.freq_r, cfg.ocean.sigf,
                     cfg.ocean.sigs, cfg.ocean.Hs,
                     cfg.ocean.swell_dir_enable,
                     cfg.ocean.swell_enable, cfg.ocean.swell_ampl,
                     np.deg2rad(cfg.ocean.swell_dir),
                     cfg.ocean.swell_wl,
                     compute, cfg.ocean.opt_res,
                     cfg.ocean.fft_max_prime,
                     choppy_enable=cfg.ocean.choppy_enable,
                     depth=cfg.ocean.depth,
                     dirspectrum_func=dirspectrum_func)

        surface.save(ocean_file)
        # Now we plot the directional spectrum
        # self.wave_dirspec[good_k] = dirspectrum_func(self.kx[good_k], self.ky[good_k])
        plt.figure()
        plt.imshow(np.fft.fftshift(surface.wave_dirspec),
                   extent=[surface.kx.min(), surface.kx.max(),
                           surface.ky.min(), surface.ky.max()],
                   origin='lower',
                   cmap='inferno_r')

        plt.grid(True)
        pltax = plt.gca()
        pltax.set_xlim((-0.1, 0.1))
        pltax.set_ylim((-0.1, 0.1))
        narr_length = 0.08 # np.min([surface_full.kx.max(), surface_full.ky.max()])
        pltax.arrow(0, 0,
                    -narr_length * np.sin(np.radians(cfg.sar.heading)),
                    narr_length * np.cos(np.radians(cfg.sar.heading)),
                    fc="k", ec="k")
        plt.xlabel('$k_x$ [rad/m]')
        plt.ylabel('$k_y$ [rad/m]')
        plt.colorbar()
        #plt.show()
        # Create plots directory
        plot_path = os.path.dirname(output_file) + os.sep + 'raw_plots'
        if plot_save:
            if not os.path.exists(plot_path):
                os.makedirs(plot_path)

        plt.savefig(os.path.join(plot_path, 'input_dirspectrum.png'))
        plt.close()

    # CALCULATE PARAMETERS
    if rank == 0:
        print('Initializing simulation parameters...')

    # SR/GR/INC Matrixes
    sr0 = geosar.inc_to_sr(inc_angle, alt)
    gr0 = geosar.inc_to_gr(inc_angle, alt)
    gr = surface.x + gr0
    sr, inc, _ = geosar.gr_to_geo(gr, alt)
    sr -= np.min(sr)

    inc = inc.reshape(1, inc.size)
    sr = sr.reshape(1, sr.size)
    gr = gr.reshape(1, gr.size)
    sin_inc = np.sin(inc)
    cos_inc = np.cos(inc)

    # lambda, K, resolution, time, etc.
    l0 = const.c/f0
    k0 = 2.*np.pi*f0/const.c
    sr_res = const.c/(2.*rg_bw)
    if cfg.sar.L_total:
        ant_l = ant_l/np.float(num_ch)
        d_chan = ant_l
    else:
        if np.float(cfg.sar.Spacing) != 0:
            d_chan = np.float(cfg.sar.Spacing)
        else:
            d_chan = ant_l

    if v_ground == 'auto':
        v_ground = geosar.orbit_to_vel(alt, ground=True)
    t_step = 1./prf
    t_span = (1.5*(sr0*l0/ant_l) + surface.Ly)/v_ground
    az_steps = np.int(np.floor(t_span/t_step))

    # Number of RG samples
    max_sr = np.max(sr) + wh_tol + (np.max(surface.y) + (t_span/2.)*v_ground)**2./(2.*sr0)
    min_sr = np.min(sr) - wh_tol
    rg_samp_orig = np.int(np.ceil(((max_sr - min_sr)/sr_res)*over_fs))
    rg_samp = np.int(utils.optimize_fftsize(rg_samp_orig))

    # Other initializations
    if do_hh:
        proc_raw_hh = np.zeros([num_ch, az_steps, rg_samp], dtype=np.complex)
    if do_vv:
        proc_raw_vv = np.zeros([num_ch, az_steps, rg_samp], dtype=np.complex)
    t_last_rcs_bragg = -1.
    last_progress = -1
    nrcs_avg_vv = np.zeros(az_steps, dtype=np.float)
    nrcs_avg_hh = np.zeros(az_steps, dtype=np.float)

    ## RCS MODELS
    # Specular
    if scat_spec_enable:
        if scat_spec_mode == 'kodis':
            rcs_spec = rcs.RCSKodis(inc, k0, surface.dx, surface.dy)
        elif scat_spec_mode == 'fa' or scat_spec_mode == 'spa':
            spec_ph0 = np.random.uniform(0., 2.*np.pi,
                                         size=[surface.Ny, surface.Nx])
            rcs_spec = rcs.RCSKA(scat_spec_mode, k0, surface.x, surface.y,
                                 surface.dx, surface.dy)
        else:
            raise NotImplementedError('RCS mode %s for specular scattering not implemented' % scat_spec_mode)

    # Bragg
    if scat_bragg_enable:
        phase_bragg = np.zeros([2, surface.Ny, surface.Nx])
        bragg_scats = np.zeros([2, surface.Ny, surface.Nx], dtype=np.complex)
        # dop_phase_p = np.random.uniform(0., 2.*np.pi, size=[surface.Ny, surface.Nx])
        # dop_phase_m = np.random.uniform(0., 2.*np.pi, size=[surface.Ny, surface.Nx])
        tau_c = closure.grid_coherence(cfg.ocean.wind_U,surface.dx, f0)
        rndscat_p = closure.randomscat_ts(tau_c, (surface.Ny, surface.Nx), prf)
        rndscat_m = closure.randomscat_ts(tau_c, (surface.Ny, surface.Nx), prf)
        # NOTE: This ignores slope, may be changed
        k_b = 2.*k0*sin_inc
        c_b = sin_inc*np.sqrt(const.g/k_b + 0.072e-3*k_b)

        if scat_bragg_model == 'romeiser97':
            current_dir = np.deg2rad(cfg.ocean.current_dir)
            current_vec = (cfg.ocean.current_mag *
                           np.array([np.cos(current_dir),
                                     np.sin(current_dir)]))
            U_dir = np.deg2rad(cfg.ocean.wind_dir)
            U_vec = (cfg.ocean.wind_U *
                     np.array([np.cos(U_dir), np.sin(U_dir)]))
            U_eff_vec = U_vec - current_vec

            rcs_bragg = rcs.RCSRomeiser97(k0, inc, pol,
                                          surface.dx, surface.dy,
                                          linalg.norm(U_eff_vec),
                                          np.arctan2(U_eff_vec[1],
                                                     U_eff_vec[0]),
                                          surface.wind_fetch,
                                          scat_bragg_spec, scat_bragg_spread,
                                          scat_bragg_d)
        else:
            raise NotImplementedError('RCS model %s for Bragg scattering not implemented' % scat_bragg_model)

    surface_area = surface.dx * surface.dy * surface.Nx * surface.Ny
    ###################
    # SIMULATION LOOP #
    ###################
    if rank == 0:
        print('Computing profiles...')

    for az_step in np.arange(az_steps, dtype=np.int):

        # AZIMUTH & SURFACE UPDATE
        t_now = az_step * t_step
        az_now = (t_now - t_span/2.)*v_ground
        # az = np.repeat((surface.y - az_now)[:, np.newaxis], surface.Nx, axis=1)
        az = (surface.y - az_now).reshape((surface.Ny, 1))
        surface.t = t_now

        # COMPUTE RCS FOR EACH MODEL
        # Note: SAR processing is range independent as slant range is fixed
        sin_az = az / sr0
        az_proj_angle = np.arcsin(az / gr0)

        # Note: Projected displacements are added to slant range
        sr_surface = (sr - cos_inc*surface.Dz + az/2*sin_az
                      + surface.Dx*sin_inc + surface.Dy*sin_az)

        if do_hh:
            scene_hh = np.zeros([int(surface.Ny), int(surface.Nx)], dtype=np.complex)
        if do_vv:
            scene_vv = np.zeros([int(surface.Ny), int(surface.Nx)], dtype=np.complex)
        # Point target
        if add_point_target and rank == 0:
            sr_pt = (sr[0, surface.Nx/2] + az[surface.Ny/2, 0]/2 *
                     sin_az[surface.Ny/2, surface.Nx/2])
            pt_scat = (100. * np.exp(-1j * 2. * k0 * sr_pt))
            if do_hh:
                scene_hh[surface.Ny/2, surface.Nx/2] = pt_scat
            if do_vv:
                scene_vv[surface.Ny/2, surface.Nx/2] = pt_scat
            sr_surface[surface.Ny/2, surface.Nx/2] = sr_pt

        # Specular
        if scat_spec_enable:
            if scat_spec_mode == 'kodis':
                Esn_sp = np.sqrt(4.*np.pi)*rcs_spec.field(az_proj_angle, sr_surface,
                                                          surface.Diffx, surface.Diffy,
                                                          surface.Diffxx, surface.Diffyy, surface.Diffxy)
                if do_hh:
                    scene_hh += Esn_sp
                if do_vv:
                    scene_vv += Esn_sp
            else:
                # FIXME
                if do_hh:
                    pol_tmp = 'hh'
                    Esn_sp = (np.exp(-1j*(2.*k0*sr_surface)) * (4.*np.pi)**1.5 *
                              rcs_spec.field(1, 1, pol_tmp[0], pol_tmp[1],
                                             inc, inc,
                                             az_proj_angle, az_proj_angle + np.pi,
                                             surface.Dz,
                                             surface.Diffx, surface.Diffy,
                                             surface.Diffxx,
                                             surface.Diffyy,
                                             surface.Diffxy))
                    scene_hh += Esn_sp
                if do_vv:
                    pol_tmp = 'vv'
                    Esn_sp = (np.exp(-1j*(2.*k0*sr_surface)) * (4.*np.pi)**1.5 *
                              rcs_spec.field(1, 1, pol_tmp[0], pol_tmp[1],
                                             inc, inc,
                                             az_proj_angle, az_proj_angle + np.pi,
                                             surface.Dz,
                                             surface.Diffx, surface.Diffy,
                                             surface.Diffxx,
                                             surface.Diffyy,
                                             surface.Diffxy))
                    scene_vv += Esn_sp
            nrcs_avg_hh[az_step] += (np.sum(np.abs(Esn_sp)**2) / surface_area)
            nrcs_avg_vv[az_step] += nrcs_avg_hh[az_step]

        # Bragg
        if scat_bragg_enable:
            if (t_now - t_last_rcs_bragg) > ocean_dt:

                if scat_bragg_model == 'romeiser97':
                    if pol == 'DP':
                        rcs_bragg_hh, rcs_bragg_vv = rcs_bragg.rcs(az_proj_angle,
                                                                   surface.Diffx,
                                                                   surface.Diffy)
                    elif pol=='hh':
                        rcs_bragg_hh = rcs_bragg.rcs(az_proj_angle,
                                                     surface.Diffx,
                                                     surface.Diffy)
                    else:
                        rcs_bragg_vv = rcs_bragg.rcs(az_proj_angle,
                                                     surface.Diffx,
                                                     surface.Diffy)

                if use_hmtf:
                    # Fix Bad MTF points
                    surface.hMTF[np.where(surface.hMTF < -1)] = -1
                    if do_hh:
                        rcs_bragg_hh[0] *= (1 + surface.hMTF)
                        rcs_bragg_hh[1] *= (1 + surface.hMTF)
                    if do_vv:
                        rcs_bragg_vv[0] *= (1 + surface.hMTF)
                        rcs_bragg_vv[1] *= (1 + surface.hMTF)

                t_last_rcs_bragg = t_now

            if do_hh:
                scat_bragg_hh = np.sqrt(rcs_bragg_hh)
                nrcs_bragg_hh_instant_avg = np.sum(rcs_bragg_hh) / surface_area
                nrcs_avg_hh[az_step] += nrcs_bragg_hh_instant_avg
            if do_vv:
                scat_bragg_vv = np.sqrt(rcs_bragg_vv)
                nrcs_bragg_vv_instant_avg = np.sum(rcs_bragg_vv) / surface_area
                nrcs_avg_vv[az_step] += nrcs_bragg_vv_instant_avg


            # Doppler phases (Note: Bragg radial velocity taken constant!)
            surf_phase = - (2 * k0) * sr_surface
            cap_phase = (2 * k0) * t_step * c_b * (az_step + 1)
            phase_bragg[0] = surf_phase - cap_phase # + dop_phase_p
            phase_bragg[1] = surf_phase + cap_phase # + dop_phase_m
            bragg_scats[0] = rndscat_m.scats(t_now)
            bragg_scats[1] = rndscat_p.scats(t_now)
            if do_hh:
                scene_hh += ne.evaluate('sum(scat_bragg_hh * exp(1j*phase_bragg) * bragg_scats, axis=0)')
            if do_vv:
                scene_vv += ne.evaluate('sum(scat_bragg_vv * exp(1j*phase_bragg) * bragg_scats, axis=0)')

        # ANTENNA PATTERN
        #  FIXME: this assume co-located Tx and Tx, so it will not work for true bistatic configurations
        if cfg.sar.L_total:
            beam_pattern = sinc_1tx_nrx(sin_az, ant_l * num_ch, f0, num_ch, field=True)
        else:
            beam_pattern = sinc_1tx_nrx(sin_az, ant_l, f0, 1, field=True)

        #  GENERATE CHANEL PROFILES
        for ch in np.arange(num_ch, dtype=np.int):

            if do_hh:
                scene_bp = scene_hh * beam_pattern
                # Add channel phase & compute profile
                scene_bp *= np.exp(-1j*k0*d_chan*ch*sin_az)
                if use_numba:
                    raw.chan_profile_numba(sr_surface.flatten(),
                                           scene_bp.flatten(),
                                           sr_res / over_fs,
                                           min_sr,
                                           chan_sinc_vec,
                                           n_sinc_samples, sinc_ovs,
                                           proc_raw_hh[ch][az_step])

                else:
                    raw.chan_profile_weave(sr_surface.flatten(),
                                           scene_bp.flatten(),
                                           sr_res / over_fs,
                                           min_sr,
                                           chan_sinc_vec,
                                           n_sinc_samples, sinc_ovs,
                                           proc_raw_hh[ch][az_step])
            if do_vv:
                scene_bp = scene_vv * beam_pattern
                # Add channel phase & compute profile
                scene_bp *= np.exp(-1j*k0*d_chan*ch*sin_az)
                if use_numba:
                    raw.chan_profile_numba(sr_surface.flatten(),
                                           scene_bp.flatten(),
                                           sr_res / over_fs,
                                           min_sr,
                                           chan_sinc_vec,
                                           n_sinc_samples, sinc_ovs,
                                           proc_raw_vv[ch][az_step])

                else:
                    raw.chan_profile_weave(sr_surface.flatten(),
                                           scene_bp.flatten(),
                                           sr_res / over_fs,
                                           min_sr,
                                           chan_sinc_vec,
                                           n_sinc_samples, sinc_ovs,
                                           proc_raw_vv[ch][az_step])

        # SHOW PROGRESS (%)
        current_progress = np.int((100 * az_step) / az_steps)
        if current_progress != last_progress:
            last_progress = current_progress
            print('SP,%d,%d,%d' % (rank, size, current_progress))

    # PROCESS REDUCED RAW DATA & SAVE (ROOT)
    if rank == 0:
        print('Processing and saving results...')

        # Filter and decimate
        #range_filter = np.ones_like(total_raw)
        #range_filter[:, :, rg_samp/(2*2*cfg.sar.over_fs):-rg_samp/(2*2*cfg.sar.over_fs)] = 0

        #total_raw = np.fft.ifft(range_filter*np.fft.fft(total_raw))
        if do_hh:
            proc_raw_hh = proc_raw_hh[:, :, :rg_samp_orig]
        if do_vv:
            proc_raw_vv = proc_raw_vv[:, :, :rg_samp_orig]

        # Calibration factor (projected antenna pattern integrated in azimuth)
        az_axis = np.arange(-t_span/2.*v_ground, t_span/2.*v_ground, sr0*const.c/(np.pi*f0*ant_l*10.))

        if cfg.sar.L_total:
            pattern = sinc_1tx_nrx(az_axis/sr0, ant_l * num_ch, f0,
                                   num_ch, field=True)
        else:
            pattern = sinc_1tx_nrx(az_axis/sr0, ant_l, f0, 1,
                                   field=True)
        cal_factor = (1. / np.sqrt(np.trapz(np.abs(pattern)**2., az_axis) *
                      sr_res/np.sin(inc_angle)))

        if do_hh:
            noise = (utils.db2lin(nesz, amplitude=True) / np.sqrt(2.) *
                     (np.random.normal(size=proc_raw_hh.shape) +
                      1j*np.random.normal(size=proc_raw_hh.shape)))
            total_raw_hh = proc_raw_hh * cal_factor + noise
        if do_vv:
            noise = (utils.db2lin(nesz, amplitude=True) / np.sqrt(2.) *
                     (np.random.normal(size=proc_raw_vv.shape) +
                      1j*np.random.normal(size=proc_raw_vv.shape)))
            total_raw_vv = proc_raw_vv * cal_factor + noise

        # Add slow-time error
        # if use_errors:
        #     if do_hh:
        #         total_raw_hh *= errors.beta_noise
        #     if do_vv:
        #         total_raw_vv *= errors.beta_noise

        # Save RAW data (and other properties, used by 3rd party software)
        if do_hh and do_vv:
            rshp = (1,) + proc_raw_hh.shape
            proc_raw = np.concatenate((proc_raw_hh.reshape(rshp),
                                        proc_raw_vv.reshape(rshp)))
            rshp = (1,) + nrcs_avg_hh.shape
            NRCS_avg = np.concatenate((nrcs_avg_hh.reshape(rshp),
                                       nrcs_avg_vv.reshape(rshp)))
        elif do_hh:
            rshp = (1,) + proc_raw_hh.shape
            proc_raw = proc_raw_hh.reshape(rshp)
            rshp = (1,) + nrcs_avg_hh.shape
            NRCS_avg = nrcs_avg_hh.reshape(rshp)
        else:
            rshp = (1,) + proc_raw_vv.shape
            proc_raw = proc_raw_vv.reshape(rshp)
            rshp = (1,) + nrcs_avg_vv.shape
            NRCS_avg = nrcs_avg_vv.reshape(rshp)

        raw_file = tpio.RawFile(output_file, 'w', proc_raw.shape)
        raw_file.set('inc_angle', np.rad2deg(inc_angle))
        raw_file.set('f0', f0)
        raw_file.set('num_ch', num_ch)
        raw_file.set('ant_l', ant_l)
        raw_file.set('prf', prf)
        raw_file.set('v_ground', v_ground)
        raw_file.set('orbit_alt', alt)
        raw_file.set('sr0', sr0)
        raw_file.set('rg_sampling', rg_bw*over_fs)
        raw_file.set('rg_bw', rg_bw)
        raw_file.set('raw_data*', proc_raw)
        raw_file.set('NRCS_avg', NRCS_avg)
        raw_file.close()

        print(time.strftime("Finished [%Y-%m-%d %H:%M:%S]", time.localtime()))
Ejemplo n.º 5
0
def sar_focus(cfg_file, raw_output_file, output_file):

    ###################
    # INITIALIZATIONS #
    ###################

    print(
        '-------------------------------------------------------------------')
    print(
        time.strftime("- OCEANSAR SAR Processor: %Y-%m-%d %H:%M:%S",
                      time.localtime()))
    print(
        '-------------------------------------------------------------------')

    # CONFIGURATION FILE
    cfg = tpio.ConfigFile(cfg_file)

    # PROCESSING
    az_weighting = cfg.processing.az_weighting
    doppler_bw = cfg.processing.doppler_bw
    plot_format = cfg.processing.plot_format
    plot_tex = cfg.processing.plot_tex
    plot_save = cfg.processing.plot_save
    plot_path = cfg.processing.plot_path
    plot_raw = cfg.processing.plot_raw
    plot_rcmc_dopp = cfg.processing.plot_rcmc_dopp
    plot_rcmc_time = cfg.processing.plot_rcmc_time
    plot_image_valid = cfg.processing.plot_image_valid

    # SAR
    f0 = cfg.sar.f0
    prf = cfg.sar.prf
    num_ch = cfg.sar.num_ch
    alt = cfg.sar.alt
    v_ground = cfg.sar.v_ground
    rg_bw = cfg.sar.rg_bw
    over_fs = cfg.sar.over_fs

    # CALCULATE PARAMETERS
    l0 = const.c / f0
    if v_ground == 'auto':
        v_ground = geo.orbit_to_vel(alt, ground=True)
    rg_sampling = rg_bw * over_fs

    # RAW DATA
    raw_file = tpio.RawFile(raw_output_file, 'r')
    raw_data = raw_file.get('raw_data*')
    sr0 = raw_file.get('sr0')
    raw_file.close()

    # OTHER INITIALIZATIONS
    # Create plots directory
    plot_path = os.path.dirname(output_file) + os.sep + plot_path
    if plot_save:
        if not os.path.exists(plot_path):
            os.makedirs(plot_path)

    slc = []

    ########################
    # PROCESSING MAIN LOOP #
    ########################
    for ch in np.arange(num_ch):

        if plot_raw:
            utils.image(np.real(raw_data[0, ch]),
                        min=-np.max(np.abs(raw_data[0, ch])),
                        max=np.max(np.abs(raw_data[0, ch])),
                        cmap='gray',
                        aspect=np.float(raw_data[0, ch].shape[1]) /
                        np.float(raw_data[0, ch].shape[0]),
                        title='Raw Data',
                        xlabel='Range samples',
                        ylabel='Azimuth samples',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep + 'plot_raw_real_%d.%s' %
                        (ch, plot_format),
                        dpi=150)
            utils.image(np.imag(raw_data[0, ch]),
                        min=-np.max(np.abs(raw_data[0, ch])),
                        max=np.max(np.abs(raw_data[0, ch])),
                        cmap='gray',
                        aspect=np.float(raw_data[0, ch].shape[1]) /
                        np.float(raw_data[0, ch].shape[0]),
                        title='Raw Data',
                        xlabel='Range samples',
                        ylabel='Azimuth samples',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep + 'plot_raw_imag_%d.%s' %
                        (ch, plot_format),
                        dpi=150)
            utils.image(np.abs(raw_data[0, ch]),
                        min=0,
                        max=np.max(np.abs(raw_data[0, ch])),
                        cmap='gray',
                        aspect=np.float(raw_data[0, ch].shape[1]) /
                        np.float(raw_data[0, ch].shape[0]),
                        title='Raw Data',
                        xlabel='Range samples',
                        ylabel='Azimuth samples',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep + 'plot_raw_amp_%d.%s' %
                        (ch, plot_format),
                        dpi=150)
            utils.image(np.angle(raw_data[0, ch]),
                        min=-np.pi,
                        max=np.pi,
                        cmap='gray',
                        aspect=np.float(raw_data[0, ch].shape[1]) /
                        np.float(raw_data[0, ch].shape[0]),
                        title='Raw Data',
                        xlabel='Range samples',
                        ylabel='Azimuth samples',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep + 'plot_raw_phase_%d.%s' %
                        (ch, plot_format),
                        dpi=150)

        # Optimize matrix sizes
        az_size_orig, rg_size_orig = raw_data[0, ch].shape
        optsize = utils.optimize_fftsize(raw_data[0, ch].shape)
        optsize = [raw_data.shape[0], optsize[0], optsize[1]]
        data = np.zeros(optsize, dtype=complex)
        data[:, :raw_data[0, ch].shape[0], :raw_data[
            0, ch].shape[1]] = raw_data[:, ch, :, :]

        az_size, rg_size = data.shape[1:]

        # RCMC Correction
        print('Applying RCMC correction... [Channel %d/%d]' % (ch + 1, num_ch))

        #fr = np.linspace(-rg_sampling/2., rg_sampling/2., rg_size)
        fr = (np.arange(rg_size) - rg_size / 2) * rg_sampling / rg_size
        fr = np.roll(fr, int(-rg_size / 2))

        fa = (np.arange(az_size) - az_size / 2) * prf / az_size
        fa = np.roll(fa, int(-az_size / 2))

        ## Compensation of ANTENNA PATTERN
        ## FIXME this will not work for a long separation betwen Tx and Rx!!!
        ant_L = cfg.sar.ant_L
        # fa = 2 * v_orb / l0 * sin_az
        sin_az = fa * l0 / (2 * v_ground)
        if cfg.sar.L_total:
            beam_pattern = sinc_1tx_nrx(sin_az,
                                        ant_L * num_ch,
                                        f0,
                                        num_ch,
                                        field=True)
        else:
            beam_pattern = sinc_1tx_nrx(sin_az, ant_L, f0, 1, field=True)
        #fa[az_size/2:] = fa[az_size/2:] - prf
        rcmc_fa = sr0 / np.sqrt(1 - (fa * (l0 / 2.) / v_ground)**2.) - sr0

        data = np.fft.fft2(data)

        #        for i in np.arange(az_size):
        #            data[i,:] *= np.exp(1j*2*np.pi*2*rcmc_fa[i]/const.c*fr)
        data = (data * np.exp(4j * np.pi * rcmc_fa.reshape(
            (1, az_size, 1)) / const.c * fr.reshape((1, 1, rg_size))))
        data = np.fft.ifft(data, axis=2)

        if plot_rcmc_dopp:
            utils.image(np.abs(data[0]),
                        min=0.,
                        max=3. * np.mean(np.abs(data)),
                        cmap='gray',
                        aspect=np.float(rg_size) / np.float(az_size),
                        title='RCMC Data (Range Dopler Domain)',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep + 'plot_rcmc_dopp_%d.%s' %
                        (ch, plot_format))

        if plot_rcmc_time:
            rcmc_time = np.fft.ifft(data[0],
                                    axis=0)[:az_size_orig, :rg_size_orig]
            rcmc_time_max = np.max(np.abs(rcmc_time))
            utils.image(np.real(rcmc_time),
                        min=-rcmc_time_max,
                        max=rcmc_time_max,
                        cmap='gray',
                        aspect=np.float(rg_size) / np.float(az_size),
                        title='RCMC Data (Time Domain)',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep +
                        'plot_rcmc_time_real_%d.%s' % (ch, plot_format))
            utils.image(np.imag(rcmc_time),
                        min=-rcmc_time_max,
                        max=rcmc_time_max,
                        cmap='gray',
                        aspect=np.float(rg_size) / np.float(az_size),
                        title='RCMC Data (Time Domain)',
                        usetex=plot_tex,
                        save=plot_save,
                        save_path=plot_path + os.sep +
                        'plot_rcmc_time_imag_%d.%s' % (ch, plot_format))

        # Azimuth compression
        print('Applying azimuth compression... [Channel %d/%d]' %
              (ch + 1, num_ch))

        n_samp = 2 * (np.int(doppler_bw / (fa[1] - fa[0])) / 2)
        weighting = (az_weighting - (1. - az_weighting) *
                     np.cos(2 * np.pi * np.linspace(0, 1., int(n_samp))))
        # Compensate amplitude loss

        L_win = np.sum(np.abs(weighting)**2) / weighting.size
        weighting /= np.sqrt(L_win)
        if fa.size > n_samp:
            zeros = np.zeros(az_size)
            zeros[0:int(n_samp)] = weighting
            # zeros[:n_samp/2] = weighting[:n_samp/2]
            # zeros[-n_samp/2:] = weighting[-n_samp/2:]
            weighting = np.roll(zeros, int(-n_samp / 2))
        weighting = np.where(
            np.abs(beam_pattern) > 0, weighting / beam_pattern, 0)
        ph_ac = 4. * np.pi / l0 * sr0 * \
            (np.sqrt(1. - (fa * l0 / 2. / v_ground)**2.) - 1.)
        #        for i in np.arange(rg_size):
        #            data[:,i] *= np.exp(1j*ph_ac)*weighting
        data = data * (np.exp(1j * ph_ac) * weighting).reshape((1, az_size, 1))

        data = np.fft.ifft(data, axis=1)

        print('Finishing... [Channel %d/%d]' % (ch + 1, num_ch))
        # Reduce to initial dimension
        data = data[:, :int(az_size_orig), :int(rg_size_orig)]

        # Removal of non valid samples
        n_val_az_2 = np.floor(doppler_bw / 2. /
                              (2. * v_ground**2. / l0 / sr0) * prf / 2.) * 2.
        # data = raw_data[ch, n_val_az_2:(az_size_orig - n_val_az_2 - 1), :]
        data = data[:, int(n_val_az_2):int(az_size_orig - n_val_az_2 - 1), :]
        if plot_image_valid:
            plt.figure()
            plt.imshow(np.abs(data[0]),
                       origin='lower',
                       vmin=0,
                       vmax=np.max(np.abs(data)),
                       aspect=np.float(rg_size_orig) / np.float(az_size_orig),
                       cmap='gray')
            plt.xlabel("Range")
            plt.ylabel("Azimuth")
            plt.savefig(
                os.path.join(plot_path,
                             ('plot_image_valid_%d.%s' % (ch, plot_format))))

        slc.append(data)

    # Save processed data
    slc = np.array(slc, dtype=np.complex)
    print("Shape of SLC: " + str(slc.shape), flush=True)
    proc_file = tpio.ProcFile(output_file, 'w', slc.shape)
    proc_file.set('slc*', slc)
    proc_file.close()

    print('-----------------------------------------')
    print(
        time.strftime("Processing finished [%Y-%m-%d %H:%M:%S]",
                      time.localtime()))
    print('-----------------------------------------')