Example #1
0
def get_it_spectrum(opt):

    wl_lo = opt.channel.pipeline_params.wavrange_lo.val
    wl_hi = opt.channel.pipeline_params.wavrange_hi.val
    wl = opt.star.sed.wl
    planet_wl = opt.planet.sed.wl

    # CHANGE INTRODUCED
    # If the star is downsampled here it can cause inconsistencies in the representation of the source spectrum
    # Hence I err on the side of upsampling the planet spectrum to the star resolution, rather than downsampling
    # the star spectrum to the planet spectrum resolution.
    # The impact of this change on the final planet spectrum is minimal

    # R = wl/np.gradient((wl))
    # R_planet = planet_wl/np.gradient((planet_wl))
    # # select onyl wavelengths in range for channel
    # idx = np.argwhere((wl.value>= wl_lo) & (wl.value<= wl_hi)).T[0]
    # idx2 = np.argwhere((planet_wl.value>= wl_lo) & (planet_wl.value<= wl_hi)).T[0]
    # # rebin to lower resolution spectrum
    # if  R_planet[idx2].min() < R[idx].min():
    #     opt.star.sed.rebin(planet_wl)
    # else:
    #     opt.planet.sed.rebin(wl)

    opt.planet.sed.rebin(wl)

    # now make in-transit stellar spectrum
    star_sed_it = opt.star.sed.sed * (1 - opt.planet.sed.sed)
    opt.star.sed_it = Sed(opt.star.sed.wl, star_sed_it)

    return opt

    return opt
Example #2
0
def getR(opt):  #this needs updating
    disp = opt.channel.camera.dispersion.path.replace('__path__', opt.__path__)
    R_file = disp.replace('dispersion', 'R')
    dtmp = np.loadtxt(R_file, delimiter=',')
    wav = dtmp[..., 0] * u.um
    R = dtmp[..., 1] * u.dimensionless_unscaled
    R = np.interp(opt.x_wav_osr, wav, R, left=None, right=None)
    R = Sed(opt.x_wav_osr, R)
    return R
Example #3
0
def zodical_light(opt):

    deg = opt.model_exosystem.ecliptic_lat.val.value
    wl = opt.x_wav_osr
    jexosim_msg('Zodi model initiated...\n', opt.diagnostics)
    jexosim_msg('Ecliptic latitude in deg: %s   \n' % (deg), opt.diagnostics)
    deg = abs(deg)
    if deg >= 57.355:
        level = 1.0
    else:
        level = -0.22968868 * (np.log10(deg + 1))**7 + 1.12162927 * (np.log10(
            deg + 1))**6 - 1.72338015 * (np.log10(deg + 1))**5 + 1.13119022 * (
                np.log10(deg + 1)
            )**4 - 0.95684987 * (np.log10(deg + 1))**3 + 0.2199208 * (np.log10(
                deg + 1))**2 - 0.05989941 * (np.log10(deg + 1)) + 2.57035947
    jexosim_msg('Zodi model coefficient... %s\n' % (level), opt.diagnostics)
    spectrum = level * (3.5e-14 * planck(wl, 5500 * u.K) +
                        planck(wl, 270 * u.K) * 3.58e-8)
    sed = Sed(wl, spectrum)
    transmission = Sed(wl, np.ones(wl.size) * u.dimensionless_unscaled)
    zodi = [sed, transmission]
    return zodi
Example #4
0
def emission_estimation(N, temp, emissivity, transmission):

    t_i = transmission.sed**(1. / N
                             )  # estimate transmission of each optical surface
    for i in range(0, N):  #loop through each surface i=0 to i = N-1
        if i == 0:
            emission_sed = emissivity * planck(transmission.wl,
                                               temp) * t_i**(N - 1 - i)
        else:
            emission_sed = emission_sed + emissivity * planck(
                transmission.wl, temp) * t_i**(N - 1 - i)
        idx = np.argwhere(transmission.sed == 0)
        emission_sed[idx] = 0.0 * emission_sed.unit
    emission = Sed(transmission.wl, emission_sed)
    return emission
