Beispiel #1
0
def lsst_flare_fluxes_from_u(ju_flux):
    """
    Convert from Johnson U band flux to flux in the LSST bands
    by assuming the flare is a 9000K black body (see Section 4
    of Hawley et al 2003, ApJ 597, 535)

    Parameters
    ----------
    flux in Johnson U band (either a float or a numpy array)

    Returns
    -------
    floats/numpy arrays of fluxes in all 6 LSST bands
    """

    if not hasattr(lsst_flare_fluxes_from_u, 'johnson_u_raw_flux'):
        t_start = time.time()
        throughputs_dir = getPackageDir('throughputs')
        johnson_dir = os.path.join(throughputs_dir, 'johnson')
        johnson_u_hw = Bandpass()
        johnson_u_hw.readThroughput(os.path.join(johnson_dir, 'johnson_U.dat'))
        atm = Bandpass()
        atm.readThroughput(
            os.path.join(throughputs_dir, 'baseline', 'atmos_std.dat'))

        wv, sb = johnson_u_hw.multiplyThroughputs(atm.wavelen, atm.sb)
        johnson_u = Bandpass(wavelen=wv, sb=sb)

        boltzmann_k = 1.3807e-16  # erg/K
        planck_h = 6.6261e-27  # erg*s
        _c = 2.9979e10  # cm/s

        hc_over_k = 1.4387e7  # nm*K

        temp = 9000.0  # black body temperature in Kelvin

        bb_wavelen = np.arange(200.0, 1500.0, 0.1)  # in nanometers

        exp_arg = hc_over_k / (temp * bb_wavelen)
        exp_term = 1.0 / (np.exp(exp_arg) - 1.0)
        ln_exp_term = np.log(exp_term)

        # the -7.0 np.log(10) will convert wavelen into centimeters
        log_bb_flambda = -5.0 * (np.log(bb_wavelen) -
                                 7.0 * np.log(10.0)) + ln_exp_term

        log_bb_flambda += np.log(2.0) + np.log(planck_h) + 2.0 * np.log(_c)

        # assume these stars all have radii half that of the Sun;
        # see Boyajian et al. 2012 (ApJ 757, 112)
        r_sun = 6.957e10  # cm
        log_bb_flambda += np.log(
            4.0 * np.pi * np.pi) + 2.0 * np.log(0.5 * r_sun)

        # thee -7.0*np.log(10.0) makes sure we get ergs/s/cm^2/nm
        bb_flambda = np.exp(log_bb_flambda - 7.0 * np.log(10))

        bb_sed = Sed(wavelen=bb_wavelen, flambda=bb_flambda)

        # because we have a flux in ergs/s but need a flux in
        # the normalized units of Sed.calcFlux (see eqn 2.1
        # of the LSST Science Book), we will calculate the
        # ergs/s/cm^2 of a raw, unnormalized blackbody spectrum
        # in the Johnson U band, find the factor that converts
        # that raw flux into our specified flux, and then
        # multiply that factor *by the fluxes calculated for the
        # blackbody in the LSST filters using Sed.calcFlux()*.
        # This should give us the correct normalized flux for
        # the flares in the LSST filters.

        lsst_flare_fluxes_from_u.johnson_u_raw_flux = bb_sed.calcErgs(
            johnson_u)

        lsst_bands = BandpassDict.loadTotalBandpassesFromFiles()
        norm_raw = None
        lsst_flare_fluxes_from_u.lsst_raw_flux_dict = {}
        for band_name in ('u', 'g', 'r', 'i', 'z', 'y'):
            bp = lsst_bands[band_name]

            flux = bb_sed.calcFlux(bp)

            lsst_flare_fluxes_from_u.lsst_raw_flux_dict[band_name] = flux
            if norm_raw is None:
                norm_raw = flux
            print('raw flux in %s = %e; %e; %e' %
                  (band_name, flux, flux / norm_raw, bb_sed.calcErgs(bp)))
        print('sed johnson flux %e' %
              lsst_flare_fluxes_from_u.johnson_u_raw_flux)
        print('that init took %e' % (time.time() - t_start))

    factor = ju_flux / lsst_flare_fluxes_from_u.johnson_u_raw_flux

    u_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['u']
    g_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['g']
    r_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['r']
    i_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['i']
    z_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['z']
    y_flux_out = factor * lsst_flare_fluxes_from_u.lsst_raw_flux_dict['y']

    return (u_flux_out, g_flux_out, r_flux_out, i_flux_out, z_flux_out,
            y_flux_out)
