Esempio n. 1
0
def modified_BB_draine2007beta_z(nu, param):
    """
    Formula of modified black body to link dust mass
    and beta (and kappa), without an extra normalisation factor
    """
    import astropy.constants as cst
    from astropy.cosmology import Planck15
    #    from astropy import analytic_functions
    import astropy.units as u
    from astropy.modeling import models
    mdust, tdust, beta, redshift = param
    bb = models.BlackBody1D(tdust * u.K,
                            bolometric_flux=cst.L_sun.to(u.erg / u.s) /
                            (u.cm * u.cm))
    nu_rest = nu * (1 +
                    redshift) * u.Hz  # shift the frequency range to restframe
    nu_0 = (cst.c / (250e-6 * u.m)).to(u.Hz)
    kappa_n0 = 4.0 * u.cm * u.cm / u.g
    kappa_abs = kappa_n0.to(u.m * u.m / u.kg) * (nu_rest / nu_0)**beta
    DL = Planck15.luminosity_distance(redshift)

    y_z = bb(nu_rest) * (1 + redshift) * kappa_abs.to(u.cm * u.cm / u.kg)
    y_z *= ((10**mdust) * u.M_sun).to(u.kg) * u.kg
    y_z /= (DL.to(u.cm) * DL.to(u.cm) * cst.M_sun)
    return y_z.value
Esempio n. 2
0
def bbfunc(x,*par):
    """
    Helper function for gettempbb. Initialize a blackbody model without values.
    """
    import astropy.units as ur
    from astropy.modeling import models
    from astropy.modeling.blackbody import FLAM

    temp,norm = par
    mod = models.BlackBody1D(temperature=temp*ur.K,bolometric_flux = norm*ur.erg/(ur.cm**2 * ur.s))
    return mod(x*ur.nm).to(FLAM, equivalencies=ur.spectral_density(x*ur.nm)).value
Esempio n. 3
0
T_dust = 130. * u.Kelvin
F_ir = 10**(-10.6) * (u.erg / u.cm / u.cm / u.s)

# read in the spectrum
sp = ascii.read(data_dir + f)
#change the unit on the wavelength axis to work with astropy
sp['wavelength'].unit = u.micron

# plot
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=[12, 6])
ax1.plot(sp['wavelength'], sp['flux_density'], label='Spitzer merged spectrum')
ax1.set_xlabel('wavelength (micron)')
ax1.set_ylabel('flux (Jy)')

# now fit the continuum
bb = models.BlackBody1D(temperature=T_dust, bolometric_flux=F_ir)
ax1.plot(sp['wavelength'],
         bb(sp['wavelength']).to(u.Jy),
         'r-',
         label='best fit BB (T = 130 K)')
ax1.set_title('SMP LMC 81')
ax1.legend(loc=2)

