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
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])
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)
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
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
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)
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
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)
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')
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)
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)
# 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 = [
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
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
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')
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
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
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)