Beispiel #2
0
    def test_calcErgs(self):
        """
        Test that calcErgs actually calculates the flux of a source in
        ergs/s/cm^2 by running it on black bodies with flat bandpasses
        and comparing to the Stefan-Boltzmann law.
        """

        boltzmann_k = 1.3807e-16  # in ergs/Kelvin
        planck_h = 6.6261e-27  # in cm^2*g/s
        speed_of_light = 2.9979e10  # in cm/s
        stefan_boltzmann_sigma = 5.6705e-5  # in ergs/cm^2/s/Kelvin

        wavelen_arr = np.arange(10.0, 200000.0, 10.0)  # in nm
        bp = Bandpass(wavelen=wavelen_arr, sb=np.ones(len(wavelen_arr)))

        log10_bb_factor = np.log10(2.0) + np.log10(planck_h)
        log10_bb_factor += 2.0*np.log10(speed_of_light)
        log10_bb_factor -= 5.0*(np.log10(wavelen_arr) - 7.0)  # convert wavelen to cm

        for temp in np.arange(5000.0, 7000.0, 250.0):
            log10_exp_arg = np.log10(planck_h) + np.log10(speed_of_light)
            log10_exp_arg -= (np.log10(wavelen_arr) - 7.0)
            log10_exp_arg -= (np.log10(boltzmann_k) + np.log10(temp))

            exp_arg = np.power(10.0, log10_exp_arg)
            log10_bose_factor = -1.0*np.log10(np.exp(exp_arg)-1.0)

            # the -7.0 below is because, otherwise, flambda will be in
            # ergs/s/cm^2/cm and we want ergs/s/cm^2/nm
            #
            # the np.pi comes from the integral in the 'Stefan-Boltzmann'
            # section of
            # https://en.wikipedia.org/wiki/Planck%27s_law#Stefan.E2.80.93Boltzmann_law
            #
            bb_flambda = np.pi*np.power(10.0, log10_bb_factor+log10_bose_factor-7.0)

            sed = Sed(wavelen=wavelen_arr, flambda=bb_flambda)
            ergs = sed.calcErgs(bp)

            log10_ergs = np.log10(stefan_boltzmann_sigma) + 4.0*np.log10(temp)
            ergs_truth = np.power(10.0, log10_ergs)

            msg = '\ntemp:%e\nergs: %e\nergs_truth: %e' % (temp, ergs, ergs_truth)
            self.assertAlmostEqual(ergs/ergs_truth, 1.0, 3, msg=msg)

        # Now test it on a bandpass with throughput=0.25 and an wavelength
        # array that is not the same as the SED

        wavelen_arr = np.arange(10.0, 100000.0, 146.0)  # in nm
        bp = Bandpass(wavelen=wavelen_arr, sb=0.25*np.ones(len(wavelen_arr)))

        wavelen_arr = np.arange(5.0, 200000.0, 17.0)

        log10_bb_factor = np.log10(2.0) + np.log10(planck_h)
        log10_bb_factor += 2.0*np.log10(speed_of_light)
        log10_bb_factor -= 5.0*(np.log10(wavelen_arr) - 7.0)  # convert wavelen to cm

        for temp in np.arange(5000.0, 7000.0, 250.0):
            log10_exp_arg = np.log10(planck_h) + np.log10(speed_of_light)
            log10_exp_arg -= (np.log10(wavelen_arr) - 7.0)
            log10_exp_arg -= (np.log10(boltzmann_k) + np.log10(temp))

            exp_arg = np.power(10.0, log10_exp_arg)
            log10_bose_factor = -1.0*np.log10(np.exp(exp_arg)-1.0)

            # the -7.0 below is because, otherwise, flambda will be in
            # ergs/s/cm^2/cm and we want ergs/s/cm^2/nm
            #
            # the np.pi comes from the integral in the 'Stefan-Boltzmann'
            # section of
            # https://en.wikipedia.org/wiki/Planck%27s_law#Stefan.E2.80.93Boltzmann_law
            #
            bb_flambda = np.pi*np.power(10.0, log10_bb_factor+log10_bose_factor-7.0)

            sed = Sed(wavelen=wavelen_arr, flambda=bb_flambda)
            ergs = sed.calcErgs(bp)

            log10_ergs = np.log10(stefan_boltzmann_sigma) + 4.0*np.log10(temp)
            ergs_truth = np.power(10.0, log10_ergs)

            msg = '\ntemp: %e\nergs: %e\nergs_truth: %e' % (temp,ergs, ergs_truth)
            self.assertAlmostEqual(ergs/ergs_truth, 0.25, 3, msg=msg)