# subtract best-fit BB from spectrum
sp_sub = sp['flux_density'] - bb(sp['wavelength']).to(u.Jy)
ax2.plot(sp['wavelength'], sp_sub, label='spectrum, continuum subtracted')
ax2.set_xlabel('wavelength (micron)')
ax2.set_ylabel('flux (Jy)')
#ax2.set_xlim((5., 15.))
ax2.legend(loc=2)
fig.show()
Esempio n. 4
0
def bb_abmag_fluence(val=False, duet=None, **kwargs):
    """
    Take a blackbody with a certain temperature and convert to photon rate in a band.

    Other Parameters
    ----------------

    val : boolean
        Retrurns AB mags without units (False, default) or with Astropy units

    duet: ``astroduet.conifg.Telescope() object``
        If you've already instanced a duet telecope object, feed it in here.
        Currently allows the use of the default bandpasses.

    umag : float
        Must have astropy AB units
        Apparent U-band AB mag. Only used if other values not provided?

    siwftmag : float
        Must have astropy AB units. Apparent Swift magnitude (default is 22*u.ABmag)

    ref : string
        Band to use for reference magnitude; options are 'u', 'swift' ('swift')

    bbtemp : float
        Blackbody temperature to use (20000*ur.K)

    dist : float
        Distance of the source. swiftmags are assumed to be given at a reference
        distance of 10 pc (I think?)

    bolflux : float
        Bolometric flux; if not 1, refmag and distance are ignored. Should have
        units like (1*ur.erg/ur.cm**2/ur.s)

    diag : boolean
        SHow diagnostic inforamtion

    Returns
    -------
    ABmag1, ABmag2





    """

    import astropy.units as ur
    import astropy.constants as cr
    from astropy.modeling import models
    from astropy.modeling.blackbody import FLAM
    import numpy as np
    from astroduet.config import Telescope

    if duet is None:
        duet = Telescope()

    bbtemp = kwargs.pop('bbtemp', 20000. * ur.K)
    umag = kwargs.pop('umag', 22 * ur.ABmag)
    swiftmag = kwargs.pop('swiftmag', 22 * ur.ABmag)
    dist = kwargs.pop('dist', 10 * ur.pc)
    ref = kwargs.pop('ref', 'swift')
    diag = kwargs.pop('diag', False)
    dist0 = 10 * ur.pc
    bolflux = kwargs.pop('bolflux', 1. * ur.erg / (ur.cm**2 * ur.s))

    bandu = [340, 380] * ur.nm  # For comparison purposes
    bandsw = [
        172.53, 233.57
    ] * ur.nm  # Swift UVW2 effective band (lambda_eff +/- 0.5 width_eff)

    wav = np.arange(1000, 9000) * ur.AA  # Wavelength scale in 1 Angstrom steps
    bb = models.BlackBody1D(
        temperature=bbtemp,
        bolometric_flux=bolflux)  # Load the blackbody model
    flux = bb(wav).to(FLAM, ur.spectral_density(wav))

    # Get Swift reference AB mag
    fluxden_sw = np.mean(flux[(wav >= bandsw[0].to(ur.AA))
                              & (wav <= bandsw[1].to(ur.AA))])
    magsw = fluxden_sw.to(ur.ABmag,
                          equivalencies=ur.spectral_density(np.mean(bandsw)))

    # Conver to flux AB mags across the band.
    flux_ab = flux.to(ur.ABmag, equivalencies=ur.spectral_density(wav))

    # Distance modulus
    distmod = (5 * np.log10(dist / dist0)).value * ur.mag

    # Set up input:
    magoff = swiftmag - magsw

    # Apply the distance modulus and the Swift reference offset
    if (bolflux == 1. * ur.erg / (ur.cm**2 * ur.s)):
        flux_mag = flux_ab + magoff + distmod
    else:
        flux_mag = flux_ab

    # Convert back to flux
    flux_conv = flux_mag.to(FLAM, equivalencies=ur.spectral_density(wav))
    dw = 1 * ur.AA
    ph_energy = (cr.h.cgs * cr.c.cgs / wav.cgs) / ur.ph

    # Convert to photon flux.
    ph_flux = flux_conv * dw / ph_energy

    # Apply filters, QE, etc.
    band1_fluence = duet.apply_filters(wav, ph_flux, diag=diag, **kwargs).sum()
    band2_fluence = duet.apply_filters(wav,
                                       ph_flux,
                                       band=2,
                                       diag=diag,
                                       **kwargs).sum()

    if diag:
        print()
        print('Compute ABmags in TD bands for blackbody')
        print('Blackbody temperature: {}'.format(bbtemp))
        print('Reference UVW2-band magnitude: {}'.format(swiftmag))
        print('Distance: {} (Reference distance is 10 pc)'.format(dist))
        print()
        print('Flux density Swift: {}'.format(fluxden_sw))
        print('Distance modulus: {}'.format(distmod))
        print('Raw ABmag Swift: {}'.format(magsw))
        print('Offset from Swift band: {}'.format(magoff))
        print('Fluence band one: {}'.format(band1_fluence))
        print('Fluence band two: {}'.format(band2_fluence))
        print('')

    if val:
        return band1_fluence.value, band2_fluence.value
    else:
        return band1_fluence, band2_fluence
