Пример #1
0
def calc_dust_extinct(neb_lines, method):
    """
    Estimate the Visual extinction A_V based on input nebular emission lines

    Uses the Fitzpatrick & Massa (2007) extinction law

    Args:
        neb_lines (dict):  Line fluxes
        method (str): Name of the method
          Ha/Hb -- Use the Halpha/Hbeta ratio and standard intrinsic flux
        curve (str): Extinction curve to use

    Returns:
        float: A_V in magnitudes

    """

    if method == 'Ha/Hb':
        wave1 = 6564.6  # redder
        wave2 = 4862.7
        #
        F1_obs = neb_lines['Halpha']
        F2_obs = neb_lines['Hbeta']
        #
        pair = True
        intrinsic = Ha_Hb_intrin
    elif method == 'Hb/Hg':
        wave1 = 4862.7  #redder
        wave2 = 4341.7
        #
        F1_obs = neb_lines['Hbeta']
        F2_obs = neb_lines['Hgamma']
        #
        pair = True
        intrinsic = Hb_Hg_intrin
    else:
        print("Not prepared for this method of analysis: {}".format(method))
        raise IOError("See docs for available options")

    if not pair:
        raise IOError("Not ready for this mode")

    # Extinction
    a1AV = extinction.fm07(np.atleast_1d(wave1), 1.0)[0]
    a2AV = extinction.fm07(np.atleast_1d(wave2), 1.0)[0]

    # Observed ratio
    fratio_obs = F1_obs / F2_obs

    # Calculate using intrinsic ratio
    AV = 2.5 * np.log10(intrinsic / fratio_obs) / (a1AV - a2AV)

    # Return
    return AV
Пример #2
0
    def apply_dust(self):

        import extinction

        for ii in range(self.n_zz):
            if self.dust['flag'] == 'calzetti':
                self.lum_em[:, ii] = extinction.apply(
                    extinction.calzetti00(self.wav_em, self.dust['Av'], 4.05),
                    self.lum_em[:, ii])
            elif self.dust['flag'] == 'cardelli':
                self.lum_em[:, ii] = extinction.apply(
                    extinction.ccm89(self.wav_em, self.dust['Av'], 4.05),
                    self.lum_em[:, ii])
            elif self.dust['flag'] == 'odonnell':
                self.lum_em[:, ii] = extinction.apply(
                    extinction.odonnell94(self.wav_em, self.dust['Av'], 4.05),
                    self.lum_em[:, ii])
            elif self.dust['flag'] == 'fitzpatrick':
                self.lum_em[:, ii] = extinction.apply(
                    extinction.fitzpatrick99(self.wav_em, self.dust['Av'],
                                             3.1), self.lum_em[:, ii])
            elif self.dust['flag'] == 'fitzpatrick07':
                self.lum_em[:, ii] = extinction.apply(
                    extinction.fm07(self.wav_em, self.dust['Av']),
                    self.lum_em[:, ii])
Пример #3
0
def test_fm07():
    wave = np.arange(3000., 9000., 1000)

    # from running the code; we're just checking that results don't change!
    ref_values = [
        1.84192286, 1.42645161, 1.13842341, 0.88843179, 0.69226384, 0.54709373
    ]
    assert_allclose(extinction.fm07(wave, 1.), ref_values)