Example #5
0
def sunshield_emission(opt):

    wl = opt.x_wav_osr
    # polynomial fit to publically available data
    z = [
        -9.95238428e-15, 1.25072156e-12, -6.35949515e-11, 1.67141033e-09,
        -2.42822718e-08, 1.98344621e-07, -8.56711400e-07, 1.52392307e-06
    ]
    r = 7
    y = 0
    for i in range(0, r + 1):
        y = y + z[i] * wl.value**(r - i)
    idx = np.argwhere(wl.value < 7)
    y[idx] = 0
    y *= u.W / u.m**2 / u.um / u.sr
    sed = Sed(wl, y)
    return sed
Example #6
0
def get_planet_spectrum(opt):
    fp_signal_it = opt.fp_signal_it[1::3, 1::3]
    fp_signal = opt.fp_signal[1::3, 1::3]

    rat = (1 - (fp_signal_it / fp_signal))
    rat[np.isnan(rat)] = 0
    cr_average = np.zeros(fp_signal.shape[1])
    for i in range(fp_signal.shape[1]):
        slice = rat[:, i]
        idx = np.argwhere(slice > 0)
        slice = slice[idx]
        # wt = 1/slice
        # this is important to remove outliers
        idx = np.argwhere(
            abs(slice - np.median(slice)) > 0.01 * np.median(slice)).T[0]
        # sd = np.std(slice)
        # idx = np.argwhere(abs(slice-np.mean(slice) > sd))
        slice = np.delete(slice, idx)
        # wt = 1/slice
        # if i == 200:
        #     print (idx, 0.1*np.median(slice))
        #     plt.plot(slice, 'ro-')
        # # if i == 1760:
        #     print (idx, 0.1*np.median(slice))
        #     plt.plot(slice, 'bo-')
        cr_average[i] = np.mean(slice)
        # cr_average[i] = np.sum(slice*wt)/ np.sum(wt)

    opt.planet.sed = Sed(opt.x_wav_osr[1::3],
                         cr_average * u.dimensionless_unscaled)

    # remove values outside of the wavelength range of the channel
    idx = np.argwhere(
        opt.planet.sed.wl.value < opt.channel.pipeline_params.wavrange_lo.val -
        0.5).T[0]
    opt.planet.sed.sed[idx] = 0 * u.dimensionless_unscaled
    idx = np.argwhere(
        opt.planet.sed.wl.value > opt.channel.pipeline_params.wavrange_hi.val +
        0.5).T[0]
    opt.planet.sed.sed[idx] = 0 * u.dimensionless_unscaled
    idx = np.argwhere(opt.planet.sed.wl.value == 0).T[0]
    opt.planet.sed.sed[idx] = 0 * u.dimensionless_unscaled

    return opt.planet.sed
Example #7
0
def optical_emission(opt):
    #telescope
    N = np.int(opt.common_optics.emissions.optical_surface.no_surfaces)
    temp = opt.common_optics.emissions.optical_surface.val
    emissivity = np.float(
        opt.common_optics.emissions.optical_surface.emissivity)
    opt.telescope_emission = emission_estimation(N, temp, emissivity,
                                                 opt.telescope_transmission)
    jexosim_lib.sed_propagation(opt.telescope_emission,
                                opt.channel_transmission)
    #channel
    N = np.int(opt.channel.emissions.optical_surface.no_surfaces)
    temp = opt.channel.emissions.optical_surface.val
    emissivity = np.float(opt.channel.emissions.optical_surface.emissivity)
    opt.channel_emission = emission_estimation(N, temp, emissivity,
                                               opt.channel_transmission)
    # combine
    emission = Sed(opt.channel_transmission.wl,
                   opt.telescope_emission.sed + opt.channel_emission.sed)
    return emission