Esempio n. 5
0
def bb_abmag(diag=False, val=False, **kwargs):
    """
    Take a blackbody with a certain temperature and convert to AB magnitudes in two bands.
    Scaled to u-band or Swift UVW2 magnitude.

    Inputs (defaults):
    umag = apparent u-band AB magnitude (22*ur.ABmag)
    swiftmag = apparent Swift UVW2 magnitude (22*ur.ABmag)
    ref = band to use for reference magnitude; options are 'u', 'swift' ('swift')
    bandone = Bandpass 1st filter (180-220)*ur.nm
    bandtwo = Bandpass 2nd filter (260-300)*ur.nm
    bbtemp = Blackbody temperature (20000*ur.K)
    dist = Distance (10*ur.pc)
    val = Return values without unit if True (False)
    bolflux = Bolometric flux; if not 1, refmag and distance are ignored (1*ur.erg/ur.cm**2/ur.s)

    diag (False)

    Returns ABmag1, ABmag2

    """

    import astropy.units as ur
    import astropy.constants as cr
    from astropy.modeling import models
    from astropy.modeling.blackbody import FLAM
    import numpy as np

    bbtemp = kwargs.pop('bbtemp', 20000. * ur.K)
    bandone = kwargs.pop('bandone', [180, 220] * ur.nm)
    bandtwo = kwargs.pop('bandtwo', [260, 300] * ur.nm)
    umag = kwargs.pop('umag', 22 * ur.ABmag)
    swiftmag = kwargs.pop('swiftmag', 22 * ur.ABmag)
    dist = kwargs.pop('dist', 10 * ur.pc)
    ref = kwargs.pop('ref', 'swift')
    dist0 = 10 * ur.pc
    bolflux = kwargs.pop('bolflux', 1. * ur.erg / (ur.cm**2 * ur.s))

    bandu = [340, 380] * ur.nm  # For comparison purposes
    bandsw = [
        172.53, 233.57
    ] * ur.nm  # Swift UVW2 effective band (lambda_eff +/- 0.5 width_eff)

    wav = np.arange(1000, 9000) * ur.AA  # Wavelength scale in 1 Angstrom steps
    bb = models.BlackBody1D(
        temperature=bbtemp,
        bolometric_flux=bolflux)  # Load the blackbody model
    flux = bb(wav).to(FLAM, ur.spectral_density(wav))

    # Calculate mean flux density in each band:
    fluxden_one = np.mean(flux[(wav >= bandone[0].to(ur.AA))
                               & (wav <= bandone[1].to(ur.AA))])
    fluxden_two = np.mean(flux[(wav >= bandtwo[0].to(ur.AA))
                               & (wav <= bandtwo[1].to(ur.AA))])
    fluxden_u = np.mean(flux[(wav >= bandu[0].to(ur.AA))
                             & (wav <= bandu[1].to(ur.AA))])
    fluxden_sw = np.mean(flux[(wav >= bandsw[0].to(ur.AA))
                              & (wav <= bandsw[1].to(ur.AA))])

    # Convert to AB magnitudes:
    magone = fluxden_one.to(ur.ABmag,
                            equivalencies=ur.spectral_density(
                                np.mean(bandone)))
    magtwo = fluxden_two.to(ur.ABmag,
                            equivalencies=ur.spectral_density(
                                np.mean(bandtwo)))
    magu = fluxden_u.to(ur.ABmag,
                        equivalencies=ur.spectral_density(np.mean(bandu)))
    magsw = fluxden_sw.to(ur.ABmag,
                          equivalencies=ur.spectral_density(np.mean(bandsw)))

    if (ref == 'u'):
        # Offset from comparison u-band magnitude:
        magoff = umag - magu
    elif (ref == 'swift'):
        # Offset from comparison swift UVW2-band magnitude:
        magoff = swiftmag - magsw

    # Distance modulus
    distmod = (5 * np.log10(dist / dist0)).value * ur.mag

    # Apply offsets
    magone_final = magone + magoff + distmod
    magtwo_final = magtwo + magoff + distmod

    if (bolflux == 1. * ur.erg / (ur.cm**2 * ur.s)):
        magone_final = magone + magoff + distmod
        magtwo_final = magtwo + magoff + distmod
    else:
        magone_final = magone
        magtwo_final = magtwo

    if diag:
        print()
        print('Compute ABmags in TD bands for blackbody')
        print('Blackbody temperature: {}'.format(bbtemp))
        print('Reference UVW2-band magnitude: {}'.format(swiftmag))
        print('Band one: {}'.format(bandone))
        print('Band two: {}'.format(bandtwo))
        print('Distance: {}'.format(dist))

        print('Flux density band one: {}'.format(fluxden_one))
        print('Flux density band two: {}'.format(fluxden_two))
        print('Flux density Swift: {}'.format(fluxden_sw))
        print('Distance modulus: {}'.format(distmod))
        print('Raw ABmag band one: {}'.format(magone))
        print('Raw ABmag band two: {}'.format(magtwo))
        print('Raw ABmag Swift: {}'.format(magsw))
        print('Offset from Swift band: {}'.format(magoff))
        print('ABmag band one: {}'.format(magone_final))
        print('ABmag band two: {}'.format(magtwo_final))
        print('')

    if val:
        return magone_final.value, magtwo_final.value
    else:
        return magone_final, magtwo_final