Пример #4
0
def fit_spectrum(parameters, wave, flux, err, snr, wave0, wave1, photparams,
                 filter, gridparams, grid, feh, feh_err,
                 ebv):  # function for spectral fit to minimize

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.optimize import curve_fit
    from extinction import fm07, apply

    minsnr = 50
    av = 3.1 * ebv

    fluxmod, errmod = warp_spec(photparams, wave0, wave1, wave, flux, err)
    flux_model = interpolate_spectrum(parameters, gridparams, grid, wave)
    #flux_model = interpolate_spectrum(parameters[0:3],gridparams,grid,wave)  # EXPERIMENTAL
    #flux_model = flux_model*10**(-0.4*extinction.fm07(wave*10000.,parameters[3])) # EXPERIMENTAL
    flux_model = apply(fm07(wave * 10000, av), flux_model)  # include reddening
    filter_all = filter * (1. * (snr > minsnr))

    r = fluxmod / flux_model
    r[np.isnan(r)] = 0.

    # Overall adjustment
    which = ((r != 0.) & (filter == 1.) & (np.isfinite(r)) &
             (np.isnan(r) == False))
    r0 = np.median(r[which])
    print('Model params = ', parameters)
    print('Phot params = ', photparams)
    flux_model = r0 * flux_model

    var = (filter_all * (fluxmod - flux_model) / errmod)**2
    var[(1 * np.isnan(var)) == 1.] = 0.
    chisquared = np.sum(var) / np.sum([1. * (var > 0.)]) * (1 + (
        (feh - parameters[2]) / feh_err)**2)

    # plotting routines
    plt.close('all')
    plt.rc('xtick', labelsize=6)
    plt.rc('ytick', labelsize=6)
    fig = plt.figure(figsize=(4, 5))
    xmins = [0.55, 1.0, 1.43, 1.95, 1.165]
    xmaxes = [0.93, 1.3, 1.80, 2.40, 1.295]
    titles = ['Visible', 'J', 'H', 'K', 'RV/resolution analysis range']
    for iplot, xmin, xmax, title in zip(np.arange(5), xmins, xmaxes, titles):
        ax = fig.add_subplot(5, 1, iplot + 1)
        plt.xlim([xmin, xmax])
        plt.title(title, fontsize=8)
        yvalues = fluxmod.compress((wave > xmin) & (wave < xmax))
        plt.ylim([min(yvalues), max(yvalues)])
        plt.plot(wave, filter_all * fluxmod, 'k.', markersize=0.7)
        plt.plot(wave, flux_model, 'r')
    plt.tight_layout()
    plt.pause(0.1)
    plt.clf()
    if np.isnan(chisquared):
        chisquared = 1.0e9

    return chisquared
Пример #5
0
def extinction_correction(filter, EBV, RV=3.1, max_wave=None):
    """
    calculate MW extinction correction for given filter

    Uses the Fitzpatrick & Massa (2007) extinction law

    Args:
        filter (str):
            filter name (name of file without .dat extension)
        EBV (float):
            E(B-V) (can get from frb.galaxies.nebular.get_ebv which uses IRSA Dust extinction query
        RV:
            from gbrammer/threedhst eazyPy.py -- characterizes MW dust
        max_wave (float, optional):
            If set, cut off the calculation at this maximum wavelength.
            A bit of a hack for the near-IR, in large part because the
            MW extinction curve ends at 1.4 microns.

    Returns:
             float: linear extinction correction

    """
    # Read in filter in Table
    path_to_filters = os.path.join(resource_filename('frb', 'data'),
                                   'analysis', 'CIGALE')
    # Hack for LRIS which does not differentiate between cameras
    if 'LRIS' in filter:
        _filter = 'LRIS_{}'.format(filter[-1])
    else:
        _filter = filter
    filter_file = os.path.join(path_to_filters, _filter + '.dat')
    filter_tbl = Table.read(filter_file, format='ascii')

    #get wave and transmission (file should have these headers in first row)
    wave = filter_tbl['col1'].data
    throughput = filter_tbl['col2'].data

    if max_wave:
        warnings.warn(
            "Cutting off the extinction correction calculation at {} Ang".
            format(max_wave))
        gdwv = wave < max_wave
        wave = wave[gdwv]
        throughput = throughput[gdwv]

    #get MW extinction correction
    AV = EBV * RV
    #AlAV = nebular.load_extinction('MW')
    Alambda = extinction.fm07(wave, AV)
    source_flux = 1.

    #calculate linear correction
    delta = np.trapz(throughput * source_flux * 10**(-0.4 * Alambda),
                     wave) / np.trapz(throughput * source_flux, wave)

    correction = 1. / delta

    return correction