Beispiel #3
0
    def test_calcErgs(self):
        """
        Test that calcErgs actually calculates the flux of a source in
        ergs/s/cm^2 by running it on black bodies with flat bandpasses
        and comparing to the Stefan-Boltzmann law.
        """

        boltzmann_k = 1.3807e-16  # in ergs/Kelvin
        planck_h = 6.6261e-27  # in cm^2*g/s
        speed_of_light = 2.9979e10  # in cm/s
        stefan_boltzmann_sigma = 5.6705e-5  # in ergs/cm^2/s/Kelvin

        wavelen_arr = np.arange(10.0, 200000.0, 10.0)  # in nm
        bp = Bandpass(wavelen=wavelen_arr, sb=np.ones(len(wavelen_arr)))

        log10_bb_factor = np.log10(2.0) + np.log10(planck_h)
        log10_bb_factor += 2.0 * np.log10(speed_of_light)
        log10_bb_factor -= 5.0 * (np.log10(wavelen_arr) - 7.0
                                  )  # convert wavelen to cm

        for temp in np.arange(5000.0, 7000.0, 250.0):
            log10_exp_arg = np.log10(planck_h) + np.log10(speed_of_light)
            log10_exp_arg -= (np.log10(wavelen_arr) - 7.0)
            log10_exp_arg -= (np.log10(boltzmann_k) + np.log10(temp))

            exp_arg = np.power(10.0, log10_exp_arg)
            log10_bose_factor = -1.0 * np.log10(np.exp(exp_arg) - 1.0)

            # the -7.0 below is because, otherwise, flambda will be in
            # ergs/s/cm^2/cm and we want ergs/s/cm^2/nm
            #
            # the np.pi comes from the integral in the 'Stefan-Boltzmann'
            # section of
            # https://en.wikipedia.org/wiki/Planck%27s_law#Stefan.E2.80.93Boltzmann_law
            #
            bb_flambda = np.pi * np.power(
                10.0, log10_bb_factor + log10_bose_factor - 7.0)

            sed = Sed(wavelen=wavelen_arr, flambda=bb_flambda)
            ergs = sed.calcErgs(bp)

            log10_ergs = np.log10(
                stefan_boltzmann_sigma) + 4.0 * np.log10(temp)
            ergs_truth = np.power(10.0, log10_ergs)

            msg = '\ntemp:%e\nergs: %e\nergs_truth: %e' % (temp, ergs,
                                                           ergs_truth)
            self.assertAlmostEqual(ergs / ergs_truth, 1.0, 3, msg=msg)

        # Now test it on a bandpass with throughput=0.25 and an wavelength
        # array that is not the same as the SED

        wavelen_arr = np.arange(10.0, 100000.0, 146.0)  # in nm
        bp = Bandpass(wavelen=wavelen_arr, sb=0.25 * np.ones(len(wavelen_arr)))

        wavelen_arr = np.arange(5.0, 200000.0, 17.0)

        log10_bb_factor = np.log10(2.0) + np.log10(planck_h)
        log10_bb_factor += 2.0 * np.log10(speed_of_light)
        log10_bb_factor -= 5.0 * (np.log10(wavelen_arr) - 7.0
                                  )  # convert wavelen to cm

        for temp in np.arange(5000.0, 7000.0, 250.0):
            log10_exp_arg = np.log10(planck_h) + np.log10(speed_of_light)
            log10_exp_arg -= (np.log10(wavelen_arr) - 7.0)
            log10_exp_arg -= (np.log10(boltzmann_k) + np.log10(temp))

            exp_arg = np.power(10.0, log10_exp_arg)
            log10_bose_factor = -1.0 * np.log10(np.exp(exp_arg) - 1.0)

            # the -7.0 below is because, otherwise, flambda will be in
            # ergs/s/cm^2/cm and we want ergs/s/cm^2/nm
            #
            # the np.pi comes from the integral in the 'Stefan-Boltzmann'
            # section of
            # https://en.wikipedia.org/wiki/Planck%27s_law#Stefan.E2.80.93Boltzmann_law
            #
            bb_flambda = np.pi * np.power(
                10.0, log10_bb_factor + log10_bose_factor - 7.0)

            sed = Sed(wavelen=wavelen_arr, flambda=bb_flambda)
            ergs = sed.calcErgs(bp)

            log10_ergs = np.log10(
                stefan_boltzmann_sigma) + 4.0 * np.log10(temp)
            ergs_truth = np.power(10.0, log10_ergs)

            msg = '\ntemp: %e\nergs: %e\nergs_truth: %e' % (temp, ergs,
                                                            ergs_truth)
            self.assertAlmostEqual(ergs / ergs_truth, 0.25, 3, msg=msg)