Esempio n. 6
0
def bb_abmag_fluence(val=False, **kwargs):
    """
    Take a blackbody with a certain temperature and convert to photon rate in a band.
    
    Now applies the various filters and returns *photon fluence* in the band
    
    Now also accepts bolometric flux as input.
    
    Inputs (defaults):
    umag = apparent u-band AB magnitude (22*ur.ABmag)
    swiftmag = apparent Swift UVW2 magnitude (22*ur.ABmag)
    ref = band to use for reference magnitude; options are 'u', 'swift' ('swift')
    bandone = Bandpass 1st filter (180-220)*ur.nm
    bandtwo = Bandpass 2nd filter (260-300)*ur.nm
    bbtemp = Blackbody temperature (20000*ur.K)
    dist = Distance (10*ur.pc)
    val = Return values without unit if True (False)
    bolflux = Bolometric flux; if not 1, refmag and distance are ignored (1*ur.erg/ur.cm**2/ur.s)
    
    diag (False)
        
    Returns ABmag1, ABmag2
       
    Also still to do: Add background from galaxies.
       
    """

    import astropy.units as ur
    import astropy.constants as cr
    from astropy.modeling import models
    from astropy.modeling.blackbody import FLAM
    import numpy as np
    from tdsat_telescope import apply_filters

    bbtemp = kwargs.pop('bbtemp', 20000. * ur.K)
    #    bandone = kwargs.pop('bandone', [180,220]*ur.nm)
    #    bandtwo = kwargs.pop('bandtwo', [260,300]*ur.nm)
    umag = kwargs.pop('umag', 22 * ur.ABmag)
    swiftmag = kwargs.pop('swiftmag', 22 * ur.ABmag)
    dist = kwargs.pop('dist', 10 * ur.pc)
    ref = kwargs.pop('ref', 'swift')
    diag = kwargs.pop('diag', False)
    dist0 = 10 * ur.pc
    bolflux = kwargs.pop('bolflux', 1. * ur.erg / (ur.cm**2 * ur.s))

    bandu = [340, 380] * ur.nm  # For comparison purposes
    bandsw = [
        172.53, 233.57
    ] * ur.nm  # Swift UVW2 effective band (lambda_eff +/- 0.5 width_eff)

    wav = np.arange(1000, 9000) * ur.AA  # Wavelength scale in 1 Angstrom steps
    bb = models.BlackBody1D(
        temperature=bbtemp,
        bolometric_flux=bolflux)  # Load the blackbody model
    flux = bb(wav).to(FLAM, ur.spectral_density(wav))

    # Get Swift reference AB mag
    fluxden_sw = np.mean(flux[(wav >= bandsw[0].to(ur.AA))
                              & (wav <= bandsw[1].to(ur.AA))])
    magsw = fluxden_sw.to(ur.ABmag,
                          equivalencies=ur.spectral_density(np.mean(bandsw)))

    # Conver to flux AB mags across the band.
    flux_ab = flux.to(ur.ABmag, equivalencies=ur.spectral_density(wav))

    # Distance modulus
    distmod = (5 * np.log10(dist / dist0)).value * ur.mag

    # Set up input:
    magoff = swiftmag - magsw

    # Apply the distance modulus and the Swift reference offset
    if (bolflux == 1. * ur.erg / (ur.cm**2 * ur.s)):
        flux_mag = flux_ab + magoff + distmod
    else:
        flux_mag = flux_ab

    # Convert back to flux
    flux_conv = flux_mag.to(FLAM, equivalencies=ur.spectral_density(wav))
    dw = 1 * ur.AA
    ph_energy = (cr.h.cgs * cr.c.cgs / wav.cgs)

    # Convert to photon flux.
    ph_flux = flux_conv * dw / ph_energy

    # Apply filters, QE, etc.
    band1_fluence = apply_filters(wav, ph_flux, diag=diag,
                                  **kwargs).sum().sum()
    band2_fluence = apply_filters(wav, ph_flux, band=2, diag=diag,
                                  **kwargs).sum()

    if diag:
        print()
        print('Compute ABmags in TD bands for blackbody')
        print('Blackbody temperature: {}'.format(bbtemp))
        print('Reference UVW2-band magnitude: {}'.format(swiftmag))
        print('Distance: {} (Reference distance is 10 pc)'.format(dist))
        print()
        print('Flux density Swift: {}'.format(fluxden_sw))
        print('Distance modulus: {}'.format(distmod))
        print('Raw ABmag Swift: {}'.format(magsw))
        print('Offset from Swift band: {}'.format(magoff))
        print('Fluence band one: {}'.format(band1_fluence))
        print('Fluence band two: {}'.format(band2_fluence))
        print('')

    if val:
        return band1_fluence.value, band2_fluence.value
    else:
        return band1_fluence, band2_fluence