Пример #6
0
def plot_spec(specDB, meta, frb, dust_correct=False):
    import numpy as np
    from astropy.coordinates import SkyCoord
    from linetools import utils as ltu
    from frb.galaxies import nebular

    """ Plot galaxy spectra """
    # Grab spectra
    spec = specDB.spectra_from_meta(meta)

    # Dust?
    if dust_correct:
        import extinction
        EBV = nebular.get_ebv(frb.coord)['meanValue']  #
        AV = EBV * 3.1  # RV

        for kk in range(spec.nspec):
            spec.select = kk
            Al = extinction.fm07(spec.wavelength.value, AV)#, 3.1)
            spec.flux = spec.flux * 10 ** (Al / 2.5)
            spec.sig = spec.sig * 10 ** (Al / 2.5)

    # Add labels
    lbls = ['None']*len(meta)
    ugroups = np.unique(meta['GROUP'])
    for ugroup in ugroups:
        rows = np.where(meta['GROUP'] == ugroup)[0]
        coords = SkyCoord(ra=meta['RA_GROUP'][rows], dec=meta['DEC_GROUP'][rows], unit='deg')
        if frb is None:
            for kk, row, imeta in zip(range(len(rows)), rows, meta):
                # JNAME
                jname = ltu.name_from_coord(coords[kk])
                lbls[row]='{:s}_{:s}'.format(jname, meta['INSTR'][row])
        else:
            seps = frb.coord.separation(coords).to('arcsec')
            pas = frb.coord.position_angle(coords).to('deg')
            for row, sep, pa, imeta in zip(rows, seps, pas, meta):
                # Separation and PA
                lbls[row]='{:s}_{:s}_{:d}_{:d}'.format(frb.frb_name, meta['INSTR'][row],
                                                   int(pa.value), int(sep.value))
    spec.labels = lbls
    # Add object type
    spec.stypes = ['Galaxy']*len(lbls)
    # Add redshift
    spec.z = meta['zem_GROUP']

    # Plot
    spec.plot(xspec=True)#, scale=1.5)
Пример #7
0
def TRblackbod(T, R, z, DM, EBV=0):

    from SNAP.Analysis.Cosmology import wave_0, bands, Mag_toFlux
    import extinction as extn
    import astropy.units as u

    #luminosity distance [pc -> cm]
    dl = 10 * np.power(10, DM / 5.0) * 3.086 * 10**18
    Area = 4.0 * np.pi * np.square(dl)  #cm^2
    area = 4.0 * np.pi * R**2
    #predicted flux density at wave
    flux_obs = lambda wave: extn.apply(extn.fm07(wave * u.AA, EBV * 3.1),
                                       blackbod(wave / (1. + z), T) * 1e23 *
                                       area / Area)  #Jy
    #flux_obs = lambda wave: blackbod(wave/(1.+z),T)*1e23*area/Area #Jy
    return flux_obs
Пример #8
0
def deredden_spectrum(wave, flux, ebv, r_v=3.1, unit='aa', model='fm07'):
    """Deredden a spectrum based on a Galactic extinction model."""

    model = model.lower().strip()

    if model == 'fm07':
        mw_extinction = fm07(wave, ebv * r_v, unit=unit)
    elif model == 'ccm89':
        mw_extinction = ccm89(wave, ebv * r_v, r_v, unit=unit)
    elif model == 'odonnell94':
        mw_extinction = ccm89(wave, ebv * r_v, r_v, unit=unit)
    else:
        raise Exception(
            "# Wrong choice of extinction model: fm07/ccm89/odonnell94")

    return remove(mw_extinction, flux)
Пример #9
0
def calc_lum(neb_lines, line, z, cosmo, AV=None):
    """
    Calculate the line luminosity (and error) from input nebular line emission

    Error is -999.*erg/s if input line flux has negative error

    Args:
        neb_lines (dict):  Observed line fluxes and errors
        line (str): Line to analyze
        z (float):  Emission redshift -- for Luminosity distance
        cosmo (astropy.cosmology.FLRW): Cosmology
        AV (float, optional):  Visual extinction, if supplied will apply

    Returns:
        Quantity, Quantity:  Luminosity, sig(Luminosity)
    """
    # Grab rest wavelength (vacuum)
    llist = linelist.LineList('Galaxy')
    wave = llist[line]['wrest']

    # Dust correct?
    if AV is not None:
        al = extinction.fm07(np.atleast_1d(wave.to('Angstrom').value), AV)[0]
    else:
        al = 0.

    # Cosmology
    DL = cosmo.luminosity_distance(z)

    # Luminosity
    flux = neb_lines[line]
    Lum = flux * units.erg / units.s / units.cm**2 * 10**(al / 2.5) * (
        4 * np.pi * DL**2)

    # Error
    if neb_lines[line + '_err'] > 0.:
        flux_err = neb_lines[line + '_err']
        Lum_err = flux_err * units.erg / units.s / units.cm**2 * 10**(
            al / 2.5) * (4 * np.pi * DL**2)
    else:
        Lum_err = -999 * units.erg / units.s
    # Return
    return Lum.to('erg/s'), Lum_err.to('erg/s')
