import lib_planetcal as lib_p
print ''

pi = np.pi
radeg = (180./pi)
res = .05/radeg
map_width_rad = 3./radeg
noise = 5./(res*radeg*60.)*np.sqrt(300.)*0.5

nu_obs = 140.e9
Dapt_mm = 300.
src_planet = 'Jupiter'
x0,y0,sigma_x,sigma_y,phi,samplerate = lib_p.gen_InputParams(nu_obs,Dapt_mm)
beam_solid_str = lib_p.beam_solidangle_AirySymmetric(nu_obs,Dapt_mm*1e-3)

Amp = lib_p.planet_info(src_planet,nu_obs,beam_solid_str)
par_in = np.array([x0,y0,sigma_x,sigma_y,phi,Amp])


elip = lib_p.ellipticalGaussian()
elip.resol_rad = res
elip.map_width_rad = map_width_rad
elip.par = par_in
# elip.beam_sigma = sigma_x
# X, Y, MAP_S = elip.gen_flatellip_map()
X, Y, MAP_S = elip.gen_flatairy_map(nu_obs,Dapt_mm/2.*1e-3)
MAP_S = MAP_S*Amp

num = len(MAP_S[0])
MAP_N = noise*np.random.normal(0.,1.,[num,num])
MAP_SN = MAP_S+MAP_N
def run_mainloadSN(Telescope,
                   FreqWafer,
                   diameter_mm,
                   src_planet,
                   option_noise=''):

    #Telescope = 'LFT'
    #FreqWafer = 'p60'
    Fnum, BeamWaistFact, radius = lbv24.Telescope_info(Telescope)
    #radius = 400.e-3/2.
    radius = diameter_mm * 1e-3 / 2.
    Dapt_mm = radius * 2. * 1e3
    if Telescope == 'LFT':
        nu_obsGHz = lbv24.nuobsGHz_FreqWafer_LFT(FreqWafer)
        Dpixmm = lbv24.Dpixmm_info_PhaseA1_LFTv24(FreqWafer)
        beam_arcmin = lbv24.beamarcmin_info_PhaseA1_LFT(nu_obsGHz)
    if Telescope == 'reflect_HFT_MF':
        nu_obsGHz = lbv24.nuobsGHz_FreqWafer_HFT(FreqWafer)
        Dpixmm = lbv24.Dpixmm_info_PhaseA1_HFTv24(FreqWafer)
        beam_arcmin = lbv24.beamarcmin_info_PhaseA1_HFT(nu_obsGHz)
    nu_obs = nu_obsGHz * 1.e9
    edgetaper = lbv24.CalcSEdgeTaper_v24(nu_obs, Fnum, Dpixmm, BeamWaistFact)

    #src_planet = 'Jupiter'
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    print ''
    print '--beam properties--'
    #x0_rad,y0_rad,sigma_x_rad,sigma_y_rad,phi,samplerate = lib_p.gen_InputParams_PhaseA1_LFT(nu_obs,Dapt_mm)
    #x0_rad,y0_rad,sigma_x_rad,sigma_y_rad,phi,samplerate = lbv24.gen_cambus(nu_obsGHz)
    x0_rad, y0_rad, sigma_x_rad, sigma_y_rad, phi, samplerate = lbv24.gen_cambus(
        beam_arcmin)
    #print sigma_x_rad, sigma_x_rad*0.1
    res_rad = sigma_x_rad * 0.1  # res is in unit of rad
    map_width_rad = sigma_x_rad * 10.  # unit in rad

    # x0, y0, sigma_x, sigma_y are in unit of rad
    par_in = np.array([x0_rad, y0_rad, sigma_x_rad, sigma_y_rad, phi, 1.])

    elip = lib_p.ellipticalGaussian()
    elip.resol_rad = res_rad
    elip.map_width_rad = map_width_rad
    elip.par = par_in

    if option == 'TruncGaussian':
        X, Y, MAP_S = elip.gen_flatTruncGauss_map(nu_obs, edgetaper, radius)
        tmp_theta, tmp_out = elip.gen_flatTruncGauss_2D(
            nu_obs, edgetaper, radius)
        beam_solid_str = 2. * pi * np.sum(
            np.sin(tmp_theta) * tmp_out) * (tmp_theta[1] - tmp_theta[0])
        print 'beam solid angle', beam_solid_str
    #beam_solid_str = np.sum(MAP_S)
    #beam_solid_str = lib_p.beam_solidangle_AirySymmetric(nu_obs,Dapt_mm*1e-3)
    # x0, y0, sigma_x, sigma_y are in unit of rad

    print 'input:', src_planet, nu_obs, beam_solid_str
    Amp = lib_p.planet_info(src_planet, nu_obs, beam_solid_str)
    MAP_S = MAP_S * Amp

    print 'amp', Amp
    print '--beam properties--'
    print ''
    #sys.exit()
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    #noise = np.sqrt(0.5)*noise_info(sys.argv[2])/(res*radeg*60.)
    #NET_per_det = noise_info_PhaseA1_LFT(sys.argv[2])
    #NET_per_det = noise_info_PhaseA1_HFT(sys.argv[2])
    if Telescope == 'LFT':
        NET_arr, numDet = lbv24.noise_info_PhaseA1_LFT(nu_obsGHz)
    if Telescope == 'reflect_HFT_MF':
        NET_arr, numDet = lbv24.noise_info_PhaseA1_HFT(nu_obsGHz)

    if option_noise == 'det': NET_per_det = NET_arr * np.sqrt(numDet)
    if option_noise == 'band': NET_per_det = NET_arr
    obs_eff = 0.85 * 0.85
    time_interval_sec = 3. * obs_eff * 3600. * 24. * 365.
    time2spent_in_one_pixel = res_rad**2 / (4. * pi) * time_interval_sec
    noise = NET_per_det / np.sqrt(time2spent_in_one_pixel)
    print ''
    print '--noise properties--'
    print 'NET_per_det', NET_per_det
    print 'res_rad, res_rad**2, time2spent_in_one_pixel', res_rad, res_rad * radeg, res_rad**2, time2spent_in_one_pixel
    print 'noise', noise
    print '--noise properties--'
    print ''
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    #MAP_S = MAP_S*Amp

    num = len(MAP_S[0])
    MAP_N = noise * np.random.normal(0., 1., [num, num])
    MAP_SN = MAP_S + MAP_N

    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    num_bin = 100
    Bkk_S, kx, ky = lib_p.fft_2d(res_rad, res_rad, MAP_S)
    Bk_S_kr, Bk_S_mean, Bk_S_std, Bk_S_med = lib_p.cal_Bk(
        num_bin, kx, ky, Bkk_S)

    Bkk_N, kx, ky = lib_p.fft_2d(res_rad, res_rad, MAP_N)
    Bk_N_kr, Bk_N_mean, Bk_N_std, Bk_N_med = lib_p.cal_Bk(
        num_bin, kx, ky, Bkk_N)

    Bkk_SN, kx, ky = lib_p.fft_2d(res_rad, res_rad, MAP_SN)
    Bk_SN_kr, Bk_SN_mean, Bk_SN_std, Bk_SN_med = lib_p.cal_Bk(
        num_bin, kx, ky, Bkk_SN)

    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    py.figure(0, figsize=(18, 10))

    py.subplot(231)
    X_deg = X * radeg
    Y_deg = Y * radeg
    Z = MAP_S
    xmin, xmax, ymin, ymax = np.min(X_deg), np.max(X_deg), np.min(
        Y_deg), np.max(Y_deg)
    extent = xmin, xmax, ymin, ymax
    im1 = py.imshow(Z, extent=extent)
    py.colorbar()
    py.xlabel('$\\theta_x$ [degs]')
    py.ylabel('$\\theta_y$ [degs]')
    py.title('Map space beam, ' + src_planet)

    py.subplot(232)
    Z = MAP_N
    xmin, xmax, ymin, ymax = np.min(X_deg), np.max(X_deg), np.min(
        Y_deg), np.max(Y_deg)
    extent = xmin, xmax, ymin, ymax
    im1 = py.imshow(Z, extent=extent)
    py.colorbar()
    py.xlabel('$\\theta_x$ [degs]')
    py.ylabel('$\\theta_y$ [degs]')
    py.title('Map space noise')

    #
    data = lib_p.meshgrid2array_Z(MAP_SN)
    data_err = noise

    def fit_elipbeam_2D((X_rad, Y_rad), x0_rad, y0_rad, sigma_x_rad,
                        sigma_y_rad, theta_rad, amplitude):
        #par_init,x,y,data,noise_sigma,g):
        elip = lib_p.ellipticalGaussian()
        elip.resol_rad = res_rad
        elip.map_width_rad = map_width_rad
        elip.par = np.array(
            [x0_rad, y0_rad, sigma_x_rad, sigma_y_rad, theta_rad, amplitude])
        Z = amplitude * lib_p.ellipGauss(X_rad, Y_rad, x0_rad, y0_rad,
                                         sigma_x_rad, sigma_y_rad, theta_rad)
        z = lib_p.meshgrid2array_Z(Z)
        return np.array(z)