Esempio n. 7
0
def filter_parameters(duet=None, *args, **kwargs):
    """
    Construct the effective central wavelength and the effective bandpass
    for the filters.

    Parameters
    ----------


    Other parameters
    ----------------
    vega : conditional, default False
        Use the Vega spetrum (9.8e3 K blackbody) to compute values. Otherwise computed
        "flat" values if quoting AB mags.

    diag : conditional, default False
        Show the diagnostic info on the parameters.

    Examples
    --------
    >>> band1, band2 = filter_parameters()
    >>> allclose(band1['eff_wave'].value, 198.63858525)
    True

    """
    from astroduet.config import Telescope

    if duet is None:
        duet = Telescope()

    from astropy.modeling import models
    from astropy.modeling.blackbody import FNU, FLAM
    from astropy import units as u
    import numpy as np

    vega = kwargs.pop('vega', False)
    diag = kwargs.pop('diag', False)

    wave = np.arange(1000, 10000) * u.AA
    if vega:
        temp = 9.8e3 * u.K
        bb = models.BlackBody1D(temperature=temp)
        flux = bb(wave).to(FLAM, u.spectral_density(wave))
    else:
        flat_model = np.zeros_like(wave.value)
        flat_model += 1
        flat_model *= FNU
        flux = flat_model.to(FLAM, u.spectral_density(wave))

    band1 = duet.apply_filters(wave, flux, band=1, **kwargs)
    band2 = duet.apply_filters(wave, flux, band=2, **kwargs)

    λ_eff1 = ((band1 * wave).sum() / (band1.sum())).to(u.nm)
    λ_eff2 = ((band2 * wave).sum() / (band2.sum())).to(u.nm)

    dλ = wave[1] - wave[0]
    t1 = band1 / flux
    t2 = band2 / flux

    w1 = (dλ * t1.sum() / t1.max()).to(u.nm)
    w2 = (dλ * t2.sum() / t2.max()).to(u.nm)

    band1 = {'eff_wave': λ_eff1, 'eff_width': w1}
    band2 = {'eff_wave': λ_eff2, 'eff_width': w2}

    if diag:
        print('Band1: {0:0.2f} λ_eff, {1:0.2f} W_eff'.format(λ_eff1, w1))
        print('Band2: {0:0.2f} λ_eff, {1:0.2f} W_eff'.format(λ_eff2, w2))

    return band1, band2