Пример #10
0
def extinct(wl, spec, av, rv=3.1, unit='aa'):
    """Uses the package "extinction" to calculate an extinction curve for the given A_v and R_v, 
	then converts the extinction curve to a transmission curve
	and uses that to correct the spectrum appropriately.
	Accepted units are angstroms ('aa', default) or microns^-1 ('invum').

	Args:
		wl (list): wavelength array
		spec (list): flux array
		av (float): extinction in magnitudes
		rv (float): Preferred R_V, defaults to 3.1
		unit (string): Unit to use. Accepts angstroms "aa" or inverse microns "invum". Defaults to angstroms.

	Returns:
		spec (list): a corrected spectrum vwith no wavelength vector. 

	"""
    ext_mag = extinction.fm07(wl, av, unit)
    spec = extinction.apply(ext_mag, spec)
    return np.array(spec)
Пример #11
0
def test_fm07():
    wave = np.arange(3000, 9000, 1000)
    ref_values = [
        1.84202329, 1.42645161, 1.13844058, 0.88840962, 0.69220634, 0.54703201
    ]
    assert_allclose(extinction.fm07(wave, 1.), ref_values)
Пример #12
0

# ugriz

ugriz_mags = t_DR12_DR12_matches['PSFMAG']
ugriz_mags_err = t_DR12_DR12_matches['ERR_PSFMAG']
ugriz_mags_err[np.abs(ugriz_mags_err) > 2] = np.nan
ugriz_mags_err = np.ma.array(ugriz_mags_err, mask=np.isnan(ugriz_mags_err))

# ugriz fluxes, effective freqs (mid band freqs)
flux_DR12_ugriz, ugriz_freqs = mag_to_flux(ugriz_mags, 'ugriz')
flux_DR12_ugriz_errs, ugriz_freqs = mag_to_flux(ugriz_mags, 'ugriz')
# ugriz wavelengths
ugriz_Ang = np.array([3540, 4750, 6220, 7630, 9050])
# ugriz extinction and application to flux
ugriz_ext = extinction.fm07(ugriz_Ang, 1.0)
flux_DR12_ugriz = extinction.apply(ugriz_ext, flux_DR12_ugriz)
# same but to errors
flux_DR12_ugriz_errs = extinction.apply(ugriz_ext, flux_DR12_ugriz_errs)

# frequencies matched to each flux value
f_flux_ugriz = freqs_fluxes_match(ugriz_freqs, flux_DR12_ugriz)