Example #8
0
def run(opt):

    jexosim_msg('channel check0 : %s' % (opt.star.sed.sed.max()),
                opt.diagnostics)
    tr_ = np.array([1.] * len(opt.x_wav_osr)) * u.dimensionless_unscaled
    opt.channel.transmissions.optical_surface = opt.channel.transmissions.optical_surface if isinstance(opt.channel.transmissions.optical_surface, list) else \
                                                                    [opt.channel.transmissions.optical_surface]
    for op in opt.channel.transmissions.optical_surface:
        dtmp = np.loadtxt(op.transmission.replace('__path__', opt.__path__),
                          delimiter=',')
        tr = Sed(dtmp[:, 0] * u.um, dtmp[:, 1] * u.dimensionless_unscaled)
        tr.rebin(opt.x_wav_osr)
        tr_ *= tr.sed
    opt.channel_transmission = Sed(opt.x_wav_osr, tr_)
    opt.total_transmission = Sed(
        opt.channel_transmission.wl,
        opt.telescope_transmission.sed * opt.channel_transmission.sed)
    jexosim_lib.sed_propagation(opt.star.sed, opt.channel_transmission)
    jexosim_lib.sed_propagation(opt.star.sed_it, opt.channel_transmission)
    # apply QE and convert to electrons
    dtmp = np.loadtxt(opt.channel.detector_array.qe().replace(
        '__path__', opt.__path__),
                      delimiter=',')
    qe = Sed(dtmp[:, 0] * u.um, dtmp[:, 1] * u.dimensionless_unscaled)
    qe.rebin(opt.x_wav_osr)
    PCE = Sed(opt.total_transmission.wl, opt.total_transmission.sed * qe.sed)
    TotTrans = Sed(opt.total_transmission.wl, opt.total_transmission.sed)
    opt.PCE = PCE.sed
    opt.TotTrans = TotTrans.sed
    jexosim_plot('PCE', opt.diagnostics, xdata=PCE.wl, ydata=PCE.sed)
    jexosim_plot('Total transmission not including QE',
                 opt.diagnostics,
                 xdata=TotTrans.wl,
                 ydata=TotTrans.sed)
    opt.qe_spec = qe
    opt.Re = qe.sed * (qe.wl).to(u.m) / (const.c.value * const.h.value * u.m)
    opt.star.sed.sed *= opt.Re * u.electron / u.W / u.s
    opt.star.sed_it.sed *= opt.Re * u.electron / u.W / u.s
    jexosim_plot('channel star sed check',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.star.sed.sed,
                 marker='-')
    jexosim_msg('check 1.3 - Star sed max:  %s' % (opt.star.sed.sed.max()),
                opt.diagnostics)
    jexosim_plot('Wavelength solution check -oversampled pixels',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr,
                 ydata=opt.x_wav_osr,
                 marker='o-')
    jexosim_plot('Wavelength solution check -normal pixels',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr[1::3],
                 ydata=opt.x_wav_osr[1::3],
                 marker='o-')
    opt.d_x_wav_osr = np.zeros_like(opt.x_wav_osr)
    idx = np.where(opt.x_wav_osr > 0.0)
    opt.d_x_wav_osr[idx] = np.gradient(opt.x_wav_osr[idx])
    if np.any(opt.d_x_wav_osr < 0): opt.d_x_wav_osr *= -1.0
    jexosim_plot('D x wav osr check',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr,
                 ydata=opt.d_x_wav_osr,
                 marker='o')
    jexosim_plot('D x wav osr check 2',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.d_x_wav_osr,
                 marker='o')
    jexosim_msg("check 1.4:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)

    opt.planet_sed_original = copy.deepcopy(opt.planet.sed.sed)
    # opt.planet.sed.sed  *= opt.star.sed.sed
    # opt.planet.sed.sed  *= opt.d_x_wav_osr

    jexosim_msg("check 1.5:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)
    opt.star.sed.sed *= opt.d_x_wav_osr
    opt.star.sed_it.sed *= opt.d_x_wav_osr
    jexosim_msg("check 2:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)
    jexosim_plot('star sed check 2.0',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.star.sed.sed,
                 marker='-')

    return opt
Example #9
0
def run(opt):

    opt.osf = np.int(opt.channel.simulation_factors.osf())
    opt.offs = np.int(opt.channel.simulation_factors.pix_offs())
    fpn = opt.channel.detector_array.array_geometry.val.split(',')
    opt.fpn = [int(fpn[0]), int(fpn[1])]
    opt.fp = np.zeros(
        (int(opt.fpn[0] * opt.channel.simulation_factors.osf.val),
         int(opt.fpn[1] * opt.channel.simulation_factors.osf.val)))
    opt.fp_signal = np.zeros(
        (int(opt.fpn[0] * opt.channel.simulation_factors.osf.val),
         int(opt.fpn[1] * opt.channel.simulation_factors.osf.val)))
    opt.fp_it = np.zeros(
        (int(opt.fpn[0] * opt.channel.simulation_factors.osf.val),
         int(opt.fpn[1] * opt.channel.simulation_factors.osf.val)))
    opt.fp_signal_it = np.zeros(
        (int(opt.fpn[0] * opt.channel.simulation_factors.osf.val),
         int(opt.fpn[1] * opt.channel.simulation_factors.osf.val)))

    opt.fp_delta = opt.channel.detector_pixel.pixel_size.val / opt.channel.simulation_factors.osf.val
    #      opt.x_wav_osr, opt.x_pix_osr, opt.y_pos_osr = instrument_lib.usePoly(opt)

    if 'NIRISS' in opt.channel.name:  # this is because d_x_wav_osr is not smooth with interp method
        opt.x_wav_osr, opt.x_pix_osr, opt.y_pos_osr = instrument_lib.usePoly(
            opt)
    else:
        opt.x_wav_osr, opt.x_pix_osr, opt.y_pos_osr = instrument_lib.useInterp(
            opt)

    opt.R = instrument_lib.getR(opt)
    jexosim_msg('tel check 1: %s' % (opt.star.sed.sed.max()), opt.diagnostics)
    opt.star_sed = copy.deepcopy(opt.star.sed)  #copy of star flux at telescope
    opt.star_sed2 = copy.deepcopy(
        opt.star.sed)  #copy of star flux at telescope
    opt.Aeff = 0.25 * np.pi * opt.common_optics.telescope_effective_diameter(
    )**2
    opt.star.sed.sed *= opt.Aeff
    opt.star.sed_it.sed *= opt.Aeff

    jexosim_msg('tel check 2: %s' % (opt.star.sed.sed.max()), opt.diagnostics)
    tr_ = np.array([1.] * len(opt.x_wav_osr)) * u.dimensionless_unscaled
    opt.common_optics.transmissions.optical_surface = opt.common_optics.transmissions.optical_surface \
        if isinstance(opt.common_optics.transmissions.optical_surface, list) \
        else [opt.common_optics.transmissions.optical_surface]
    for op in opt.common_optics.transmissions.optical_surface:
        dtmp = np.loadtxt(op.transmission.replace('__path__', opt.__path__),
                          delimiter=',')
        tr = Sed(dtmp[:, 0] * u.um, dtmp[:, 1] * u.dimensionless_unscaled)
        tr.rebin(opt.x_wav_osr)
        tr_ *= tr.sed
    opt.telescope_transmission = Sed(opt.x_wav_osr, tr_)

    if opt.diagnostics == 1:
        import matplotlib.pyplot as plt
        plt.figure('checking binning down of stellar spectrum')
        plt.plot(opt.star.sed.wl, opt.star.sed.sed, alpha=0.5)

    opt.star.sed.rebin(opt.x_wav_osr)
    opt.star.sed_it.rebin(opt.x_wav_osr)

    if opt.diagnostics == 1:
        plt.figure('checking binning down of stellar spectrum')
        plt.plot(opt.star.sed.wl, opt.star.sed.sed, 'r-')

    jexosim_msg('tel check 2a: %s' % (opt.star.sed.sed.max()), opt.diagnostics)

    opt.planet.sed.rebin(opt.x_wav_osr)
    jexosim_lib.sed_propagation(opt.star.sed, opt.telescope_transmission)
    jexosim_lib.sed_propagation(opt.star.sed_it, opt.telescope_transmission)
    jexosim_msg('tel check 3: %s' % (opt.star.sed.sed.max()), opt.diagnostics)

    dtmp = np.loadtxt(opt.channel.detector_array.quantum_yield().replace(
        '__path__', opt.__path__),
                      delimiter=',')
    quantum_yield = Sed(dtmp[:, 0] * u.um,
                        dtmp[:, 1] * u.dimensionless_unscaled)
    quantum_yield.rebin(opt.x_wav_osr)
    quantum_yield.sed = np.where(
        quantum_yield.sed == 0, 1, quantum_yield.sed
    )  # avoids quantum yield of 0 due to interpolation issue
    opt.quantum_yield = quantum_yield

    return opt
Example #10
0
def sanity_check(opt):
    wl = opt.x_wav_osr[1::3]
    del_wl = abs(np.gradient(wl))
    #    del_wl = opt.d_x_wav_osr[1::3]*3
    star_spec = opt.star_sed
    star_spec.rebin(wl)
    T = opt.planet.planet.star.T
    trans_sed = opt.total_transmission.sed * u.dimensionless_unscaled
    trans = Sed(opt.total_transmission.wl, trans_sed)
    trans.rebin(wl)
    QE = opt.qe_spec
    QE.rebin(wl)
    quantum_yield = opt.quantum_yield
    quantum_yield.rebin(wl)
    Rs = (opt.planet.planet.star.R).to(u.m)
    D = (opt.planet.planet.star.d).to(u.m)

    n = quantum_yield.sed * trans.sed * del_wl * np.pi * planck(wl, T) * (
        Rs / D)**2 * opt.Aeff * QE.sed / (const.h.value * const.c.value /
                                          (wl * 1e-6))
    n2 = quantum_yield.sed * trans.sed * del_wl * star_spec.sed * opt.Aeff * QE.sed / (
        const.h.value * const.c.value / (wl * 1e-6))
    jex_sig = quantum_yield.sed * opt.fp_signal[1::3, 1::3].sum(axis=0)

    n = np.where(n < 0, 0, n)
    n2 = np.where(n2 < 0, 0, n2)

    R = opt.pipeline.pipeline_R.val
    del_wav = wl / R
    opt.exp_sig = opt.t_int * del_wav * jex_sig / del_wl
    if opt.diagnostics == 1:
        plt.figure('sanity check 1 - check focal plane signal')
        if 'NIRISS' in opt.channel.name:
            plt.plot(wl[:-10], n[:-10], 'b^', label='BB check')
            plt.plot(
                wl[:-10], n2[:-10], 'r+', label='Phoenix check'
            )  # not convolved with PSF unlike JexoSim, so peak may be higher
        else:
            plt.plot(wl, n, 'b^', label='BB check')
            plt.plot(
                wl, n2, 'r+', label='Phoenix check'
            )  # not convolved with PSF unlike JexoSim, so peak may be higher
        plt.plot(wl, jex_sig, 'gx', label='JexoSim')
        plt.ylabel('e/s/pixel col')
        plt.xlabel('pixel col wavelength (microns)')
        plt.legend(loc='best')

        ################
        plt.figure(
            'sanity check 2 - expected final star signal in R bin of %s' %
            ((R)))
        plt.plot(wl, opt.exp_sig)
        plt.ylabel('e/bin')
        plt.xlabel('Wavelength (microns)')
        ################
        plt.figure(
            'sanity check 3 - expected photon noise (sd) in R bin of %s' %
            ((R)))
        plt.plot(wl, opt.exp_sig**0.5)
        plt.ylabel('e/bin')
        plt.xlabel('Wavelength (microns)')