# WISE
# WISE mags minus Vband extinction ?! INFRARED ?
WISE_mags = [
    t_DR12_DR12_matches['W{}MAG'.format(i)] for i in range(1, 5)
]  #[t_DR12_DR12_matches['W{}MAG'.format(i)] - ext_DR12 for i in range(1,5)]
WISE_mags = np.array(WISE_mags).transpose()
# mag errs
WISE_mags_errs = [
Пример #13
0
 def correct_extinction(self, wvs):
     alams = extinction.fm07(wvs, self.mwebv)
     for i, alam in enumerate(alams):
         gind = np.where(self.filters == str(i))
         self.abs_mags[gind] = self.abs_mags[gind] - alam
Пример #14
0
def build_grid(gridfile, nbest, res, wave, ebv, flux, err, filter, wave_rv,
               flux_rv, feh, feh_err):

    # build the comparison grid of models

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.interpolate import interp1d
    from astropy.convolution import convolve, Gaussian1DKernel
    from scipy.signal import savgol_filter
    from PyAstronomy.pyasl import crosscorrRV
    from PyAstronomy.pyasl import vactoair2 as vactoair
    from extinction import fm07, apply

    from astropy.io import fits

    print('Building the Grid....')

    nn = 10
    rvmax = 400
    rvmin = -400
    drv = 2.
    c = 3.0e5
    gauss_kernel = Gaussian1DKernel(nn)

    # load the grid
    f = fits.open('../Grid/' + gridfile)
    g = f[1].data
    #header = g['HEADER'][0]
    modelspec = g['SPECTRUM'][0]
    teff = np.array(g['TEFF'][0])
    logg = np.array(g['LOGG'][0])
    metal = np.array(g['METAL'][0])
    a_fe = np.array(g['A_FE'][0])

    #junk = header[8]
    #junk = np.array(junk.split())
    #nlambda = int(np.asscalar((junk[2])))
    #junk = header[9]
    #junk = np.array(junk.split())
    #lambda0 = float(np.asscalar(junk[1]))
    #junk = header[10]
    #junk = np.array(junk.split())
    #dlambda = float(np.asscalar(junk[1]))
    #modelwave = lambda0 + dlambda*np.arange(nlambda) # for original PHOENIX
    modelwave = np.array(g['WAVE'][0])  # for Goettingen PHOENIX
    nwave, nmodels = modelspec.shape
    nwave = int(nwave)
    nmodels = int(nmodels)

    model_vac = np.array(
        modelwave)  # convert wavelengths from vacuum to air and to microns
    model_vac2 = model_vac.compress(model_vac > 2000.)
    model_wave = vactoair(model_vac2,
                          mode='edlen53') / 10000.  # convert to air
    npts = nn * res * np.log(np.max(model_wave) / np.min(model_wave))
    wave_log = np.min(model_wave) * np.exp(
        np.arange(npts) /
        (1. * npts) * np.log(np.max(model_wave) / np.min(model_wave)))

    av = ebv * 3.1
    #extinct_all = extinction.fm07(wave*10000.,av)/av_ref   # approximate extinction per unit magnitude
    #extinct = extinct_all.compress(filter==1)

    #model_compare = []
    rvbest = []
    chisq = []
    #avmodels = []
    #av_max = 4.
    #av_values = av_max*np.arange(100)/100.

    for imodel in np.arange(nmodels):

        model_spec = np.array(
            modelspec[:, imodel]) * 1.0e-8  # convert from per cm to per A
        model_spec = model_spec.compress(model_vac > 2000.)
        #model_spec = model_spec*10**(-0.4*extinction.fm07(model_vac,av)) # apply extinction  (EXPERIMENTAL)

        # interpolation function
        model_interp = interp1d(model_wave,
                                model_spec,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)
        model_prelim = model_interp(wave)
        model_prelim = apply(fm07(wave * 10000, ebv, 3.1), model_prelim)
        fr = flux.compress(filter == 1.) / model_prelim.compress(filter == 1)

        # here we need to determine best-fit extinction
        #x = []

        #for av_val in av_values:
        #    x1 = np.sum(fr*10**(-0.4*extinct*av_val))/np.sum(10**(-0.8*extinct*av_val))
        #    x2 = np.sum(extinct*fr*10**(-0.4*extinct*av_val))/np.sum(extinct*10**(-0.8*extinct*av_val))
        #    x.append(abs(x1/x2-1.))
        #av_best = av_values[np.argmin(x)]
        #avmodels.append(av_best)

        #ratval = np.sum(fr*10**(-0.4*extinct*av_best))/np.sum(10**(-0.8*extinct*av_best))*10**(-0.4*extinct*av_best)
        ratval = np.median(fr)
        model_prelim = model_prelim.compress(filter == 1) * ratval
        sig = (flux.compress(filter == 1) -
               model_prelim) / err.compress(filter == 1)
        #plt.plot(wave.compress(filter==1),err.compress(filter==1))
        #plt.show(block=True)
        chisqval = np.sum(sig**2) * (1 + (
            (feh - metal[imodel]) / feh_err)**2)  # disabled for now
        chisq.append(chisqval)
        print('Model params =', teff[imodel], logg[imodel], metal[imodel],
              av_best, chisqval)

    indices = np.argsort(chisq)
    bestmodels = indices[0:nbest]
    chisq = np.array(chisq)

    teffbest = np.sort(np.unique(teff[bestmodels]))
    loggbest = np.sort(np.unique(logg[bestmodels]))
    metalbest = np.sort(np.unique(metal[bestmodels]))
    #avmodels = np.array(avmodels)
    #avbest = np.sort(np.unique(avmodels[bestmodels]))
    #print('Best Av = ',avmodels[indices[0]])

    bestparams = [teff[indices[0]], logg[indices[0]], metal[indices[0]]]
    print('Best parameters = ', bestparams)
    plt.pause(5)
    teffmin = np.min(teffbest)
    teffmax = np.max(teffbest)
    loggmin = np.min(loggbest)
    loggmax = np.max(loggbest)
    metalmin = np.min(metalbest)
    metalmax = np.max(metalbest)
    if teffmin == teffmax:
        teffmin = teffmin - 100.
        teffmax = teffmax + 100.
    if loggmin == loggmax:
        loggmin = loggmin - 0.5
        loggmax = loggmax + 0.5
    if metalmin == metalmax:
        metalmin = metalmin - 0.5
        metalmax = metalmax + 0.5

    gridmodels = np.arange(nmodels).compress((teff >= teffmin)
                                             & (teff <= teffmax)
                                             & (logg >= loggmin)
                                             & (logg <= loggmax)
                                             & (metal >= metalmin)
                                             & (metal <= metalmax))

    grid = np.zeros((len(teffbest), len(loggbest), len(metalbest), len(wave)))

    print('Creating subgrid with ', len(gridmodels), ' models')
    for imodel in gridmodels:
        model_spec = np.array(
            modelspec[:, imodel]) * 1.0e-8  # convert from per cm to per A
        model_spec = model_spec.compress(model_vac > 2000.)

        # interpolate model spectrum to logarithmic wavelengths
        model_interp = interp1d(model_wave,
                                model_spec,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)
        model_log = model_interp(wave_log)
        model_conv = convolve(model_log,
                              gauss_kernel)  # convolve model with Gaussian
        smooth_model = savgol_filter(model_conv, 501, 2)
        model_norm = model_conv / smooth_model
        wavelim = wave_log.compress((wave_log < 1.01 * np.max(wave_rv))
                                    & (wave_log > 0.99 * np.min(wave_rv)))
        modellim = model_norm.compress((wave_log < 1.01 * np.max(wave_rv))
                                       & (wave_log > 0.99 * np.min(wave_rv)))

        # find Doppler shift of model
        rv, cc = crosscorrRV(wave_rv,
                             flux_rv,
                             wavelim,
                             modellim,
                             rvmin,
                             rvmax,
                             drv,
                             mode='doppler')
        index = np.argmax(cc)

        rvbest.append(rv[index])
        wave_shift = wave_log * (1 + rv[index] / c)

        model_interp = interp1d(wave_shift,
                                model_conv,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)

        i = np.arange(len(teffbest)).compress(teff[imodel] == teffbest)
        j = np.arange(len(loggbest)).compress(logg[imodel] == loggbest)
        k = np.arange(len(metalbest)).compress(metal[imodel] == metalbest)
        #gridflux = model_interp(wave)*10**(-0.4*extinct_all*np.asscalar(avmodels[imodel])) # apply extinction at this step for consistency with the chi-squared minimization
        gridflux = model_interp(wave)
        grid[i, j, k, :] = gridflux

    return teffbest, loggbest, metalbest, grid, rvbest, bestparams
Пример #15
0
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from mpl_toolkits.axes_grid1 import make_axes_locatable

import extinction

rcParams['font.family'] = 'serif'

wave = np.logspace(np.log10(910.), np.log10(30000.), 2000)

a_lambda = {'ccm89': extinction.ccm89(wave, 1.0, 3.1),
            'odonnell94': extinction.odonnell94(wave, 1.0, 3.1),
            'fitzpatrick99': extinction.fitzpatrick99(wave, 1.0),
            'fm07': extinction.fm07(wave, 1.0)}

names = list(a_lambda.keys())  # consistent ordering between panels

fig = plt.figure(figsize=(8.5, 6.))

ax = plt.axes()
for name in names:
    plt.plot(wave, a_lambda[name], label=name)
plt.axvline(x=2700., ls=':', c='k')
plt.axvline(x=3030.3030, ls=':', c='k')
plt.axvline(x=9090.9091, ls=':', c='k')
plt.axvspan(wave[0], 1150., fc='0.8', ec='none', zorder=-1000)
plt.axvspan(1150., 1250., fc='0.9', ec='none', zorder=-1000)    
plt.text(0.5, 0.95, '$R_V = 3.1$', transform=ax.transAxes, va='top',
         size='x-large')
Пример #16
0
def deredden(wave,
             flux,
             ra,
             dec,
             scaling=0.86,
             reddening_law='fitzpatrick99',
             dustmaps_dir=None,
             r_v=3.1,
             ebv=None):
    """Dereddens the given spectrum, given a right ascension and declination or :math:`E(B-V)`.

    Parameters
    ----------
    wave : array
        Wavelength values.
    flux : array
        Flux density values.
    ra : float
        Right ascension in degrees.
    dec : float
        Declination in degrees.
    scaling: float, default ``0.86``
        Calibration of the Milky Way dust maps. Either ``0.86``
        for the Schlafly & Finkbeiner (2011) recalibration or ``1.0`` for the original
        dust map of Schlegel, Fikbeiner & Davis (1998).
    reddening_law: str, default ``fitzpatrick99``
        Reddening law. The options are: ``ccm89`` (Cardelli, Clayton & Mathis 1989), ``odonnell94`` (O’Donnell 1994),
        ``fitzpatrick99`` (Fitzpatrick 1999), ``calzetti00`` (Calzetti 2000) and ``fm07`` (Fitzpatrick & Massa 2007 with
        :math:`R_V` = 3.1.)
    dustmaps_dir : str, default ``None``
        Directory where the dust maps of Schlegel, Fikbeiner & Davis (1998) are found.
    r_v : float, default ``3.1``
        Total-to-selective extinction ratio (:math:`R_V`)
    ebv : float, default ``None``
        Colour excess (:math:`E(B-V)`). If given, this is used instead of the dust map value.

    Returns
    -------
    deredden_flux : array
        Deredden flux values.

    """
    pisco_path = piscola.__path__[0]
    if dustmaps_dir is None:
        dustmaps_dir = os.path.join(pisco_path, 'sfddata-master')

    if ebv is None:
        m = sfdmap.SFDMap(mapdir=dustmaps_dir, scaling=scaling)
        ebv = m.ebv(ra, dec)  # RA and DEC in degrees

    a_v = r_v * ebv

    rl_list = ['ccm89', 'odonnell94', 'fitzpatrick99', 'calzetti00', 'fm07']
    assert reddening_law in rl_list, f'Choose one of the available reddening laws: {rl_list}'

    if reddening_law == 'ccm89':
        ext = extinction.ccm89(wave, a_v, r_v)
    elif reddening_law == 'odonnell94':
        ext = extinction.odonnell94(wave, a_v, r_v)
    elif reddening_law == 'fitzpatrick99':
        ext = extinction.fitzpatrick99(wave, a_v, r_v)
    elif reddening_law == 'calzetti00':
        ext = extinction.calzetti00(wave, a_v, r_v)
    elif reddening_law == 'fm07':
        ext = extinction.fm07(wave, a_v)

    deredden_flux = extinction.remove(ext, flux)

    return deredden_flux
Пример #17
0
def getReddeningLaw(law='fitzpatrick99',Rv=3.1,inv=False):

    import numpy as np
    from scipy import interpolate
    import extinction

    # Wavelength ranges (lambda_min - lambda_max) of the various reddening laws 
    #  (in Angstroms)...
    lambda_min = {'ccm89':          1250., 
                  'odonnell94':     1250., 
                  'calzetti00':     1200., 
                  'fitzpatrick99':   910., 
                  'fm07':            910.}
    lambda_max = {'ccm89':         33000.,
                  'odonnell94':    33000.,
                  'calzetti00':    22000.,
                  'fitzpatrick99': 60000.,
                  'fm07':          60000.}
    # We can extract the list of supported reddening laws by
    #  grabbing those that are keys within the lambda_min dictionary...
    supported_laws = lambda_min.keys()

    # If reddening law not in the the list of supported reddening laws,
    #  return an Exception...
    if law not in supported_laws: 
        print """Un-supported reddening law:  %s""" % (law)
        print 'Supported reddening laws are: ', supported_laws 
        print 'Returning exception'
        return Exception

    # Calculate and return the reddening law in either
    #  inverse wavelength form (inv=True) or in wavelength
    #  form (inv=False)...
    if inv==True:

        # Use inverse microns to call to "extinction" module
        #  and return reddening law in inverse Angstroms...

        # Calculate inverse wavelengths...
        x_lambda_min = 1.0e4/lambda_max[law]
        x_lambda_max = 1.0e4/lambda_min[law]
        x_micron = np.linspace(x_lambda_min, x_lambda_max, 2000) # microns^-1
        x_angstrom = x_micron * 1.0e-4 # Convert from microns^-1 to Anstroms^-1

        # Call appropriate reddening law function...
        if law == 'ccm89':
            r_array = Rv*extinction.ccm89(x_micron, 1.0, Rv, unit='invum')
        elif law == 'odonnell94':
            r_array = Rv*extinction.odonnell94(x_micron, 1.0, Rv, unit='invum')
        elif law == 'calzetti00':
            r_array = Rv*extinction.calzetti00(x_micron, 1.0, Rv, unit='invum')
        elif law == 'fitzpatrick99':
            r_array = Rv*extinction.fitzpatrick99(x_micron, 1.0, Rv, unit='invum')
        elif law == 'fm07':
            r_array = Rv*extinction.fm07(x_micron, 1.0, unit='invum')

        # Create interpolation function for reddening law...
        r = interpolate.interp1d(x_angstrom, r_array, 
                                 bounds_error=False, fill_value=0., kind=3)

    else:

        # Use Angstroms to call to "extinction" module
        #  and return reddening law in Angstroms...

        # Create wavelength array...
        angstrom = np.logspace(np.log10(lambda_min[law]), np.log10(lambda_max[law]), 2000)

        # Call appropriate reddening law function...
        if law == 'ccm89':
            r_array = Rv*extinction.ccm89(angstrom, 1.0, Rv, unit='aa')
        elif law == 'odonnell94':
            r_array = Rv*extinction.odonnell94(angstrom, 1.0, Rv, unit='aa')
        elif law == 'calzetti00':
            r_array = Rv*extinction.calzetti00(angstrom, 1.0, Rv, unit='aa')
        elif law == 'fitzpatrick99':
            r_array = Rv*extinction.fitzpatrick99(angstrom, 1.0, Rv, unit='aa')
        elif law == 'fm07':
            r_array = Rv*extinction.fm07(angstrom, 1.0, unit='aa')

        # Create interpolation function for reddening law...
        r = interpolate.interp1d(angstrom, r_array, 
                                 bounds_error=False, fill_value=0., kind='linear')

    # Return interpolation fucntion...
    return r
Пример #18
0
import myfuncs as cf
from astropy.io import ascii

f5 = 5410.
f8 = 8353.
f1 = 15450.
wave = np.array([f5, f8, f1])
av = 1.0
rv = 3.1

log = cf.HtmlLog('./', 'Reddening.html')
log.add_line('Python version of simple reddening', AppendLog=False)

ccm89 = extinction.ccm89(wave, av, rv)
f99 = extinction.fitzpatrick99(wave, av, rv)
fm07 = extinction.fm07(wave, av, 'aa')

rv = 3.1
fout = 'table.dat'
hout = open(fout, 'w')
hout.write('#  Law   Rv   A555   A814   A160   RIvi    RHvi\n')
law = 'CCM89'
av, ai, ah = extinction.ccm89(wave, av, rv)
rivi = ai / (av - ai)
rhvi = ah / (av - ai)
fmt = '%10s' + '%10.3f' * 6 + '\n'
hout.write(fmt % (law, rv, av, ai, ah, rivi, rhvi))

law = 'F99'
av, ai, ah = extinction.fitzpatrick99(wave, av, rv)
rivi = ai / (av - ai)